From a7d4447830dc5442c4a030ad3c316f7042234b75 Mon Sep 17 00:00:00 2001 From: "Eugene P." Date: Tue, 12 Nov 2024 13:40:55 +0200 Subject: [PATCH 01/18] feat(apps-backend, tooling-ci): Add e2e tests to apps backend (#3760) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(apps-backend): add e2e tests. * feat(apps-backend): add e2e tests to CI for testing. * feat(apps-backend): move e2e tests to another config. * feat(apps-backend): revert hierarchy. * feat(apps-backend): remove DEPLOY_URL * feat(apps-backend): remove DEPLOY_URL from e2e test * feat(tooling-ci): move e2e tests for apps-backend to e2e.yml * feat(apps-backend): Run apps-backend e2e tests conditionally on apps-backend changes * feat(apps-backend): Run apps-backend e2e tests also on merge to develop --------- Co-authored-by: Mario Sarcevic Co-authored-by: Begoña Álvarez de la Cruz --- .github/workflows/_e2e.yml | 11 ++++++++ .github/workflows/hierarchy.yml | 1 + apps/apps-backend/jest-e2e.json | 13 +++++++++ apps/apps-backend/package.json | 5 ++-- apps/apps-backend/src/app.module.ts | 2 ++ .../src/health/health.controller.ts | 12 ++++++++ apps/apps-backend/src/health/health.module.ts | 10 +++++++ apps/apps-backend/test/health.e2e-spec.ts | 28 +++++++++++++++++++ 8 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 apps/apps-backend/jest-e2e.json create mode 100644 apps/apps-backend/src/health/health.controller.ts create mode 100644 apps/apps-backend/src/health/health.module.ts create mode 100644 apps/apps-backend/test/health.e2e-spec.ts diff --git a/.github/workflows/_e2e.yml b/.github/workflows/_e2e.yml index 6438470f121..42eb66e2c64 100644 --- a/.github/workflows/_e2e.yml +++ b/.github/workflows/_e2e.yml @@ -9,6 +9,9 @@ on: isExplorer: type: boolean required: true + isAppsBackend: + type: boolean + required: true isTypescriptSDK: type: boolean required: true @@ -74,6 +77,14 @@ jobs: if: inputs.isGraphQlTransport || inputs.isRust || inputs.isDevelop run: pnpm dlx concurrently --kill-others --success command-1 "$E2E_RUN_LOCAL_NET_CMD" 'pnpm --filter @iota/graphql-transport test:e2e' + - name: Build apps-backend + if: inputs.isAppsBackend || inputs.isDevelop + run: pnpm --filter apps-backend build + + - name: Run apps-backend e2e tests + if: inputs.isAppsBackend || inputs.isDevelop + run: pnpm --filter apps-backend test:e2e + - name: Build explorer if: inputs.isTypescriptSDK || inputs.isExplorer || inputs.isRust || inputs.isDevelop run: pnpm turbo --filter=iota-explorer build diff --git a/.github/workflows/hierarchy.yml b/.github/workflows/hierarchy.yml index 47d92c4ce92..612d35b03a0 100644 --- a/.github/workflows/hierarchy.yml +++ b/.github/workflows/hierarchy.yml @@ -145,6 +145,7 @@ jobs: isRust: ${{ needs.diff.outputs.isRust == 'true' }} isWallet: ${{ needs.diff.outputs.isWallet == 'true' }} isExplorer: ${{ needs.diff.outputs.isExplorer == 'true' }} + isAppsBackend: ${{ needs.diff.outputs.isAppsBackend == 'true' }} isTypescriptSDK: ${{ needs.diff.outputs.isTypescriptSDK == 'true' }} isGraphQlTransport: ${{ needs.diff.outputs.isGraphQlTransport == 'true' }} isDevelop: ${{ github.ref_name == 'develop' }} diff --git a/apps/apps-backend/jest-e2e.json b/apps/apps-backend/jest-e2e.json new file mode 100644 index 00000000000..8a02f0e8a41 --- /dev/null +++ b/apps/apps-backend/jest-e2e.json @@ -0,0 +1,13 @@ +{ + "moduleFileExtensions": ["js", "json", "ts"], + "rootDir": "./", + "testRegex": ".e2e-spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "testEnvironment": "node", + "moduleNameMapper": { + "^src/(.*)$": "/dist/$1", + "^@iota/core/(.*)$": "/dist/core/src/$1" + } +} diff --git a/apps/apps-backend/package.json b/apps/apps-backend/package.json index eb94045a4f5..149cc6fd9fc 100644 --- a/apps/apps-backend/package.json +++ b/apps/apps-backend/package.json @@ -6,8 +6,9 @@ "format": "prettier --write \"src/**/*.ts\"", "dev": "nest start --watch", "debug": "nest start --debug --watch", - "preview": "pnpm run build && node dist/main", - "lint": "eslint --max-warnings=0 \"{src,apps,libs,test}/**/*.ts\"" + "preview": "pnpm run build && node dist/apps-backend/src/main", + "lint": "eslint --max-warnings=0 \"{src,apps,libs,test}/**/*.ts\"", + "test:e2e": "jest --config ./jest-e2e.json" }, "dependencies": { "@iota/core": "workspace:*", diff --git a/apps/apps-backend/src/app.module.ts b/apps/apps-backend/src/app.module.ts index 0dc2844e50e..b7fd88272e7 100644 --- a/apps/apps-backend/src/app.module.ts +++ b/apps/apps-backend/src/app.module.ts @@ -11,6 +11,7 @@ import { FeaturesModule } from './features/features.module'; import { MonitorNetworkModule } from './monitor-network/monitor-network.module'; import { PricesModule } from './prices/prices.module'; import { RestrictedModule } from './restricted/restricted.module'; +import { HealthModule } from './health/health.module'; @Module({ imports: [ @@ -30,6 +31,7 @@ import { RestrictedModule } from './restricted/restricted.module'; ttl: 3600, max: 100, }), + HealthModule, ], }) export class AppModule {} diff --git a/apps/apps-backend/src/health/health.controller.ts b/apps/apps-backend/src/health/health.controller.ts new file mode 100644 index 00000000000..c86fdd5fc40 --- /dev/null +++ b/apps/apps-backend/src/health/health.controller.ts @@ -0,0 +1,12 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Controller, Get } from '@nestjs/common'; + +@Controller('health') +export class HealthController { + @Get() + check() { + return { status: 'ok' }; + } +} diff --git a/apps/apps-backend/src/health/health.module.ts b/apps/apps-backend/src/health/health.module.ts new file mode 100644 index 00000000000..e6394484ac5 --- /dev/null +++ b/apps/apps-backend/src/health/health.module.ts @@ -0,0 +1,10 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Module } from '@nestjs/common'; +import { HealthController } from './health.controller'; + +@Module({ + controllers: [HealthController], +}) +export class HealthModule {} diff --git a/apps/apps-backend/test/health.e2e-spec.ts b/apps/apps-backend/test/health.e2e-spec.ts new file mode 100644 index 00000000000..f8ea44ed7cc --- /dev/null +++ b/apps/apps-backend/test/health.e2e-spec.ts @@ -0,0 +1,28 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import * as request from 'supertest'; +import { AppModule } from '../src/app.module'; + +describe('Health Check (e2e)', () => { + let app: INestApplication; + + beforeAll(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [AppModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + await app.init(); + }); + + afterAll(async () => { + await app.close(); + }); + + it('/health (GET)', async () => { + await request(app.getHttpServer()).get('/health').expect(200).expect({ status: 'ok' }); + }); +}); From af9a325f67ee9df8913034eea08a51817bc70cea Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 12 Nov 2024 03:50:57 -0800 Subject: [PATCH 02/18] feat: remove the `v0` execution layer cut (#4002) * feat: remove the `v0` cut * fix: snapshots update * fix: remove the `v0` execution layer cut leftovers * fix(scripts): `execution_layer.py` should work with the only latest cut * feat: the latest cut should have the index 1 --- .github/crates-filters.yml | 6 - Cargo.lock | 129 +- Cargo.toml | 8 - crates/iota-genesis-builder/Cargo.toml | 6 +- .../src/stardust/migration/executor.rs | 6 +- dprint.json | 1 - external-crates/move/Cargo.lock | 72 - external-crates/move/Cargo.toml | 5 - .../crates/bytecode-verifier-tests/Cargo.toml | 23 - .../bytecode-verifier-tests/METER_TESTING.md | 5 - .../crates/bytecode-verifier-tests/src/lib.rs | 12 - .../src/support/mod.rs | 37 - .../src/unit_tests/binary_samples.rs | 80 - .../bounds_tests.proptest-regressions | 10 - .../src/unit_tests/bounds_tests.rs | 363 --- .../src/unit_tests/catch_unwind.rs | 30 - .../src/unit_tests/code_unit_tests.rs | 144 - .../src/unit_tests/constants_tests.rs | 264 -- .../src/unit_tests/control_flow_tests.rs | 243 -- .../src/unit_tests/duplication_tests.rs | 26 - .../src/unit_tests/generic_ops_tests.rs | 478 --- .../src/unit_tests/large_type_test.rs | 167 - .../src/unit_tests/limit_tests.rs | 827 ----- .../src/unit_tests/locals.rs | 130 - .../src/unit_tests/loop_summary_tests.rs | 468 --- .../src/unit_tests/many_back_edges.rs | 104 - .../src/unit_tests/mod.rs | 57 - .../unit_tests/negative_stack_size_tests.rs | 77 - .../src/unit_tests/reference_safety_tests.rs | 454 --- .../src/unit_tests/signature_tests.rs | 207 -- .../src/unit_tests/vec_pack_tests.rs | 74 - .../move-abstract-interpreter/Cargo.toml | 18 - .../move-abstract-interpreter/src/absint.rs | 236 -- .../src/control_flow_graph.rs | 353 --- .../move-abstract-interpreter/src/lib.rs | 9 - .../unit_tests/control_flow_graph_tests.rs | 243 -- .../src/unit_tests/mod.rs | 5 - .../crates/move-bytecode-verifier/Cargo.toml | 22 - .../crates/move-bytecode-verifier/README.md | 81 - .../src/ability_cache.rs | 101 - .../src/ability_field_requirements.rs | 102 - .../src/acquires_list_verifier.rs | 235 -- .../src/check_duplication.rs | 417 --- .../src/code_unit_verifier.rs | 155 - .../move-bytecode-verifier/src/constants.rs | 53 - .../src/control_flow.rs | 171 - .../src/control_flow_v5.rs | 287 -- .../src/cyclic_dependencies.rs | 65 - .../move-bytecode-verifier/src/data_defs.rs | 205 -- .../src/dependencies.rs | 565 ---- .../move-bytecode-verifier/src/friends.rs | 50 - .../src/instantiation_loops.rs | 304 -- .../src/instruction_consistency.rs | 230 -- .../crates/move-bytecode-verifier/src/lib.rs | 48 - .../move-bytecode-verifier/src/limits.rs | 225 -- .../src/locals_safety/abstract_state.rs | 170 - .../src/locals_safety/mod.rs | 194 -- .../src/loop_summary.rs | 291 -- .../src/reference_safety/abstract_state.rs | 957 ------ .../src/reference_safety/mod.rs | 581 ---- .../src/regression_tests/mod.rs | 6 - .../regression_tests/reference_analysis.rs | 337 -- .../src/script_signature.rs | 166 - .../move-bytecode-verifier/src/signature.rs | 529 ---- .../src/stack_usage_verifier.rs | 318 -- .../move-bytecode-verifier/src/type_safety.rs | 1268 -------- .../move-bytecode-verifier/src/verifier.rs | 112 - .../v0/crates/move-stdlib-natives/Cargo.toml | 24 - .../v0/crates/move-stdlib-natives/src/bcs.rs | 124 - .../crates/move-stdlib-natives/src/debug.rs | 817 ----- .../v0/crates/move-stdlib-natives/src/hash.rs | 142 - .../crates/move-stdlib-natives/src/helpers.rs | 13 - .../v0/crates/move-stdlib-natives/src/lib.rs | 178 -- .../crates/move-stdlib-natives/src/signer.rs | 77 - .../crates/move-stdlib-natives/src/string.rs | 251 -- .../move-stdlib-natives/src/type_name.rs | 90 - .../move-stdlib-natives/src/unit_test.rs | 118 - .../crates/move-stdlib-natives/src/vector.rs | 341 -- .../v0/crates/move-vm-runtime/Cargo.toml | 47 - .../crates/move-vm-runtime/src/data_cache.rs | 143 - .../v0/crates/move-vm-runtime/src/debug.rs | 260 -- .../crates/move-vm-runtime/src/interpreter.rs | 1537 --------- .../v0/crates/move-vm-runtime/src/lib.rs | 31 - .../v0/crates/move-vm-runtime/src/loader.rs | 2800 ----------------- .../v0/crates/move-vm-runtime/src/logging.rs | 44 - .../v0/crates/move-vm-runtime/src/move_vm.rs | 116 - .../move-vm-runtime/src/native_extensions.rs | 88 - .../move-vm-runtime/src/native_functions.rs | 218 -- .../v0/crates/move-vm-runtime/src/runtime.rs | 558 ---- .../v0/crates/move-vm-runtime/src/session.rs | 315 -- .../v0/crates/move-vm-runtime/src/tracing.rs | 106 - .../move-vm-runtime/src/unit_tests/mod.rs | 6 - .../src/unit_tests/vm_arguments_tests.rs | 665 ---- iota-execution/Cargo.toml | 5 - iota-execution/src/lib.rs | 8 +- iota-execution/src/lib.template.rs | 10 +- iota-execution/src/v0.rs | 204 -- iota-execution/v0/iota-adapter/Cargo.toml | 46 - iota-execution/v0/iota-adapter/src/adapter.rs | 231 -- iota-execution/v0/iota-adapter/src/error.rs | 91 - .../v0/iota-adapter/src/execution_engine.rs | 1235 -------- .../v0/iota-adapter/src/execution_mode.rs | 285 -- .../v0/iota-adapter/src/execution_value.rs | 305 -- .../v0/iota-adapter/src/gas_charger.rs | 366 --- iota-execution/v0/iota-adapter/src/lib.rs | 17 - .../src/programmable_transactions/context.rs | 1519 --------- .../programmable_transactions/execution.rs | 1728 ---------- .../programmable_transactions/linkage_view.rs | 352 --- .../src/programmable_transactions/mod.rs | 7 - .../v0/iota-adapter/src/temporary_store.rs | 1141 ------- .../iota-adapter/src/type_layout_resolver.rs | 77 - .../v0/iota-adapter/src/type_resolver.rs | 11 - .../v0/iota-move-natives/Cargo.toml | 29 - .../v0/iota-move-natives/src/address.rs | 136 - .../v0/iota-move-natives/src/config.rs | 190 -- .../iota-move-natives/src/crypto/bls12381.rs | 199 -- .../iota-move-natives/src/crypto/ecdsa_k1.rs | 414 --- .../iota-move-natives/src/crypto/ecdsa_r1.rs | 271 -- .../v0/iota-move-natives/src/crypto/ecvrf.rs | 112 - .../iota-move-natives/src/crypto/ed25519.rs | 98 - .../iota-move-natives/src/crypto/groth16.rs | 255 -- .../iota-move-natives/src/crypto/group_ops.rs | 744 ----- .../v0/iota-move-natives/src/crypto/hash.rs | 147 - .../v0/iota-move-natives/src/crypto/hmac.rs | 90 - .../v0/iota-move-natives/src/crypto/mod.rs | 16 - .../iota-move-natives/src/crypto/poseidon.rs | 117 - .../v0/iota-move-natives/src/crypto/vdf.rs | 175 -- .../iota-move-natives/src/crypto/zklogin.rs | 211 -- .../v0/iota-move-natives/src/dynamic_field.rs | 537 ---- .../v0/iota-move-natives/src/event.rs | 169 - .../v0/iota-move-natives/src/lib.rs | 1154 ------- .../v0/iota-move-natives/src/object.rs | 128 - .../src/object_runtime/mod.rs | 727 ----- .../src/object_runtime/object_store.rs | 749 ----- .../v0/iota-move-natives/src/random.rs | 29 - .../v0/iota-move-natives/src/test_scenario.rs | 934 ------ .../v0/iota-move-natives/src/test_utils.rs | 50 - .../v0/iota-move-natives/src/transfer.rs | 253 -- .../v0/iota-move-natives/src/tx_context.rs | 60 - .../v0/iota-move-natives/src/types.rs | 109 - .../v0/iota-move-natives/src/validator.rs | 74 - iota-execution/v0/iota-verifier/Cargo.toml | 19 - .../src/entry_points_verifier.rs | 260 -- .../src/global_storage_access_verifier.rs | 124 - .../v0/iota-verifier/src/id_leak_verifier.rs | 588 ---- iota-execution/v0/iota-verifier/src/lib.rs | 39 - iota-execution/v0/iota-verifier/src/meter.rs | 108 - .../src/one_time_witness_verifier.rs | 243 -- .../v0/iota-verifier/src/private_generics.rs | 211 -- .../src/struct_with_key_verifier.rs | 99 - .../v0/iota-verifier/src/verifier.rs | 65 - .../v0/iota-verifier/tests/common/mod.rs | 6 - .../tests/common/module_builder.rs | 272 -- scripts/execution_layer.py | 33 +- 154 files changed, 34 insertions(+), 40579 deletions(-) delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/Cargo.toml delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/METER_TESTING.md delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/lib.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/support/mod.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/binary_samples.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/catch_unwind.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/code_unit_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/control_flow_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/locals.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/mod.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/negative_stack_size_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-abstract-interpreter/Cargo.toml delete mode 100644 external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/absint.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/control_flow_graph.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/lib.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/unit_tests/control_flow_graph_tests.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/unit_tests/mod.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/Cargo.toml delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/README.md delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/ability_cache.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/ability_field_requirements.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/acquires_list_verifier.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/check_duplication.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/code_unit_verifier.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/constants.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/control_flow.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/control_flow_v5.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/cyclic_dependencies.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/data_defs.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/dependencies.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/friends.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/instantiation_loops.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/instruction_consistency.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/lib.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/limits.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/locals_safety/abstract_state.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/locals_safety/mod.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/loop_summary.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/reference_safety/abstract_state.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/reference_safety/mod.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/regression_tests/mod.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/regression_tests/reference_analysis.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/script_signature.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/signature.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/stack_usage_verifier.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/type_safety.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/verifier.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/Cargo.toml delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/bcs.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/debug.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/hash.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/helpers.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/lib.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/signer.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/string.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/type_name.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/unit_test.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-stdlib-natives/src/vector.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/Cargo.toml delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/data_cache.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/debug.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/interpreter.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/lib.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/loader.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/logging.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/move_vm.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/native_extensions.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/native_functions.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/runtime.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/session.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/tracing.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/unit_tests/mod.rs delete mode 100644 external-crates/move/move-execution/v0/crates/move-vm-runtime/src/unit_tests/vm_arguments_tests.rs delete mode 100644 iota-execution/src/v0.rs delete mode 100644 iota-execution/v0/iota-adapter/Cargo.toml delete mode 100644 iota-execution/v0/iota-adapter/src/adapter.rs delete mode 100644 iota-execution/v0/iota-adapter/src/error.rs delete mode 100644 iota-execution/v0/iota-adapter/src/execution_engine.rs delete mode 100644 iota-execution/v0/iota-adapter/src/execution_mode.rs delete mode 100644 iota-execution/v0/iota-adapter/src/execution_value.rs delete mode 100644 iota-execution/v0/iota-adapter/src/gas_charger.rs delete mode 100644 iota-execution/v0/iota-adapter/src/lib.rs delete mode 100644 iota-execution/v0/iota-adapter/src/programmable_transactions/context.rs delete mode 100644 iota-execution/v0/iota-adapter/src/programmable_transactions/execution.rs delete mode 100644 iota-execution/v0/iota-adapter/src/programmable_transactions/linkage_view.rs delete mode 100644 iota-execution/v0/iota-adapter/src/programmable_transactions/mod.rs delete mode 100644 iota-execution/v0/iota-adapter/src/temporary_store.rs delete mode 100644 iota-execution/v0/iota-adapter/src/type_layout_resolver.rs delete mode 100644 iota-execution/v0/iota-adapter/src/type_resolver.rs delete mode 100644 iota-execution/v0/iota-move-natives/Cargo.toml delete mode 100644 iota-execution/v0/iota-move-natives/src/address.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/config.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/bls12381.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/ecdsa_k1.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/ecdsa_r1.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/ecvrf.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/ed25519.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/groth16.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/group_ops.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/hash.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/hmac.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/mod.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/poseidon.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/vdf.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/crypto/zklogin.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/dynamic_field.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/event.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/lib.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/object.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/object_runtime/mod.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/object_runtime/object_store.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/random.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/test_scenario.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/test_utils.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/transfer.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/tx_context.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/types.rs delete mode 100644 iota-execution/v0/iota-move-natives/src/validator.rs delete mode 100644 iota-execution/v0/iota-verifier/Cargo.toml delete mode 100644 iota-execution/v0/iota-verifier/src/entry_points_verifier.rs delete mode 100644 iota-execution/v0/iota-verifier/src/global_storage_access_verifier.rs delete mode 100644 iota-execution/v0/iota-verifier/src/id_leak_verifier.rs delete mode 100644 iota-execution/v0/iota-verifier/src/lib.rs delete mode 100644 iota-execution/v0/iota-verifier/src/meter.rs delete mode 100644 iota-execution/v0/iota-verifier/src/one_time_witness_verifier.rs delete mode 100644 iota-execution/v0/iota-verifier/src/private_generics.rs delete mode 100644 iota-execution/v0/iota-verifier/src/struct_with_key_verifier.rs delete mode 100644 iota-execution/v0/iota-verifier/src/verifier.rs delete mode 100644 iota-execution/v0/iota-verifier/tests/common/mod.rs delete mode 100644 iota-execution/v0/iota-verifier/tests/common/module_builder.rs diff --git a/.github/crates-filters.yml b/.github/crates-filters.yml index 55ca74cc759..57a47dd7a25 100644 --- a/.github/crates-filters.yml +++ b/.github/crates-filters.yml @@ -180,9 +180,3 @@ iota-move-natives-latest: - "iota-execution/latest/iota-move-natives/**" iota-verifier-latest: - "iota-execution/latest/iota-verifier/**" -iota-adapter-v0: - - "iota-execution/v0/iota-adapter/**" -iota-move-natives-v0: - - "iota-execution/v0/iota-move-natives/**" -iota-verifier-v0: - - "iota-execution/v0/iota-verifier/**" diff --git a/Cargo.lock b/Cargo.lock index c00578c507c..e598cc0b441 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5794,33 +5794,6 @@ dependencies = [ "iota-transactional-test-runner", ] -[[package]] -name = "iota-adapter-v0" -version = "0.1.0" -dependencies = [ - "anyhow", - "bcs", - "iota-macros", - "iota-metrics", - "iota-move-natives-v0", - "iota-protocol-config", - "iota-types", - "iota-verifier-v0", - "leb128", - "move-binary-format", - "move-bytecode-utils", - "move-bytecode-verifier-meter", - "move-bytecode-verifier-v0", - "move-core-types", - "move-vm-config", - "move-vm-profiler", - "move-vm-runtime-v0", - "move-vm-types", - "parking_lot 0.12.3", - "serde", - "tracing", -] - [[package]] name = "iota-analytics-indexer" version = "0.7.0-alpha" @@ -6479,20 +6452,15 @@ version = "0.1.0" dependencies = [ "cargo_metadata 0.15.4", "iota-adapter-latest", - "iota-adapter-v0", "iota-move-natives-latest", - "iota-move-natives-v0", "iota-protocol-config", "iota-types", "iota-verifier-latest", - "iota-verifier-v0", "move-binary-format", "move-bytecode-verifier", "move-bytecode-verifier-meter", - "move-bytecode-verifier-v0", "move-vm-config", "move-vm-runtime", - "move-vm-runtime-v0", "petgraph 0.6.5", ] @@ -6615,14 +6583,14 @@ dependencies = [ "fastcrypto", "flate2", "fs_extra", - "iota-adapter-v0", + "iota-adapter-latest", "iota-config", "iota-execution", "iota-framework", "iota-framework-snapshot", "iota-genesis-common", "iota-move-build", - "iota-move-natives-v0", + "iota-move-natives-latest", "iota-protocol-config", "iota-sdk 1.1.5", "iota-simulator", @@ -6633,7 +6601,7 @@ dependencies = [ "move-compiler", "move-core-types", "move-package", - "move-vm-runtime-v0", + "move-vm-runtime", "packable", "prefix-hex", "prometheus", @@ -7210,28 +7178,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "iota-move-natives-v0" -version = "0.1.0" -dependencies = [ - "bcs", - "better_any", - "fastcrypto", - "fastcrypto-vdf", - "fastcrypto-zkp", - "indexmap 2.5.0", - "iota-protocol-config", - "iota-types", - "move-binary-format", - "move-core-types", - "move-stdlib-natives-v0", - "move-vm-runtime-v0", - "move-vm-types", - "rand 0.8.5", - "smallvec", - "tracing", -] - [[package]] name = "iota-network" version = "0.7.0-alpha" @@ -8305,21 +8251,6 @@ dependencies = [ "iota-transactional-test-runner", ] -[[package]] -name = "iota-verifier-v0" -version = "0.1.0" -dependencies = [ - "iota-protocol-config", - "iota-types", - "move-abstract-interpreter-v0", - "move-abstract-stack", - "move-binary-format", - "move-bytecode-utils", - "move-bytecode-verifier-meter", - "move-core-types", - "move-vm-config", -] - [[package]] name = "iota_stronghold" version = "2.1.0" @@ -9377,14 +9308,6 @@ dependencies = [ "move-bytecode-verifier-meter", ] -[[package]] -name = "move-abstract-interpreter-v0" -version = "0.1.0" -dependencies = [ - "move-binary-format", - "move-bytecode-verifier-meter", -] - [[package]] name = "move-abstract-stack" version = "0.0.1" @@ -9486,20 +9409,6 @@ dependencies = [ "move-vm-config", ] -[[package]] -name = "move-bytecode-verifier-v0" -version = "0.1.0" -dependencies = [ - "move-abstract-interpreter", - "move-abstract-stack", - "move-binary-format", - "move-borrow-graph", - "move-bytecode-verifier-meter", - "move-core-types", - "move-vm-config", - "petgraph 0.5.1", -] - [[package]] name = "move-bytecode-viewer" version = "0.1.0" @@ -9870,20 +9779,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "move-stdlib-natives-v0" -version = "0.1.1" -dependencies = [ - "hex", - "move-binary-format", - "move-core-types", - "move-vm-runtime-v0", - "move-vm-types", - "sha2 0.9.9", - "sha3 0.9.1", - "smallvec", -] - [[package]] name = "move-symbol-pool" version = "0.1.0" @@ -9988,24 +9883,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "move-vm-runtime-v0" -version = "0.1.0" -dependencies = [ - "better_any", - "fail", - "move-binary-format", - "move-bytecode-verifier-v0", - "move-core-types", - "move-vm-config", - "move-vm-profiler", - "move-vm-types", - "once_cell", - "parking_lot 0.11.2", - "smallvec", - "tracing", -] - [[package]] name = "move-vm-test-utils" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 0a0ff6300d9..f531d7a4b54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,11 +53,6 @@ exclude = [ "external-crates/move/crates/move-vm-types", "external-crates/move/crates/serializer-tests", "external-crates/move/crates/test-generation", - "external-crates/move/move-execution/v0/crates/bytecode-verifier-tests", - "external-crates/move/move-execution/v0/crates/move-abstract-interpreter", - "external-crates/move/move-execution/v0/crates/move-bytecode-verifier", - "external-crates/move/move-execution/v0/crates/move-stdlib-natives", - "external-crates/move/move-execution/v0/crates/move-vm-runtime", "sdk/move-bytecode-template", ] members = [ @@ -162,9 +157,6 @@ members = [ "iota-execution/latest/iota-adapter", "iota-execution/latest/iota-move-natives", "iota-execution/latest/iota-verifier", - "iota-execution/v0/iota-adapter", - "iota-execution/v0/iota-move-natives", - "iota-execution/v0/iota-verifier", ] [workspace.package] diff --git a/crates/iota-genesis-builder/Cargo.toml b/crates/iota-genesis-builder/Cargo.toml index a70eac62788..81d3c77ffe1 100644 --- a/crates/iota-genesis-builder/Cargo.toml +++ b/crates/iota-genesis-builder/Cargo.toml @@ -40,14 +40,14 @@ tracing.workspace = true tracing-subscriber = "0.3" # internal dependencies -iota-adapter-v0 = { path = "../../iota-execution/v0/iota-adapter/" } +iota-adapter-latest = { path = "../../iota-execution/latest/iota-adapter/" } iota-config.workspace = true iota-execution.workspace = true iota-framework.workspace = true iota-framework-snapshot.workspace = true iota-genesis-common.workspace = true iota-move-build.workspace = true -iota-move-natives-v0 = { path = "../../iota-execution/v0/iota-move-natives" } +iota-move-natives-latest = { path = "../../iota-execution/latest/iota-move-natives" } iota-protocol-config.workspace = true iota-sdk = { version = "1.1", default-features = false, features = ["irc_27", "irc_30", "std"] } iota-types.workspace = true @@ -55,7 +55,7 @@ move-binary-format.workspace = true move-compiler.workspace = true move-core-types.workspace = true move-package.workspace = true -move-vm-runtime-v0 = { path = "../../external-crates/move/move-execution/v0/crates/move-vm-runtime" } +move-vm-runtime-latest = { path = "../../external-crates/move/crates/move-vm-runtime", package = "move-vm-runtime" } shared-crypto.workspace = true [target.'cfg(msim)'.dependencies] diff --git a/crates/iota-genesis-builder/src/stardust/migration/executor.rs b/crates/iota-genesis-builder/src/stardust/migration/executor.rs index 8c7b6fb96f6..816123dba63 100644 --- a/crates/iota-genesis-builder/src/stardust/migration/executor.rs +++ b/crates/iota-genesis-builder/src/stardust/migration/executor.rs @@ -7,13 +7,13 @@ use std::{ }; use anyhow::Result; -use iota_adapter_v0::{ +use iota_adapter_latest::{ adapter::new_move_vm, execution_mode, gas_charger::GasCharger, programmable_transactions, temporary_store::TemporaryStore, }; use iota_framework::BuiltInFramework; use iota_move_build::CompiledPackage; -use iota_move_natives_v0::all_natives; +use iota_move_natives_latest::all_natives; use iota_protocol_config::{Chain, ProtocolConfig, ProtocolVersion}; use iota_sdk::types::block::output::{ AliasOutput, BasicOutput, FoundryOutput, NativeTokens, NftOutput, OutputId, TokenId, @@ -44,7 +44,7 @@ use iota_types::{ }, }; use move_core_types::{ident_str, language_storage::StructTag}; -use move_vm_runtime_v0::move_vm::MoveVM; +use move_vm_runtime_latest::move_vm::MoveVM; use crate::{ process_package, diff --git a/dprint.json b/dprint.json index 17a5a9f5404..efec70de71e 100644 --- a/dprint.json +++ b/dprint.json @@ -20,7 +20,6 @@ "crates/iota-light-client/example_config/20873329.yaml", "**/pnpm-lock.yaml", "external-crates/move/crates/move-stdlib/**/docs/**/*.md", - "external-crates/move/move-execution/v0/crates/move-stdlib/**/docs/**/*.md", "nre/helm/graphql/templates/**/*.yaml", "nre/helm/indexer/templates/**/*.yaml" ], diff --git a/external-crates/move/Cargo.lock b/external-crates/move/Cargo.lock index 5446c9a86a3..812fbf776bc 100644 --- a/external-crates/move/Cargo.lock +++ b/external-crates/move/Cargo.lock @@ -361,20 +361,6 @@ dependencies = [ "petgraph", ] -[[package]] -name = "bytecode-verifier-tests-v0" -version = "0.1.0" -dependencies = [ - "hex", - "move-abstract-interpreter", - "move-binary-format", - "move-bytecode-verifier-meter", - "move-bytecode-verifier-v0", - "move-core-types", - "move-vm-config", - "petgraph", -] - [[package]] name = "bytecode-verifier-transactional-tests" version = "0.1.0" @@ -1468,15 +1454,6 @@ dependencies = [ "move-bytecode-verifier-meter", ] -[[package]] -name = "move-abstract-interpreter-v0" -version = "0.1.0" -dependencies = [ - "itertools", - "move-binary-format", - "move-bytecode-verifier-meter", -] - [[package]] name = "move-abstract-stack" version = "0.0.1" @@ -1581,20 +1558,6 @@ dependencies = [ "move-vm-config", ] -[[package]] -name = "move-bytecode-verifier-v0" -version = "0.1.0" -dependencies = [ - "move-abstract-interpreter", - "move-abstract-stack", - "move-binary-format", - "move-borrow-graph", - "move-bytecode-verifier-meter", - "move-core-types", - "move-vm-config", - "petgraph", -] - [[package]] name = "move-bytecode-viewer" version = "0.1.0" @@ -2011,20 +1974,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "move-stdlib-natives-v0" -version = "0.1.1" -dependencies = [ - "hex", - "move-binary-format", - "move-core-types", - "move-vm-runtime-v0", - "move-vm-types", - "sha2", - "sha3", - "smallvec", -] - [[package]] name = "move-symbol-pool" version = "0.1.0" @@ -2158,27 +2107,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "move-vm-runtime-v0" -version = "0.1.0" -dependencies = [ - "anyhow", - "better_any", - "fail", - "hex", - "move-binary-format", - "move-bytecode-verifier-v0", - "move-core-types", - "move-vm-config", - "move-vm-profiler", - "move-vm-types", - "once_cell", - "parking_lot 0.11.2", - "proptest", - "smallvec", - "tracing", -] - [[package]] name = "move-vm-test-utils" version = "0.1.0" diff --git a/external-crates/move/Cargo.toml b/external-crates/move/Cargo.toml index 2e927598fc5..553f221bceb 100644 --- a/external-crates/move/Cargo.toml +++ b/external-crates/move/Cargo.toml @@ -3,11 +3,6 @@ resolver = "2" members = [ "crates/*", - "move-execution/v0/crates/bytecode-verifier-tests", - "move-execution/v0/crates/move-abstract-interpreter", - "move-execution/v0/crates/move-bytecode-verifier", - "move-execution/v0/crates/move-stdlib-natives", - "move-execution/v0/crates/move-vm-runtime", # "move-execution/$CUT/crates/bytecode-verifier-tests", # "move-execution/$CUT/crates/move-abstract-interpreter", # "move-execution/$CUT/crates/move-bytecode-verifier", diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/Cargo.toml b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/Cargo.toml deleted file mode 100644 index e6484d36ef7..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "bytecode-verifier-tests-v0" -version = "0.1.0" -authors = ["IOTA Foundation "] -edition = "2021" -license = "Apache-2.0" -publish = false -description = "Move bytecode verifier tests" - -[dev-dependencies] -hex.workspace = true -petgraph.workspace = true - -move-abstract-interpreter.workspace = true -move-binary-format = { workspace = true, features = ["fuzzing"] } -# referred to via path for execution versioning -move-bytecode-verifier = { path = "../move-bytecode-verifier", package = "move-bytecode-verifier-v0" } -move-bytecode-verifier-meter.workspace = true -move-core-types.workspace = true -move-vm-config.workspace = true - -[features] -fuzzing = ["move-binary-format/fuzzing"] diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/METER_TESTING.md b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/METER_TESTING.md deleted file mode 100644 index 2f1865f6ed6..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/METER_TESTING.md +++ /dev/null @@ -1,5 +0,0 @@ -This testsuite can be run in a specific way to print the time until a 'complex' program is detected or accepted. Call as in: - -``` -cargo test --release -- --nocapture 1>/dev/null -``` diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/lib.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/lib.rs deleted file mode 100644 index 0dc645aec48..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/lib.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -#![forbid(unsafe_code)] - -#[cfg(test)] -pub mod support; - -#[cfg(test)] -pub mod unit_tests; diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/support/mod.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/support/mod.rs deleted file mode 100644 index 266dddf48a2..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/support/mod.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::{ - file_format::{ - empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, IdentifierIndex, - ModuleHandleIndex, SignatureIndex, - }, - CompiledModule, -}; - -/// Create a dummy module to wrap the bytecode program in local@code -pub fn dummy_procedure_module(code: Vec) -> CompiledModule { - let mut module = empty_module(); - let code_unit = CodeUnit { - code, - ..Default::default() - }; - let fun_def = FunctionDefinition { - code: Some(code_unit), - ..Default::default() - }; - - let fun_handle = FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(0), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }; - - module.function_handles.push(fun_handle); - module.function_defs.push(fun_def); - module -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/binary_samples.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/binary_samples.rs deleted file mode 100644 index 624004452a2..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/binary_samples.rs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -//! Tests in here are based on binary representation of modules taken from -//! production. Those tests may fail over time if the representation becomes out -//! of date, then they can be removed. Right now the serve to calibrate the -//! metering working as expected. Those tests represent cases which we want to -//! continue to succeed. - -use move_binary_format::{errors::VMResult, CompiledModule}; -use move_bytecode_verifier::verifier; -use move_bytecode_verifier_meter::bound::BoundMeter; - -use crate::unit_tests::production_config; - -#[allow(unused)] -fn run_binary_test(name: &str, bytes: &str) -> VMResult<()> { - let bytes = hex::decode(bytes).expect("invalid hex string"); - let m = CompiledModule::deserialize_with_defaults(&bytes).expect("invalid module"); - let (verifier_config, meter_config) = production_config(); - let mut meter = BoundMeter::new(meter_config); - verifier::verify_module_with_config_for_test(name, &verifier_config, &m, &mut meter) -} - -#[test] -fn sample_price_oracle() { - let code = "a11ceb0b050000000c01001602162003368a0104c0011405d401a80607fc07f90308f50b6006d50c9b3210f03e770ae73f170cfe3f951e0d935e060000010101020103010401050006020702080209020a000b0800000c0800080d070004170402030100010318070009190700071c0700000e000100000f0201010000100201010000110302000012030200001304020000140506000015050600080f080900071d0a0100081e080900071f0a0b0007200a010006210c01000122020f01000123020c01000424110b020300042511120203000a261314000527020f0100022803180004290219020304092a1a1b00032b1a0f00042c1c02020302020e0e0e0f0e10101110130e1016111615101810020608020201030001060c02060c0304030103010203010908060303080603010301030106080201080601060806010101020502060800080508040802010900010804020804080502060b0302090009010900010609010208050301080202080406080102080403ae010a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a02080508000708000a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050a0208050105010b030209000901010a0201080503070b0302090009010900090193010508000708000a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a020a02080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805080508050805010708000b03030101010301030103010b01030101010301030103010c70726963655f6f7261636c6504636f696e067369676e657206737472696e67057461626c6509747970655f696e666f046d617468036936340570726963651070726963655f6964656e74696669657204707974681250726963654964656e7469666965724d61700e54657374507269636553746f72650550726963650c666f726d61745f7072696365096765745f7072696365126765745f70726963655f666f725f746573740a696e697469616c697a6512696e697469616c697a655f746573746e6574127365745f7468726573686f6c645f73656373107369676e65645f7536345f6d696e75730f7369676e65645f7536345f706c757304696e666f055461626c6506537472696e670f50726963654964656e7469666965720e7468726573686f6c645f736563730b70726963655f7461626c6503493634196765745f6d61676e69747564655f69665f706f736974697665086765745f6578706f0f6765745f69735f6e65676174697665196765745f6d61676e69747564655f69665f6e6567617469766506706f775f31300673796d626f6c08646563696d616c7308636f6e7461696e7306626f72726f77176765745f70726963655f6e6f5f6f6c6465725f7468616e09747970655f6e616d650a616464726573735f6f66036e65770d66726f6d5f627974655f76656304757466380675707365727414812adfd8ba2f589c0fe48c5170fa287cd36050dd487d17e2f4a765101f70ed00000000000000000000000000000000000000000000000000000000000000017e783b349d3e89cf5931af376ebeadbfab855b3fa239b7ada8f5a92fbea6b3870308700000000000000003086d0000000000000003086e0000000000000003081000000000000000052014812adfd8ba2f589c0fe48c5170fa287cd36050dd487d17e2f4a765101f70ed0a0221202b9ab1e972a281585084148ba1389800799bd4be63b957507db1349314e474450a020504414156450a022120bd640cddb72063e2ede34c6a0baf6699759b9837fcb06aa0e2fbcecb9b65fde70a02040341434d0a0221202a01deaec9e51a579277b34b122399984d0bbf57e2458a7e42fecd2829867a0d0a0204034144410a022120fa17ceaf30d19ba51112fdcc750cc83454776f47fb0112e4af07f15f4bb1ebc00a020504414c474f0a0221206d0af467543fc7daedf7abed96423877560c8d03725f3e5c87516774982a679c0a020403414e430a02212015add95022ae13563a11992e727c91bdb6b55bc183d9d747436c80a483d8c8640a0204034150450a02212003ae4db29ed4ae33d323568895aa00337e658e348b37509f5372ae51f0af00d50a0204034150540a022120b881c6dad5dd3dc9a83222f8032fb439859288119afc742d43adc305cef151cc0a0204034153520a022120681e0eb7acf9a2a3384927684d932560fb6f67c6beb21baa0f110e993b2653860a02060541544c41530a0221208ff1200345393bb25be4f4eeb2d97234e91f7e6213f3745a694b1436e700f2710a02040341544d0a022120b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e6128190a02050441544f4d0a0221204cbd623d7aa47003fff1cd75c3f96cb24a660014b697d91cfb7adcd204b952020a020504415553540a02212093da3352f9f1d105fdfe4971cfa80e9dd777bfc5d0f683ebb6e1294b92137bb70a020504415641580a022120b7e3904c08ddd9c0c10c6d207d390fd19e87eb6aab96304f571ed94caebdefa00a0204034158530a0221209d23a47f843f5c9284832ae6e76e4aa067dc6072a58f151d39a65a4cc792ef9f0a0204034241520a0221203dd2b63686a450ec7290df3a1e0b583c0481f651351edfa7636f39aed55cf8a30a0204034243480a0221207f981f906d7cfe93f618804f1de89e0199ead306edc022d3230b3e8305f391b00a020504424554480a0221202f95862b045670cd22bee3114c39763a4a08beeb663b145d283c31d7d1101c4f0a020403424e420a0221201ce9069708fb49e2f1b062fa4f1be0bb151475ca506939d6d8c14386d49f43dc0a02040342525a0a022120e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b430a0204034254430a022120097d687437374051c75160d648800f021086bc8edf469f11284491fda81923150a0204034254540a0221205bc91f13e412c07599167bae86f07543f076a638962b8d6017ec19dab4a828140a020504425553440a0221202dd14c7c38aa7066c7a508aac299ebcde5165b07d5d9f2d94dfbfe41f0bc5f2e0a0204034339380a0221202356af9529a1064d41e32d617e2ce1dca5733afa901daba9e2b68dee5d53ecf90a02050443414b450a02212015ecddd26d49e1a8f1de9376ebebc03916ede873447c1255d2d5891b92ce57170a02060543424554480a022120bd4dbcbfd90e6bc6c583e07ffcb5cb6d09a0c7b1221805211ace08c8378596270a0204034348520a022120e799f456b358a2534aa1b45141d454ac04b444ed23b1440b778549bb758f2b5c0a02040343485a0a0221209c479b12a2b2c1051715d4d462dd7a6abbb6dccabf3af31a53f6130a1cd88efc0a020504434954590a0221208517b35589b5f1f6ad626da2379ff592d5101b63aa661d75b7a883fdbda023f00a020504434f50450a0221204e53c6ef1f2f9952facdcf64551edb6d2a550985484ccce6a0477cae4c1bca3e0a020403434f570a0221208f218655050a1476b780185e89f19d2b1e1f49e9bd629efad6ac547a946bf6ab0a020504435553440a022120b0948a5e5313200c632b51bb5ca32f6de0d36e9950a942d19751e833f70dabfd0a0204034441490a022120dcef50dd0a4cd2dcc17e45df1676dcb336a11a61c69df7a0299b0150c672d25c0a020504444f47450a022120ca3eed9b267293f6595901c734c7525ce8ef49adafe8284606ceb307afa2ca5b0a020403444f540a022120ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0a0204034554480a022120c80657b7f6f3eac27218d09d5a4e54e47b25768d9f5e10ac15fe2cf9008814000a020504464944410a0221202fb245b9a84554a0f15aa123cbb5f64cd263b59e9a87d80148cbffab50c69f300a020504464c4f570a0221205c6c0d2386e3352356c3ab84434fafb5ea067ac2678a38a338c4a69ddc4bdb0c0a02040346544d0a0221206c75e52531ec5fd3ef253f6062956a8508a2f03fa0a209fb7fbc51efd9d35f880a0204034654540a022120301377b122716cee1a498e7930a1836c0b1db84667cc78bbbcbad6c330ea6afb0a02040347414c0a0221200781209c28fda797616212b7f94d77af3a01f3e94a5d421760aef020cf2bcb510a02050447414c410a022120baa284eaf23edf975b371ba2818772f93dbae72836bbdea28b07d40f3cf8b4850a020403474d540a0221206034b1f68b9363dff2cf9d53b1a88fb4d0929c65f34d532db53738853efc00ad0a020504474f46580a02212095609d32c98a467a72ac419f2e64bb2b8dbd5b00b74f3a0fd72f42343af1743d0a0205044858524f0a0221207a5bc1d2b56ad029048cd63964b3ad2776eadf812edc1a43a31406cb54bff5920a020403494e4a0a022120a4702f0f5818258783a1e47f453cb20b0fbec32ca67260e1d19dfcdd6a4d0ebb0a020605494e5445520a02212081a21b01c15b8d01f6cdfed65e00987cc4c901858c821b2089344987de3102e90a0204034a45540a022120ee42016c303126bd9263724e00f83a8114e84518c6e8ffc9738c001cc301daff0a0204034a53540a022120abe4f2b264560a397f38eec024369356e5c1ea4f7aab94729369f144b3d977790a0204034a55560a022120d1d95644ffc11ca502f21e067a7814144c56b37018515ced4335a886a827a3050a0206054c415a494f0a0221206e3f3fa8253588df9326580180233eb791e03b443a3ba7a1d892e73874e19a540a0204034c54430a022120e6ccd3f878cf338e6732bf59f60943e8ca2c28402fc4d9c258503b2edbe74a310a0205044c554e410a0221204456d442a152fd1f972b18459263ef467d3c29fb9d667e30c463b086691fbc790a0205044c554e430a0221205de33a9112c2b700b8d30b8a3402c103578ccfa2765696471cc672bd5cf6ac520a0206054d415449430a0221201888f463c27997174f97d2a36af29bf4648b61a5f69e67c45505a80f826bb7850a0205044d424f580a02212027d108eb764c912f49d3453a21dd95516619b1c45d0b607ee58a137ac8a6f32d0a0205044d45414e0a022120dfaeafde7f8ad3cb9ddbcc85ed7ae7e53910e7ab377fd75921920f97c80a8edc0a0204034d45520a0221200b46c1c04e9c914037cc4e0561a7e6787f6db0b89b7b65281f0f6fea1ce45a740a0204034d49520a0221205b70af49d639eefe11f20df47a0c0760123291bb5bc55053faf797d1ff9059830a0205044d4e474f0a022120c2289a6a43d2ce91c6f55caec370f4acc38a2ed477f58813334c6d03749ff2a40a0205044d534f4c0a022120c415de8d2eba7db216527dff4b60e8f3a5311c740dadb233e13e12547e2267500a0205044e4541520a02212005934526b94a9fbe4c4ce0c3792213032f086ee4bf58f2168a7085361af9bdc10a0203024f470a022120c572690504b42b57a3f7aed6bd4aae08cbeeebdadcf130646a692fe73ec1e0090a0204034f4e450a02212037505261e557e251290b8c8899453064e8d760ed5c65a779726f2490980da74c0a0205044f5243410a0221200afa3199e0899270a74ddcf5cc960d3c6c4414b4ca71024af1a62786dd24f52a0a020504504f52540a02212088e2d5cbd2474766abffb2a67a58755a2cc19beb3b309e1ded1e357253aa36230a020605504f52544f0a0221203d253019d38099c0fe918291bd08c9b887f4306a44d7d472c8031529141f275a0a0204035053470a022120fd0690232b0fae5efdc402c1b9aac74176383ff7daf87d021554bda24a38e0ec0a020504524143410a02212091568baa8beb53db23eb3fb7f22c6e8bd303d103919e19733f2bb642d3e7987a0a0204035241590a0221206ed3c7c4427ae2f91707495fc5a891b30795d93dbb3931782ddd77a5d8cb6db70a0204035342520a0221201021a42d623ab4fe0bf8c47fd21cc10636e39e07f91e9b2478551e137d512aaa0a02070653434e534f4c0a022120f8d030e4ef460b91ad23eabbbb27aec463e3c30ecc8d5c4b71e92f54a36ccdbd0a020504534c4e440a0221209fb0bd29fe51481b61df41e650346cc374b13c2bab2e3610364cd834a592025a0a020403534e590a022120ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d0a020403534f4c0a02212023245bb74254e65a98cc3ff4a37443d79f527e44e449750ad304538b006f21bc0a02040353524d0a022120a1a6465f4c2ebf244c31d80bc95c27345a3424e428c2def33eced9e90d3f701b0a0206055354534f4c0a0221204457960559b812558bb0f8cb7912f8bcb843eb801a3133ef45be998630ff8c050a020403544c4d0a022120433faaa801ecdb6618e3897177a118b273a8e18cc3ff545aadfc207d58d028f70a020504545553440a022120eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a0a020504555344430a0221202b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b0a020504555344540a022120ef94acc2fb09eb976c6eb3000bab898cab891d5b800702cd1dc88e61d7c3c5e60a020504555354430a0221207507a4629ad0143550666bce2e7cae0b961a0f624f821feaab642fe1be632f5c0a0204035641490a022120b216f7ca372b318985903866e0b6dc44a14564828c49f36d0d363805aa76335c0a02040357494e0a022120b82449fd728133488d2d41131cffe763f9c1693b73c544d9ef6aaa371060dd250a020403574f4f0a022120831624f51c7bd4499fe5e0f16dfa2fd22584ae4bdc496bbbbe9ba831b2d9bce90a0204035856530a02212026852e2d0696e25e6adaad2d7ca3a1f2f15aab68d317ace14d41b4128a7e780f0a0204035a42430a022120d6b3bc030a8bbb7dd9de46fb564c34bb7f860dead8985eb16a49cdc62f8ab3a50a02212073dc009953c83c944690037ea477df627657f45c14f16ad3a61089c5a3f9f4f20a02212008f781a893bc9340140c5f89c8a96f438bcfae4d1474cc0f688e3a52892c73180a0221204204a764d9e0ca8db0fd43b62728265bf82671ce8a8b4bfedba13672be12de620a022120cb1743d0e3e3eace7e84b8230dc082829813e3ab04e91b503c08e9a441c0ea8b0a02212044a93dddd8effa54ea51076c4e851b6cbbfd938e82eb90197de38fe8876bb66e0a022120c11efd88a9b2c96bc84bccd6ce4aa05bebad7aa760dbe5f2f00ef90c4abd50cc0a02212061226d39beea19d334f17c2febce27e12646d84675924ebb02b9cdaea68727e30a022120d7566a3ba7f7286ed54f4ae7e983f4420ae0b1e0f3892e11f9c4ab107bbad7b90a02212030029479598797290e3638a1712c29bde2367d0eca794f778b25b5a472f192de0a022120fc309467defa4b198c6b5bd59c08db4b9dfb27ddbcc32f31560f217b4ff8fc2b0a022120ecf553770d9b10965f8fb64771e93f5690a182edc32be4a3236e0caaa6e0581a0a022120457064c555edae5b6b89267e992be4c58be5375f0e9ca9749391c7094f7d90330a022120f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b0a022120eb3b5720301b36fa074260e6e27e2cfff3a7c6bbb47564eb218a9a7f2a8c01930a02212006c532524fabd49cc142815502d785e4f34ec3bd035480efb770568d423f46c60a022120c098773aa18ebb7e84d5ee7ea7d97105ab2015a329f670012398cd2c8f5cc6ca0a0221200d10b9ccdc9af1d65cd4bafabf4e34db01c0ce83abba190230eaf26d7592cd210a022120970541e943e11d1bf1d4d763bc8e70995f613dc682f727045a866312312a63760a02212013ac8c71e4e1c61dece57bea76163d393bf75cd0db8e52981e1564fa592698cb0a022120b59d65c2e10af17c0d6f7d10be8d64c0c13dd15d957c4c39763b4cc55e5919370a02212087a67534df591d2dd5ec577ab3c75668a8e3d35e92e27bf29d9e2e52df8de4120a02212031775e1d6897129e8a84eeba975778fb50015b88039e9bc140bbd839694ac0ae0a02212036032e522b810babd8e3148e9f0d588af9e95e93b97ffb58566b837fdbd31f7f0a022120ca80ba6dc32e08d06f1aa886011eed1d77c77be9eb761cc10d72b7d0a2fd57a60a0221206660d7629213995af8aa169ad6a1cf1a725765d3741b7e7a27825f884a701b960a022120aa67a6594d0e1578faa3bba80bec5b31e461b945e4fbab59eeab38ece09335fb0a0221209b7bfd7654cbb80099d5edc0a29159afc9e9b4636c811cf8c3b95bd11dd8e3dd0a0221200184a60a47ab7c23fcb828d727b05748ef52433fb5ae96f775cc98c9049d8c2c0a0221206354d685c247f1efc36f967617beffa2ebd5a95d8ffe17de4498505c923067b80a02212021adabf73ad61903c1872fa220f84d3b1b9990cec2047f8317e2a67efcd1764e0a022120c999fe8a75bf9528931deb832e2934dd1ac138757d7f2c1398675b6f521d556f0a02212087fd5a8d0bf026239f98b53311d2cec2ee171e853f545e1ad742e092a97ef8600a02212051ae9b785e6aeb288955720faef15f63ee3ae21af38114ade8b3fc3d3831b5ad0a0221202d9315a88f3019f8efa88dfe9c0f0843712da0bac814461e27733f6b83eb51b30a0221202245aec1db780b8dc9f710173256996164f0a65f25a975453e4202a54371d2ea0a022120077e345652cb98edba89815a63a0ede724eba12d7a10c8498e0e762d581aca6b0a022120997e0bf451cb36b4aea096e6b5c254d700922211dd933d9d17c467f0d6f343210a022120677dbbf4f68b5cb996a40dfae338b87d5efb2e12a9b2686d1ca16d69b3d7f2040a0221206de025a4cf28124f8ea6cb8085f860096dbc36d9c40002e221fc449337e065b20a022120d2c2c1f2bba8e0964f9589e060c2ee97f5e19057267ac3284caef3bd50bd2cb50a02212070bf2974182b6ebf4eac64977170074315e7a07d7b58a963758060924ee9a1920a0221209f2acb902ee5c3a8e41c643164a498ed3089c99df3477189babd3682801340750a02212052800482aa2666c0d2621f8f0a8c19ee6e5e5039a65524e268315501b3355fbb0a0221202f317bea04ce89adb8acc85a1a68d20d6e89976d5e86306570a0bb3107e4916a0a022120b5366e5ded52c3db5d81635a624a39d81eb8c639427fc79c539e5c91e17c84940a0221207f57ca775216655022daa88e41c380529211cde01a1517735dbcf30e4a02bdaa0a02212027e867f0f4f61076456d1a73b14c7edc1cf5cef4f4d6193a33424288f11bd0f40a0221209b245faf19d2f3306b58821ef60b194d7b67eb5250635059d8eaae4a36337b280a02212085dafbfa99c733fdd33649551666958ca8f82fd0d849746e093b770caab249d20a0221206b86b78584e182c61729267d73593f48b6a929f3218234769281513cbe5e87ee0a0204035041490a0221201e761bb4e6b1e4d7899b618d389516ddbdfbdb858018b71c45cb6ade57c96f620a0221207730809b4a4656325b7fbc8157fd803c3da170727c541afc4db37773246258b10a022120cb9372930932694b8a74dd5599c0f9e236575f434faf05141d95803a91f044ed0a022120341d9502b1e6bc445036fd76f57bc824c09254a754289878b52a40eb067d2a0b0a022120f9917668f24038a383e51c0b019f5d9645d6785c6bf9a0d48483edf82ba5caec0a022120dd51a67a1b4d0702abf5b5385631b7d3e586993eadacf2e0d900c0a81edcffdd0a022120b5d2cee0b86bb0571db898ae7b9f288c5e272fa486d41a5bf375b52a0249d94c0a022120fe650f0367d4a7ef9815a593ea15d36593f0643aaaf0149bb04be67ab851decd0a02212078ec25615d53d2486db101e829f77615c4408cbbd543088714b9f267da44591a0a022120b718e659619a031b41c6ea9122f146859a82d4a7edc17c55b1e5188e8b4c1d1c0a020504535445500a02212013f7925c9186b8cca50dde4bbf2d4fa9705052cceb6f2fc79df827e2b37d6f3b0a0221200adbf6463e27f60f171bcc498703a4282d1954ec3a85e1f6698b48ecde18c00e0a0221201bd1c59cd425aebf8a931c1b2a902b9a11e7d18dc68021e4a35a5cf24220a6c70a02212041f3625971ca2ed2263e78573fe5ce23e13d2558ed3f2e47ab0f84fb9e7ae7220a0221201fc18861232290221461220bd4e2acd1dcdfbc89c84092c93c18bdc7756c15880a022120026d1f1cf9f1c0ee92eb55696d3bd2393075b611c4f468ae5b967175edc4c25c0a022120eca4f9c5ce7cbef8a349fa9f6c12b23ac45b9ad91c4d1808c6a2dda841f95a020a022120834d3f05278b6f5c963670f437a2267c160914707328f888418902106bcd13d70a022120bf517e0f7ccfc307f0b2fa93b99a737641933989af6af769c928725989c21e660a0221206ff709bf1f0fdb46d991ae6839163df1e050d143429d737fc650b6b2143478080a02212064abe8a459058c60d55427f62be3dc4942c0ba93d1eb5cb85117b70b8e4651ad126170746f733a3a6d657461646174615f763063036d000000000000001a4552525f4e4f545f454e4f5547485f5045524d495353494f4e53006e00000000000000134552525f544f4b454e5f4e4f545f464f554e44007000000000000000174552525f414c52454144595f494e495449414c495a454400000202160b0302080408051a030102011b0b03020804030000000007440a0011080c020e0211090c080b00110a0c050600000000000000000c0a090c090b0a0b0907030911070c090c0a0e05110b0c070a07031a051e0e05110c0c0305210e0511090c030b030c060b0a0b090b060b0711070c090c0a0b0a0b090b01340911060c090c0a0b090335053c0b080b0a33110d1a0c0405420b080b0a33110d180c040b04020101000200010d26070429010304050638000238010c0338020c0007042b000c010a0110000a03380303160b01010702270a0110000b033804140c020b020b0110011411120c040e040b001100020200000101151438050c0007042b010c010a0110020a003806030e0b01010702270b0110020b0038071402030104010017a4060a00111407042103090b00010701270a00111429002003120b00010700273808063c0000000000000012000c6b0a000b6b2d000b0011142a000c6c070511160c020a6c0f00070611170b023809070711160c040a6c0f00070811170b043809070911160c060a6c0f00070a11170b063809070b11160c080a6c0f00070c11170b083809070d11160c0a0a6c0f00070e11170b0a3809070f11160c0c0a6c0f00071011170b0c3809071111160c0e0a6c0f00071211170b0e3809071311160c100a6c0f00071411170b103809071511160c120a6c0f00071611170b123809071711160c140a6c0f00071811170b143809071911160c160a6c0f00071a11170b163809071b11160c180a6c0f00071c11170b183809071d11160c1a0a6c0f00071e11170b1a3809071f11160c1c0a6c0f00072011170b1c3809072111160c1e0a6c0f00072211170b1e3809072311160c200a6c0f00072411170b203809072511160c220a6c0f00072611170b223809072711160c240a6c0f00072811170b243809072911160c260a6c0f00072a11170b263809072b11160c280a6c0f00072c11170b283809072d11160c2a0a6c0f00072e11170b2a3809072f11160c2c0a6c0f00073011170b2c3809073111160c2e0a6c0f00073211170b2e3809073311160c300a6c0f00073411170b303809073511160c320a6c0f00073611170b323809073711160c340a6c0f00073811170b343809073911160c360a6c0f00073a11170b363809073b11160c380a6c0f00073c11170b383809073d11160c3a0a6c0f00073e11170b3a3809073f11160c3c0a6c0f00074011170b3c3809074111160c3e0a6c0f00074211170b3e3809074311160c400a6c0f00074411170b403809074511160c420a6c0f00074611170b423809074711160c440a6c0f00074811170b443809074911160c460a6c0f00074a11170b463809074b11160c480a6c0f00074c11170b483809074d11160c4a0a6c0f00074e11170b4a3809074f11160c4c0a6c0f00075011170b4c3809075111160c4e0a6c0f00075211170b4e3809075311160c500a6c0f00075411170b503809075511160c520a6c0f00075611170b523809075711160c540a6c0f00075811170b543809075911160c560a6c0f00075a11170b563809075b11160c580a6c0f00075c11170b583809075d11160c5a0a6c0f00075e11170b5a3809075f11160c5c0a6c0f00076011170b5c3809076111160c5e0a6c0f00076211170b5e3809076311160c600a6c0f00076411170b603809076511160c620a6c0f00076611170b623809076711160c640a6c0f00076811170b643809076911160c660a6c0f00076a11170b663809076b11160c680a6c0f00076c11170b683809076d11160c6a0a6c0f00076e11170b6a3809076f11160c6e0a6c0f00077011170b6e3809077111160c700a6c0f00077211170b703809077311160c720a6c0f00077411170b723809077511160c740a6c0f00077611170b743809077711160c760a6c0f00077811170b763809077911160c780a6c0f00077a11170b783809077b11160c7a0a6c0f00077c11170b7a3809077d11160c7c0a6c0f00077e11170b7c3809077f11160c7e0a6c0f0007800111170b7e380907810111160c80010a6c0f0007820111170b8001380907830111160c82010a6c0f0007840111170b8201380907850111160c84010a6c0f0007860111170b8401380907870111160c86010a6c0f0007880111170b8601380907890111160c88010a6c0f00078a0111170b88013809078b0111160c8a010a6c0f00078c0111170b8a013809078d0111160c8c010a6c0f00078e0111170b8c013809078f0111160c8e010a6c0f0007900111170b8e01380907910111160c90010a6c0f0007920111170b9001380907930111160c92010a6c0f0007940111170b9201380907950111160c94010a6c0f0007960111170b9401380907970111160c96010a6c0f0007980111170b9601380907990111160c98010a6c0f00079a0111170b98013809079b0111160c9a010a6c0f00079c0111170b9a013809079d0111160c9c010a6c0f00079e0111170b9c013809079f0111160c9e010a6c0f0007a00111170b9e01380907a10111160ca0010a6c0f0007a20111170ba001380907a30111160ca2010a6c0f0007a40111170ba201380907a50111160ca4010a6c0f0007a60111170ba401380907a70111160ca6010a6c0f0007a80111170ba601380907a90111160ca8010a6c0f0007aa0111170ba801380907ab0111160caa010a6c0f0007ac0111170baa01380907ad0111160cac010a6c0f0007ae0111170bac01380907af0111160cae010b6c0f0007b00111170bae0138090204010401001da7050a0011140c010a01070421030b0b00010701270a00111429002003140b0001070027380806504600000000000012000c020b000b022d000b012a000c0307b10111160c4c0a030f00070611170b4c380907b20111160c6d0a030f00070a11170b6d380907b30111160c780a030f00070c11170b78380907b40111160c83010a030f00070e11170b8301380907b50111160c8e010a030f00071011170b8e01380907b60111160c520a030f00071211170b52380907b70111160c5d0a030f00071611170b5d380907b80111160c650a030f00071a11170b65380907b90111160c660a030f00071e11170b66380907ba0111160c670a030f00072411170b67380907bb0111160c680a030f00072611170b68380907bc0111160c690a030f00072811170b69380907bd0111160c6a0a030f00072a11170b6a380907be0111160c6b0a030f00072c11170b6b380907bf0111160c6c0a030f00072e11170b6c380907c00111160c6e0a030f00073011170b6e380907c10111160c6f0a030f00073211170b6f380907c20111160c700a030f00073811170b70380907c30111160c710a030f00073e11170b71380907c40111160c720a030f00074011170b72380907c50111160c730a030f00074211170b73380907c60111160c740a030f00074411170b74380907c70111160c750a030f00074611170b75380907c80111160c760a030f00074811170b76380907c90111160c770a030f00074a11170b77380907ca0111160c790a030f00074c11170b79380907cb0111160c7a0a030f00074e11170b7a380907cc0111160c7b0a030f00075011170b7b380907cd0111160c7c0a030f00075211170b7c380907ce0111160c7d0a030f00075411170b7d380907cf0111160c7e0a030f00075611170b7e380907d00111160c7f0a030f00075811170b7f380907d10111160c80010a030f00075a11170b8001380907d20111160c81010a030f00075c11170b8101380907d30111160c82010a030f00075e11170b8201380907d40111160c84010a030f00076211170b8401380907d50111160c85010a030f00076411170b8501380907d60111160c86010a030f00076a11170b8601380907d70111160c87010a030f00076c11170b8701380907d80111160c88010a030f00076e11170b8801380907d90111160c89010a030f00077011170b8901380907da0111160c8a010a030f00077211170b8a01380907db0111160c8b010a030f00077411170b8b01380907dc0111160c8c010a030f00077611170b8c01380907dd0111160c8d010a030f00077811170b8d01380907de0111160c8f010a030f00077a11170b8f01380907df0111160c90010a030f00077c11170b9001380907e00111160c91010a030f00077e11170b9101380907e10111160c92010a030f0007820111170b9201380907e20111160c93010a030f0007840111170b9301380907e30111160c4d0a030f0007e40111170b4d380907e50111160c4e0a030f0007860111170b4e380907e60111160c4f0a030f00078c0111170b4f380907e70111160c500a030f00078e0111170b50380907e80111160c510a030f0007900111170b51380907e90111160c530a030f0007920111170b53380907ea0111160c540a030f0007940111170b54380907eb0111160c550a030f0007960111170b55380907ec0111160c560a030f0007980111170b56380907ed0111160c570a030f00079a0111170b57380907ee0111160c580a030f0007ef0111170b58380907f00111160c590a030f00079c0111170b59380907f10111160c5a0a030f00079e0111170b5a380907f20111160c5b0a030f0007a00111170b5b380907f30111160c5c0a030f0007a20111170b5c380907f40111160c5e0a030f0007a40111170b5e380907f50111160c5f0a030f0007a60111170b5f380907f60111160c600a030f0007a80111170b60380907f70111160c610a030f0007aa0111170b61380907f80111160c620a030f0007ac0111170b62380907f90111160c630a030f0007ae0111170b63380907fa0111160c640b030f0007b00111170b6438090205010401001e120a00111407042103090b00010701270b0011142a000c020b010b020f011502060000001f5d0a010a031f0305051c0a020a0026030a05110b020b0017090c070c0405170b000b0217080c070c040b040b070c060c05055a0a01031f05230a03200c080525090c080b080328052f0b000b0216080c0e0c0d05560b01200b031f0335053c0b000b0216090c0c0c0b05520a000a0226034105480b000b0217090c0a0c09054e0b020b0017080c0a0c090b090b0a0c0c0c0b0b0b0b0c0c0e0c0d0b0d0b0e0c060c050b050b060207000000205e0a010a031f03050508080c0705140a0120030c05100a03200c040512090c040b040c070b070317051e0b000b02160b010c060c05055b0b01032105250b03200c080527090c080b08032a05410a000a0224032f05360b000b0217080c0a0c09053c0b020b0017090c0a0c090b090b0a0c0e0c0d05570a020a00240346054d0b020b0017080c0c0c0b05530b000b0217090c0c0c0b0b0b0b0c0c0e0c0d0b0d0b0e0c060c050b050b060200000001010000"; - let res = run_binary_test("sample_price_oracle", code); - assert!(res.is_ok(), "{:?}", res) -} - -#[test] -fn sample_aptosd_swap() { - let code = "a11ceb0b050000000c0100160216300346ee0104b4022205d602960407ec06de0708ca0e40068a0f8b01109510f9010a8e12520ce012e80e0dc821160000010101020103010401050106010700080009000a000b0700000c0700000d0800000e0700000f07000a28040207000400042b0401060102380800083a0000063c070100000010000100001102010000120101000013030100001401010000150101000016020100001701040000180506000019010700001a020100001b020100001c010100001d000100001e020100001f02010000200001000021000100092f01090009300105000a310b0c02070604320e01010607330205000934010f0009350104000936010f000a37110f020704033900010100033b02010100093d0104000a3e1617020704063f180f01000640191a01000a411b1c02070409421d010005431f040005441f0400094501200009460104000947010f0009480901000a490125020704014a022601060a4b1128020704140a150d1a0a1b121c1315141e0a1f052005210a151e290a2a0d2a142a1e2b0a1b1303060c05030001060c02060c0301030105050303030303010a050c03030303030505070b0502050803070b0502050803070802070803070b0601080401020205080303070b050209000901090009010107090101080402070b060109000900010108070b05020508030501070b06010800030107080207080302060b05020900090109000108070108080108002d0b0901050b0901050b0901050c0b0901050b0901050b0901050b0901050b090105030303030303070b06010801070b06010801070b06010801070b0601080103070803070803070803070803070b0502050803070b0502050803070b0502050803070b0502050803070b090105070b090105070b090105070b09010503030b0901050b0901050b0901050b090105070802070802070802070802070802030301060b050209000901010b0901090001060b0901090001070b0901090001090002070b0502090009010900030709010b090109000b09010900020503010801020303010c04010103030a03030303030505070b0502050803070b0502050803070803070b0901050b090105070803070b0502050803070b0901050b0901050a050a0b0502050803060c030c0b060108040c0b060108000c0b060108010c010b050209000901010b060109000c0b0901050c070b0502050803050b090105070b06010801060803070b0502050803070b0901050b090105070802060c030609010b090109000b090109000d6170746f737061645f73776170076163636f756e740a6170746f735f636f696e04636f696e056576656e74066d6174683634066f7074696f6e067369676e65720d6170746f737061645f636f696e06636f6e6669670e6974657261626c655f7461626c65104269644170746f735061644576656e7417446973747269627574654170746f737061644576656e74114c61756e636850616452656769737472790f546f6b656e446973747269627574650e57686974654c6973744576656e740c61646457686974654c6973740c6173736572745f61646d696e136173736572745f6e6f5f656d657267656e63790b6269644170746f735061640d64697374726962757465416c6c0e64697374726962757465417470701064697374726962757465536561736f6e0f67657453776170546f74616c4269640c67657457686974654c6973740d67657457686974654c697374730a696e697469616c697a650f6c61756e6368506164536561736f6e09726566756e64416c6c0b726566756e644170746f730b7265736574536561736f6e0f77686974654c697374536561736f6e0d77697468647261774170746f731077697468647261774170746f73506164036361700362696408696e766573746f72106469737472696275746564546f6b656e06726566756e6409696e766573746f72730d4974657261626c655461626c6508746f74616c426964126269646170746f737061645f6576656e74730b4576656e7448616e646c6519646973747269627574656170746f737061645f6576656e74731077686974656c6973745f6576656e74730b64697374726962757465640c676574537761705374617465126765745265736f757263654164647265737317626f72726f775f6d75745f776974685f64656661756c740a656d69745f6576656e740a616464726573735f6f660b6973456d657267656e63791467657453776170436f6e6669674861726443617011697342797061737357686974654c69737408636f6e7461696e73094170746f73436f696e087472616e736665720c4170746f73506164436f696e087265676973746572064f7074696f6e1a67657453776170436f6e666967417074546f417074745261746508686561645f6b65790769735f736f6d6507657874726163740f626f72726f775f697465725f6d75740a6d696e7441747070546f036d696e036d6178116765745265736f757263655369676e65721467657453776170436f6e666967536f66744361701967657453776170436f6e666967456e61626c65526566756e640c736574537761705374617465036e6577106e65775f6576656e745f68616e646c650b626f72726f775f6974657241376d8231e6aedc29a19459e804b3770a250c3f367ac8d0f91e10842e8c906d0000000000000000000000000000000000000000000000000000000000000001030800e87648170000000308950100000000000003089a0100000000000003089b010000000000000308930100000000000003089801000000000000030896010000000000000308970100000000000003089901000000000000020104020105020101020103020102052041376d8231e6aedc29a19459e804b3770a250c3f367ac8d0f91e10842e8c906d126170746f733a3a6d657461646174615f7630e4010893010000000000000f4552525f5045524d495353494f4e530095010000000000000d4552525f454d455247454e4359009601000000000000104552525f534541534f4e5f454e444544009701000000000000144552525f534541534f4e5f4e4f545f5245534554009801000000000000114552525f534541534f4e5f414354495645009901000000000000104552525f534541534f4e5f5354415445009a01000000000000134552525f484152444341505f52454143484544009b01000000000000144552525f4e4f545f494e5f57484954454c4953540b6572726f7220636f64657300020322032303240501020522032303250326032405020205270b050205080329032a0b060108002c0b060108012d0b06010804030206220323032e03250326032405040206220323032e032503260324050001000102083c0b0011011112070d21030807082711132a020c0c0a0c0f000c0b0b0c0f010c0e0b0b0c0a0a010c090b010c080b0a0b090600000000000000000600000000000000000600000000000000000600000000000000000600000000000000000b08120338000c0d0b020a0d0f02150b0e0a0d1002140a0d1003140a0d1004140a0d1005140a0d1005140b0d10061412043801020100000001080b001116070e210307070427020200000001061117200305070127020301000102106111021112070c2103090b000107082711180c0611132a020c0811190c040a080f000a0011160c030c020b022e0b0338020c070b040b071e03250b00010b08010703270a081007140b062503310b00010b08010702270a081007140a01160a080f07150a080f080c050a0011130a0138030a0038040b080f000a00111607000600000000000000000600000000000000000600000000000000000600000000000000000b001116120338000c090b010a090f03150b050a091002140a091003140b091006141200380502040000010215a00311180c13111d0c2b11132a020c260b261007140c2c0b2c0a13250310055c11132a020c270a270f000c180b270f090c0f0a182e38060c010d010c1c0a1c2e3807032405550a180b1c380838090c22010c140a141003140a140f0a150a14100a140a2b180a140f04150a141006140a1410041411220a0f0a141002140a141003140a141004140a141005140b141006141201380a0d220c1c051f0b1c010b18010b0f01059f030b130c0a11132a020c2a0a2a0f000c1b0b2a0f090c120a1b2e38060c040d040c1f0a1f2e3807037205c3010a1b0b1f380838090c23010c170a171002140c0d0a171003140c0b0b0d0b0b11230a0a11230c090a0906000000000000000024038c0105b4010a090a170f0a150a090a2b180a170f04150b0a0b09170c0a0a171006140a1710041411220a120a171002140a171003140a171004140a171005140b171006141201380a05b6010b17010a0a0600000000000000002503bb0105c0010b1b010b120105c3010d230c1f056d0a0a0600000000000000002403c80105b30211132a020c280a280f000c190b280f090c100a192e38060c000d000c1d0a1d2e380703dc0105b3020a190b1d380838090c24010c150a151003140a15100a141706000000000000000011240a0a11230c200a200600000000000000002403f40105a4020a15100a140a20160a150f0a150a200a2b180c210a151004140a21160a150f04150b0a0b20170c0a0a151006140b2111220a100a151002140a151003140a151004140a151005140b151006141201380a05a6020b15010a0a0600000000000000002503ab0205b0020b19010b100105b3020d240c1d05d7010b0a0600000000000000002503b90206a1860100000000002711132a020c290a290f000c1a0b290f090c110a1a2e38060c020d020c1e0a1e2e380703cd020599030a1a0b1e380838090c25010c160a161003140c0c0a16100a140c0e0a0c0a0e2603e8020b1a010b16010b1101061127000000000000270b0c0b0e1706000000000000000011240a160f05150a161005140600000000000000002403f70205940311250c030e030a161006140a16100514110d0a110a161002140a161003140a161004140a161005140b161006141201380a0596030b16010d250c1e05c8020b1e010b1a010b1101020500000102211a11260c0211132a021007140c0311270c010b01030c05110b030b02230c000513090c000b0003160518110c05191104020601000102010f0b00110111021112070c210309070827070911281105070a1128020701000102010511132b02100714020801000102222511132a020f000c090b090c080a000c070b000c060b080b070600000000000000000600000000000000000600000000000000000600000000000000000600000000000000000b06120338000c0a0a0a1002140a0a1003140a0a100a140a0a1004140b0a100514020901000102232611132a020f000c03400500000000000000000c060a032e38060c000d000c040a042e3807031105200a030b04380838090c05010c020d060b0210061444050d050c04050c0b04010b03010b06020a01000024220b00110111250c0a0e0a0c02380b0c0111250c040e04380c0c0511250c060e06380d0c0711250c080e08380e0c090b020b010600000000000000000b070b090b0512022d02070b1128020b010000010b0b0011011112070d210308070827070c1128020c00000102274a11132a020c0a0a0a0f000c070b0a0f090c050a072e38060c000d000c0811250c010e010c0b0a082e3807031805410a070b0838080c030c020b022e0b03380f0c09010c060a0b0a061006140a06100314110d0a050a061002140a061003140a061004140a061005140b061006141201380a0d090c0805130b0b010b08010b07010b0501020d00000001050b000b010b023803020e010000010b0b0011011112070a210308070627070b1128020f010000010b0b0011011112070b210308070727070d1128021001000020090b00110111250c030e030b010b023803021101000020090b00110111250c030e030b010b02381002020002040300030103030304030502010202020303020000"; - let res = run_binary_test("sample_aptosd_swap", code); - assert!(res.is_ok(), "{:?}", res) -} - -#[test] -fn sample_router() { - let code = "a11ceb0b050000000a01000e020e0603148f0104a3012805cb018f0207da03f90208d30640069307a00110b3082b0cde08db110000010101020003000400050006010a0401000100070000000008010202000000090102020000020b050600050c060700050d050200030e0207020000040f02070200000410020a0200000111020c01000612000d000113020f01000414020a0200000115100f0100031611120200000117130201000418020d0200000519140d00041a1500020000041b020a020000041c020d020000051d140d00031e111202000006080609070907080808090b0b0e0c080d0b0e080f0b100812080f0e0809090e130914091209160802040403060c030300030404043501010101010103030404040404040404040b000109000b000109000b000109000b000109000b000109000b000109000b000109010b000109010b0001090103030303030303030404030301010404010404040503030303030301060c0105010102090009010209010900010301090001020104010901010b0001090002060c0308060c070b00010900070b00010901030301030302030302050b000109000305040106060c010303030432010103030404040404040404040b000109000b000109000b000109000b000109000b000109000b000109000b000109010b000109010b000109010303030303030404030301010404010404040505030303030303030306726f7574657204636f696e067369676e657203616d6d0b636c6f625f6d61726b657403666565047574696c0873696d706c69667918737761705f636f696e5f666f725f65786163745f636f696e18737761705f65786163745f636f696e5f666f725f636f696e04436f696e0a616464726573735f6f660a6665655f65786973747316696e697469616c697a655f6665655f64656661756c740b706f6f6c5f6578697374730d6d61726b65745f657869737473086c6f745f73697a6508646563696d616c7303657870047a65726f0c6e5f6269645f6c6576656c730877697468647261771d636f696e5f737761705f636f696e5f666f725f65786163745f636f696e076465706f7369740b626573745f6269645f61750c73756274726163745f66656516706c6163655f6f726465725f666f725f726f757465720c6e5f61736b5f6c6576656c730b626573745f61736b5f6175076164645f6665651d636f696e5f737761705f65786163745f636f696e5f666f725f636f696e49661cd59c0b89440313af587bc99c3d38614d9a52479eb3f7c7c766d580c30b00000000000000000000000000000000000000000000000000000000000000010308c9000000000000000308ca000000000000000308c800000000000000030804000000000000000308070000000000000003086500000000000000030866000000000000000308030000000000000003080200000000000000030864000000000000000308ffffffffffffffff0308050000000000000003080100000000000000030868000000000000000308670000000000000003080600000000000000126170746f733a3a6d657461646174615f7630170104000000000000000c45544553545f4641494c4544000001000003190a000c030a010c040a01320000000000000000000000000000000022030905120b000a01190c020b010c000b020c0105040b030a001a0b040b001a020101040004ec030a0011030c310a311104200308050a0a0011053800030d0510080c03051238010c030b030c2d38020c2a38030c290a2d0b291f031d05fb0138040c27320a000000000000000000000000000000380535110a0c0e0600000000000000000c320600000000000000000c3438060c1a0a340a0223032f05340a320a01230c060536090c060b06033905eb01380706000000000000000021033e055f0a000a010a321738080c140b000d140d1a0a010a32170a020a34170906000000000000000006000000000000000038090c210c1d0a310b14380a0b320b21160c320b340b1d160c3405eb01380b0c130a310a130811110c120a020a3417350a0e180a121a340c090b090a272303750596010a000a010a321738080c180b000d180d1a0a010a32170a020a34170906000000000000000006000000000000000038090c230c1f0a310b18380a0b320b23160c320b340b1f160c3405eb010a0e0a1211000c250c2b0a000a010a321738080c190a000d190d1a0a010a32170a020a3417080b2b340b253438090c240c200a310b19380a0b320b24160c320b340b20160c340a340a022303c20105c7010a320a01230c0805c901090c080b0803cc0105ea010a020a3417350a0e180b121a340c0a0a000907060b13340b0a3200000000000000000000000000000000380c0c2e0c0d0b320b0d34160c320b340b2e34160c34052a0b320b012503f1010707270b340b022103f7010708270b310b1a380d05eb030a2d0a2a1f03800205b203380e0c28320a000000000000000000000000000000380f35110a0c0f0600000000000000000c330600000000000000000c3538060c1b0a350a02230392020597020a330a01230c04059902090c040b04039c0205a20338100600000000000000002103a10205a402080c0505aa020a020a35170a28230c050b0503ad0205ce020a000a010a331738080c150b000d150d1b0a010a33170a020a35170906000000000000000006000000000000000038090c220c1e0a310b15380a0b330b22160c330b350b1e160c3505a20338110c110a310a110811150c100b100a0f11000c260c2c0a000a010a331738080c160a000d160d1b0a010a33170a020a3517080b2c340b263438090c360c370a310b16380a0b330b36160c330b350b37160c350a350a02230381030586030a330a01230c07058803090c070b07038b0305a1030a000807060b11340a020a3517320000000000000000000000000000000038120c2f0c0b0b330b2f34160c330b350b0b34160c35058d020b330b012503a8030707270b350b022103ae030708270b310b1b380d05eb030b2d03b50305cd030a000a0138080c1738060c1c0b000d170d1c0b010b0209060000000000000000060000000000000000380901010a310b17380a0b310b1c380d05eb030b2a03d00305e7030b00080705070a0a02320000000000000000000000000000000038120c300c0c0b0c340b022103e0030707270b30340b012503eb030708270b0001070c27020201040016d1030a0011030c2b0a2b1104200308050a0a0011053800030d0510080c03051238010c030b030c2738020c2438030c230a270a231f031d05b70138040c21320a000000000000000000000000000000380535110a0c0a0600000000000000000c2d0600000000000000000c2f38060c160a2d0a0123032f05a70138070600000000000000002103340537080c04053d0a010a2d170a21230c040b040340055f0a000a010a2d1738080c100b000d100d160a010a2d170600000000000000000906000000000000000006000000000000000038130c1c0c190a2b0b10380a0b2d0b1c160c2d0b2f0b19160c2f05a701380b0c0f0a2b0a0f0811110c0e0b0e0a0a11000c1f0c250a000a010a2d1738080c140a000d140d160a010a2d17060000000000000000080b25340b1f3438130c310c330a2b0b14380a0b2d0b31160c2d0b2f0b33160c2f0a2d0a012303900105a6010a000907060b0f340a010a2d173200000000000000000000000000000000380c0c280c080b2d0b0834160c2d0b2f0b2834160c2f052a0b2d0b012103ad010707270b2f0b022603b3010708270b2b0b16380d05d0030a270b241f03bc01059403380e0c22320a000000000000000000000000000000380f35110a0c0b0600000000000000000c2e0600000000000000000c3038060c180a2e0a012303ce0105840338100600000000000000002103d30105f2010a000a010a2e1738080c150b000d150d180a010a2e170600000000000000000906000000000000000006000000000000000038130c1d0c1a0a2b0b15380a0b2e0b1d160c2e0b300b1a160c3005840338110c0d0a2b0a0d0811150c0c0a010a2e17350a0b180a0c1a340c050b050a222303880205a7020a000a010a2e1738080c110b000d110d180a010a2e170600000000000000000906000000000000000006000000000000000038130c1e0c1b0a2b0b11380a0b2e0b1e160c2e0b300b1b160c300584030a0b0a0c11000c200c260a000a010a2e1738080c120a000d120d180a010a2e17060000000000000000080b26340b203438130c320c340a2b0b12380a0b2e0b32160c2e0b300b34160c300a2e0a012303d1020583030a010a2e17350a0b180b0c1a340c060a000807060b0d340a06320000000000000000000000000000000038120c2a0c070a07340b062503ee020b0001061111000000000000270a2a340a010a2e172503f9020b0001062222000000000000270b2e0b2a34160c2e0b300b0734160c3005c9010b2e0b0121038a030707270b300b02260390030708270b2b0b18380d05d0030b2703970305b2030a000a0138080c1338060c170a000d130d170b010b0209060000000000000000060000000000000000381301010b0011030c2c0a2c0b17380d0b2c0b13380a05d0030b2303b50305cc030b000907050600000000000000000a013200000000000000000000000000000000380c0c290c090b09340b012103c5030707270b29340b022603d0030708270b0001070c270200"; - let res = run_binary_test("sample_router", code); - assert!(res.is_ok(), "{:?}", res) -} - -#[test] -fn sample_pool() { - let code = "a11ceb0b050000000c010020022079039901c90204e2036605c804fd0507c50aa80c08ed166006cd17c101108e19bb020ac91bd4020c9d1eb3250dd043340000010101020103010401050106010701080109010a020b000c000d000e000f0010070000110600001206000013060000140600001508000000040000160800001708000018060000190600001a0600001b0600071d07000b2707000b3a0700053c040106010344040100010245080009470402030100010b480400084e0402030100010b6c07000e7807000e7b07000e7e07000e80010700001c000100001e020100001f030100002002010000210201000022020100002300010000240201000025040100002605010000280607000029080100002a090100002b0a0100002c0b01000658050d0008590f07020300045a101000085b1213020300045c101000035d15160100035e17010100035f1810010005601a0101060b611e1c000b621f06000b632010000b64212200096524010203000a66250101000867122a0203000a682c2d01000a672e2f01000967312a0203000b69320100096a3301020300036b340101000d6d393a000c6d393a0009593b070203000b6e1c3c000b6f3d10000b703d10000b713d0d0003723e16010007733f1d000d74393a000c74393a000975013302030408654401020300087501460203040176054701060b7706100008790f490203000e7a4b4a000e7c4c4d000f7d4e0101040e7f3951000e81010e5300100e1011121114141514161417191c231d1c17261728120e1e111f2b202b12302123232324141735173617371f1c201c27232c1417403023103031303111310e17453211320e32303345333733263319333533363328334035303511384d384a3851350e385303060c04030006060c040a050a080d0a080d0a0306060c04020303030b060c020a050a080d0a080d0a03030303030201060c01080e010103060c05080d02060c0407060c03030303030302060c05040b11010812070805070806070808010502050a0402060b150209000901090001030204080602070b15020900090109000107090101081202060c03010b1101090002070b110109000b1101090001060b1101090001080202070b100109000900070708050303070806070808080f0a080f01080f01080d0405080d080d030305080d080d0205080f03060c080f0301081402080f081403070b1302090009010900090102070a09000a0900010803030708050708060708080108041a06040604030b1101081205080d070a0405020307080503030303030307080803080f0a080f0b1302080f0814040302070a04010901010402060a090006090002010302070a0900030109000208000a0402070b130209000901090002060c0814010b13020900090102050b1101090001080c01080b0108092c03030303030816050405080d040302030a080f0303030503080d03070b1001080a020b11010812030307080503030303030303070806070b150204080603060816030503080f0a080f0503030303030602030303030302060b13020900090109000108160106081602070b1101090003010a0201080a2b03030303030816050405080d040302030a080f0303030503080d03070b1001080a020b110108120307080503030303030303070806070b150204080603060816030503080f0a080f08070805030303070806070808080f0a080f0d01050b1101081206080d060507080507040303070808080f0a080f0b1302080f081403070b15020900090109000901010801010b150209000901010b10010900080800030403060a040608060708080a0817010609010108170d05030305080d020303020a080f0304030405080d0a040a081701081802060c09000206080607080817030303020303030303020303030303020303030303030301081902060a0407080801081a04506f6f6c076163636f756e740a6170746f735f636f696e04636f696e056572726f72056576656e74067369676e657206737472696e67057461626c65117461626c655f776974685f6c656e67746806766563746f7205746f6b656e104578706f6e656e7469616c43757276650b4c696e6561724375727665054d6f64656c04566965770c436f6c6c656374696f6e49640f437265617465506f6f6c4576656e74144465706f736974436f696e506f6f6c4576656e74154465706f736974546f6b656e506f6f6c4576656e740d45646974506f6f6c4576656e740a4576656e7453746f726508506f6f6c4775696405506f6f6c730f52656d6f7665506f6f6c4576656e7409537761704576656e74155769746864726177436f696e506f6f6c4576656e74165769746864726177546f6b656e506f6f6c4576656e740b4465706f736974436f696e06537472696e670c4465706f736974546f6b656e0845646974506f6f6c0a52656d6f7665506f6f6c1753776170436f696e466f7253706563696669634e4654730f537761704e465473466f72436f696e0c5769746864726177436f696e0d5769746864726177546f6b656e066372656174650b696e69745f6d6f64756c650b546f6b656e4461746149640a69735f6572633131353515766965775f636f6c6c656374696f6e5f706f6f6c7309766965775f706f6f6c0f766965775f70726963655f63616c630f766965775f757365725f706f6f6c7312636f6c6c656374696f6e5f63726561746f720f636f6c6c656374696f6e5f6e616d650763726561746f7207706f6f6c5f69640a73706f745f70726963650563757276650564656c7461116c705f6665655f6d756c7469706c69657204747970650673656e646572136465706f7369745f636f696e5f616d6f756e7405636f696e7309746f6b656e5f69647307546f6b656e49640b6372656174655f706f6f6c0b4576656e7448616e646c650b72656d6f76655f706f6f6c126465706f7369745f746f6b656e5f706f6f6c116465706f7369745f636f696e5f706f6f6c1377697468647261775f746f6b656e5f706f6f6c1277697468647261775f636f696e5f706f6f6c09656469745f706f6f6c047377617004436f696e094170746f73436f696e06746f6b656e730f5461626c65576974684c656e67746805546f6b656e0c7472616e73616374696f6e7317746f74616c5f7472616e73616374696f6e5f76616c75650f6c705f6665655f6561726e696e677305636f756e7405706f6f6c73055461626c650a757365725f706f6f6c7310636f6c6c656374696f6e5f706f6f6c730b636f696e5f616d6f756e740c70726f746f636f6c5f6665650e70726f746f636f6c5f70617965650b726f79616c74795f6665650d726f79616c74795f7061796565066c705f6665651477697468647261775f636f696e5f616d6f756e740a616464726573735f6f6608636f6e7461696e7310696e76616c69645f617267756d656e740a626f72726f775f6d7574117065726d697373696f6e5f64656e696564087769746864726177056d657267650576616c75650a656d69745f6576656e74136372656174655f746f6b656e5f69645f726177146372656174655f746f6b656e5f646174615f69640a62616c616e63655f6f660e77697468647261775f746f6b656e0361646406617070656e640672656d6f766508696e6465785f6f660d6465706f7369745f746f6b656e0d64657374726f795f656d707479076465706f73697407526f79616c74790a676574427579496e666f0b6765745f726f79616c7479176765745f726f79616c74795f64656e6f6d696e61746f72156765745f726f79616c74795f6e756d657261746f72116765745f726f79616c74795f7061796565076578747261637404757466380b67657453656c6c496e666f036e6577106e65775f6576656e745f68616e646c65156765745f746f6b656e646174615f6d6178696d756d08506f6f6c5669657706626f72726f7709706f6f6c5f7669657713436f6c6c656374696f6e506f6f6c735669657715636f6c6c656374696f6e5f706f6f6c735f7669657704766965770d507269636543616c63566965770f70726963655f63616c635f766965770d55736572506f6f6c73566965770f757365725f706f6f6c735f76696577ecb44cec6276ddc5860a13b976262c786e06af8f7306923cabec17808dabf0940000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303086600000000000000030869000000000000000308680000000000000003086e000000000000000308670000000000000003086a0000000000000003086b0000000000000003086c000000000000000308650000000000000003086d000000000000000520ecb44cec6276ddc5860a13b976262c786e06af8f7306923cabec17808dabf09403086400000000000000052000000000000000000000000000000000000000000000000000000000000000000a0204036275790a02050473656c6c126170746f733a3a6d657461646174615f7630a6020a6500000000000000074552525f4e554d006600000000000000134552525f444946465f434f4c4c454354494f4e006700000000000000124552525f4e4f545f45584953545f504f4f4c006800000000000000154552525f494e56414c49445f504f4f4c5f54595045006900000000000000154552525f494e56414c49445f504f4f4c5f41524753006a000000000000001c4552525f4e4f545f4558495453545f544f4b454e5f494e5f504f4f4c006b00000000000000124552525f4e4f545f484156455f544f4b454e006c00000000000000144552525f4e4f545f504f4f4c5f43524541544f52006d00000000000000184552525f504f4f4c5f4e4f545f454e4f5547485f434f494e006e00000000000000114552525f49535f313135355f544f4b454e000002022d052e080d0102092f0530042d052e080d3103320233033403350202020a360530042d052e080d37033803310332023303340303020a360530042d052e080d390a080f3803310332023303340304020730042d052e080d31033202330334030502083b0b100108013d0b100108093e0b100108033f0b10010802400b1001080c410b1001080b420b10010804430b1001080a06020e2f053103380b11010812460b1302080f08142d052e080d3202330334033502390a080f49034a044b030702014c040802034d0b15020408064f0b1502050a04500b150208000a0409020c2f0530042d052e080d3103320233033403350249034a044b030a0210360530042d052e080d310332023303390a080f510352035305540355055603380335080d0b020a360530042d052e080d5703380331033202330334030c020a360530042d052e080d390a080f380331033202330334030001000205080c61070a2a080c06070a2a050c040a0610000a00110f3800040d05160b00010b06010b040107041111270a0610010a013801041c05250b00010b06010b040107041111270b060f010a0138020c050a051002140a00110f210432053b0b00010b05010b040107071113270a000a0238030c030a050f030b0338040b040f040b00110f0b010a051005140a051006140b020a05100338050a051007140a051008140a051009140b05100a1412023806020101000205081bd801070a2a080c0a070a2a050c060a0a10000a00110f3800040d05160b00010b0a010b060107041111270a0a10010a013801041c05250b00010b0a010b060107041111270b0a0f010a0138020c09401c00000000000000000c0c0a091002140a00110f210434053d0b00010b09010b060107071113270e02410d0c080600000000000000000c070a070a082304b60105470e020a07420d0a09100521044f05580b00010b09010b060107001111270e030a07421d0a09100621046005690b00010b09010b060107001111270e020a07420d140e030a07421d140e040a07421d140e050a0742101411180c0b0e020a07420d140e030a07421d140e040a07421d141119110a20048c010595010b00010b09010b060107031111270d0c0a0b441c0a00110f0a0b111a0601000000000000002604a00105a9010b00010b09010b060107061111270a090f0b0a0b0a000b0b060100000000000000111b38070b07060100000000000000160c0705420a090f0c0a0c38080b060f0d0b00110f0b010a091005140a091006140b0c0a09100338050a091007140a091008140a091009140b09100a1412033809020201000205082759070a2a080c08070a2a050c060a0810000a00110f3800040d05160b00010b08010b060107041111270a0810010a013801041c05250b00010b08010b060107041111270b080f010a0138020c070a071002140b00110f21043205390b07010b060107071113270a020a070f08150a040a070f09150a030a070f07150a050a070f0a150b060f0e0b010a071005140b071006140b030b020b040b051204380a0203010002050829dc01070a2a080c17070a2a050c100a1710000a00110f3800040d05160b00010b17010b100107041111270a170f000a00110f380b0c1f0a1710010a0138010422052d0b1f010b00010b17010b100107041111270a170f010a01380c13060c150c1c0c1d010c1e0c160c0f0c0e0c0b0c0a0c1b0c090c180c0d0a0d0a00110f21044605510b1f010b00010b17010b100107071113270a1f0e010c062e0b06380d0c12010b1f0b12380e010b170f0f0a0a0a0b1200380f0c0c0a0c0e010c072e0b07380d0c13046d05760b00010b10010b0c0107051111270b0c0b13380e010600000000000000000c110e02410d0c14401c00000000000000000c1a0a110a142304a5010586010e020a11420d140e030a11421d140e040a11421d140e050a1142101411180c190d1a0a19441c0a000d1b0b19381011220b11060100000000000000160c110581010b1b38110e0938050c080a00110f0b0938120a100f100a0d0a010a0a0a0b0b1a0600000000000000000600000000000000003100060000000000000000060000000000000000120c38130a100f110b0d0a010a0a0a0b0b080600000000000000000600000000000000003100060000000000000000060000000000000000120b38140b100f120b00110f0b010b0a0b0b0b180b0e0b0f0b160b1e0b1d0b1c0b15120938150204010002050838d502070a2a080f010c2a070a2a050c210a2a0a010c102e0b103801040f05180b00010b2a010b210107041111270e02410d0c270b2a0a0138020c290a2910081431012104380a291007140a291009140a270a29100a14070b11250c0a0c090c080c070c060c1d055a0a29100814310221043f05480b00010b29010b210107021111270a291007140a291009140a270a29100a14070b11260c0a0c090c080c070c060c1d0b1d0b060b070b080b090b0a0c240c2b0c1f0c250c26310021046905720b00010b29010b21010701111127070c0600000000000000000600000000000000000c2f0c2d0c2e0b260a290f07150b250a290f0915401c00000000000000000c310a000a1f38030c1e0600000000000000000c220a220a272304f401058d010e020a22420d140e030a22421d140e040a22421d140e050a2242101411180c300a29100c0e3038160c2304a60105af010b00010b29010b210107051111270a290f0c0b233817010d310a30441c0a29100b0a30381804bd0105c6010b00010b29010b210107051111270a000a290f0b0a30381011220b3011280c0b0e0b0c2c0a2c11290c200a2c112a0c280b2c112b0c2e0a200600000000000000002204ef010a1f0a271a0b28180b201a0c2d0b2f0a2d160c2f0a2e0d1e0a2d381938120b22060100000000000000160c220588010a291013140a1f35160a290f13150a29101414060100000000000000160a290f1415070a0d1e0a2b381938120a290f030b1e38040b210f150c1c0b00110f0c0c0b010c0d0a291005140c0e0a291006140c0f0a291007140c110a291008140c120a291009140c130b310c140b1f0a2b160b2d160c150b2b0c160b2f0c170b2e0c180b240c19070d112d0c1a0b29100338050c1b0b1c0b0c0b0d0b0e0b0f0b110b120b130b140b150b16070a0b170b180b190b1b0b1a120a381a02050100020508418c03070a2a080f010c29070a2a050c200a290a010c102e0b103801040f05180b00010b29010b200107041111270e02410d0c250b290a0138020c280a2810081431012104380a281007140a281009140a250a28100a14070b112e0c0a0c090c080c070c060c1d055a0a28100814310221043f05480b00010b28010b200107021111270a281007140a281009140a250a28100a14070b112f0c0a0c090c080c070c060c1d0b1d0b060b070b080b090b0a0c220c2a0c270c230c24310021046905720b00010b28010b20010701111127070c0600000000000000000600000000000000000c2e0c2c0c2d401c00000000000000000c300a280f030a270a2a1738190c1e0600000000000000000c210a210a2523049a020588010e020a21420d0a281005210490010599010b00010b28010b200107001111270e030a21421d0a2810062104a10105aa010b00010b28010b200107001111270e020a21420d140e030a21421d140e040a21421d140e050a2142101411180c2f0e020a21420d140e030a21421d140e040a21421d141119110a2004cd0105d6010b00010b28010b200107031111270d300a2f441c0a00110f0a2f111a0601000000000000002604e10105ea010b00010b28010b200107061111270a280f0b0a2f0a000a2f060100000000000000111b38070b2f11280c0b0e0b0c2b0a2b11290c1f0a2b112a0c260b2b112b0c2d0a1f060000000000000000220495020a270a251a0b26180b1f1a0c2c0b2e0a2c160c2e0a2d0d1e0a2c381938120b21060100000000000000160c210583010a280f0c0a303808070a0a280f030a2a381938120b240a280f07150b230a280f09150a00110f0b1e38120a281013140a270a2a170b2e1735160a280f13150a28101414060100000000000000160a280f14150b200f150c1c0b00110f0c0c0b010c0d0a281005140c0e0a281006140c0f0a281007140c110a281008140c120a281009140c130b300c140b270a2a170a2c170c150b2a0c160b2c0c170b2d0c180b220c19070e112d0c1a0b28100338050c1b0b1c0b0c0b0d0b0e0b0f0b110b120b130b140b150b16070a0b170b180b190b1b0b1a120a381a020601000205082770070a2a080c05070a2a050c030a0510000a00110f3800040d05160b00010b05010b030107041111270a0510010a013801041c05250b00010b05010b030107041111270b050f010a0138020c040a041002140a00110f210432053b0b00010b04010b030107071113270a04100338050a02260442054b0b00010b04010b030107091111270a00110f0a040f030a02381938120b030f110b00110f0b010a041005140a041006140b020a04100338050a041007140a041008140a041009140b04100a14120b38140207010002050842a901070a2a080c0b070a2a050c060a0b10000a00110f3800040d05160b00010b0b010b060107041111270a0b10010a013801041c05250b00010b0b010b060107041111270b0b0f010a0138020c0a401c00000000000000000c0d0a0a1002140a00110f210434053d0b00010b0a010b060107071113270e02410d0c090600000000000000000c070a070a0923048b0105470e020a07420d140e030a07421d140e040a07421d140e050a0742101411180c0c0a0a100c0e0c38160c08046005690b00010b0a010b060107051111270a0a0f0c0b083817010d0d0a0c441c0a0a100b0a0c381804770580010b00010b0a010b060107051111270a000a0a0f0b0b0c381011220b07060100000000000000160c0705420b060f100b00110f0b010a0a1005140a0a1006140b0d0a0a100338050a0a1007140a0a1008140a0a1009140b0a100a14120c38130208010003050708439f02070a2a080c14070a2a070f160c11070a2a050c10381b0c170e02410d0c130a13060000000000000000240414051f0b00010b14010b11010b100107081111270e02060000000000000000420d0c0f0e03060000000000000000421d0c0e0a14100f0a0f140a0e141200381c20043a0a140f0f0a0f140a0e141200402b0000000000000000381d0a140f0f0a0f140a0e141200380f0a1114442b401c00000000000000000c160600000000000000000c120a120a132304b001054e0a0f0e020a12420d21045b0a0e0e030a12421d210c0b055d090c0b0b0b0460056f0b00010b14010b11010b10010b0f010b0e0107001111270e020a12420d140e030a12421d140e040a12421d141119110a20048001058f010b00010b14010b11010b10010b0f010b0e0107031111270e020a12420d140e030a12421d140e040a12421d140e050a1242101411180c150d160a15441c0d170a150a000b15060100000000000000111b38070b12060100000000000000160c1205490a100f0d0a00110f0a11140a0f140a0e140a160a060a070a010a080a09120338090a000a0638030c0d0a100f040a00110f0a11140a0f140a0e140a060b060a070a010a080a09120238060a140f010a11140a00110f0a070b0d0b170a0f140a0e140a010a080a090a0a0b1606000000000000000032000000000000000000000000000000000600000000000000001206381e0a140f000a00110f0c0c2e0b0c38002004ff010a140f000a00110f402b0000000000000000381f0b140f000a00110f380b0a1114442b0b100f170b00110f0a11140b0f140b0e140b070b010b080b090b0a120138200a11143201000000000000000000000000000000160b11150209000000011e0a0038213822382312082d080a00320000000000000000000000000000000012072d070a000a0038240a0038250a0038260a0038270a0038280a0038290a00382a0b00382b12052d05020a00000001060601000000000000000b0011342120020b010401084876070a2a080c090a010a0212000c030a09100f0a03381c040d05130b00010b0901063f05000000000000270a09100f0b03382c0c07404a00000000000000000c0a0a07412b0c060600000000000000000c040a040a0623046b05240a070a04422b140c050a0910010a053801042f05370b00010b09010b0701063f05000000000000270a0910010b05382d0c080d0a0a081002140a081007140a08100338050a081005140a081006140a081008140a081009140a08100a140a081018140a08100c140a081014140a081013140b081019141136444a0b04060100000000000000160c04051f0b09010b000b010b020b07140b0a1137382e020c010401084f40070a2a080c030a0310010a013801040905100b00010b030107041111270b0310010b01382d0c020b000a021002140a021007140a02100338050a021005140a021006140a021008140a021009140a02100a140a021018140a02100c140a021014140a021013140b021019141136382f020d0104005087010b010600000000000000002104380a020601000000000000002104150b030b040b050b06070b11250c090c080c070c180c170c16052b0b0206020000000000000021041a051f0b000107021111270b030b040b050b06070b11260c090c080c070c180c170c160b160b170b180b070b080b090c150c140c130c120c110c10056b0a020601000000000000002104490b030b040b050b06070b112e0c0f0c0e0c0d0c0c0c0b0c0a055f0b0206020000000000000021044e05530b000107021111270b030b040b050b06070b112f0c0f0c0e0c0d0c0c0c0b0c0a0b0a0b0b0b0c0b0d0b0e0b0f0c150c140c130c120c110c100b100b110b120b130b140b150c1a0c1d0c190c1b0c1c310021047a057e0b0001064705000000000000270b000b1c0b1b0b190b1d0b1a11393830020e01040108521b070a2a080c030a0310000a0138000409050f0b00010b0301063f05000000000000270b0310000a0138310c020b000b010b0214113a383202080108000600060205030604060506010606060706080603060a050205060802050405050501060c060b0507070005000609060d00"; - let res = run_binary_test("sample_pool", code); - assert!(res.is_ok(), "{:?}", res) -} - -#[test] -fn sample_farming() { - let code = "a11ceb0b050000000e01001e021e2603447c04c00158059802c80107e003bb04089b08a00106bb09e101109c0b780a940c3e0bd20c040cd60cd10d0da71a080eaf1a060000010101020103010401050106000700080209020a0309030a0409040a000b0800000c0e0200010001000d0c0200010001011106000513070002230401000107240000000e000100000f0201020000032104050001220607000525090a000e26010c0200000c26010c0200000a26010c0200000427001200022812140100022915160100022a17010100082b150101000d2c1a010200000b2c1a01020000092c1a010200000d2d1b010200000b2d1b01020000092d1b01020000062e011400050b050d050e050f05100511060b060d060e060f06100611070b070d070e070f0710071109130a130b1309180a180b1809190a190b190c130c180d0b0e0b0f0b0d0d0e0d0f0d0d0e0d100e0e0e100f0e0f10100b110b120b01060c0009060c0303030303030303020c080302060c0501080301060803010c2001010101010101010101030303030308040b050108060b050109000b050109010708000b0102090009010b0102090009010b020209000901070b020209000901050c0a0b0102090009010503030303010a0201080402090009010101020901090002080609000209000806020806090102090108060105010900010302060c03010b0501090002050b0501090001090101080603060c030305060c03030303010b010209000901076661726d696e67076163636f756e7404636f696e107265736f757263655f6163636f756e74067369676e657206737472696e670974696d657374616d700d6661756365745f746f6b656e73076c656e64696e6706726f7574657204737761700a4d6f64756c65446174610c506f736974696f6e496e666f0f506f736974696f6e496e666f4465780b696e69745f6d6f64756c65166c657665726167655f7969656c645f6661726d696e670a7369676e65725f636170105369676e65724361706162696c697479086465785f6e616d6506537472696e670b7369676e65725f616464720a637265617465645f617406737461747573086c657665726167650e737570706c79416d6f756e745f780e737570706c79416d6f756e745f790e737570706c79416d6f756e745f7a0e626f72726f77416d6f756e745f780e626f72726f77416d6f756e745f790e626f72726f77416d6f756e745f7a10706f736974696f6e496e666f5f70616e10706f736974696f6e496e666f5f6c697110706f736974696f6e496e666f5f6175781d72657472696576655f7265736f757263655f6163636f756e745f6361701d6372656174655f7369676e65725f776974685f6361706162696c69747904436f696e03455a4d04757466380f69735f706169725f637265617465640a616464726573735f6f660762616c616e6365087769746864726177076465706f73697406626f72726f7710737761705f65786163745f696e7075740d6164645f6c69717569646974790b6e6f775f7365636f6e64734d63574ba8d90a5926e2866d8291e57683108a47b96d884232a871fe4feddf4100000000000000000000000000000000000000000000000000000000000000015e40a5bf7ab741784d3a99d96d8e2ddc6706ee06e5f509a3314a74c9e53746f5b30dd6a14dd7626ac8a37bc964914f07e3dc38d629637f1087f9f7186f1e0909c4911c40cf758ec21c0ebf0e547933ef6bb0f53ad581c08d2ecc7ad11364be1b030804000000000000000520f67b2452fd82768002ec6c28568713b9359a596585dc1a4bf85fce6b0e3754020308020000000000000003080300000000000000030801000000000000000308ffffffffffffffff0410e80300000000000000000000000000000308000000000000000005204d63574ba8d90a5926e2866d8291e57683108a47b96d884232a871fe4feddf41052000000000000000000000000000000000000000000000000000000000000000000a020c0b50616e63616b65537761700a020b0a4c6971756964537761700a020d0c4155582045786368616e6765126170746f733a3a6d657461646174615f763064030100000000000000164552524f525f4e4f545f435245415445445f50414952000200000000000000184552524f525f494e53554646494349454e545f4153534554000300000000000000174552524f525f494e56414c49445f504152414d5f4445580000020110080301020b1208041405150316011703180319031a031b031c031d030202031e0a0b0102090009011f0a0b010209000901200a0b010209000901020b010b00000000030c0b00070111020c020e0211030c010e010b0212002d000201010402000208ee04070a1104010a010600000000000000002103080536070a11040c183800030e0511080c09051338010c090b0903190b00010704273802031c051f080c0b052138030c0b0b0b03270b00010704273804032a052d080c0c052f38050c0c0b0c03350b0001070427059f010a0106010000000000000021033b0569070b11040c18380603410544080c0d054638070c0d0b0d034c0b00010704273808034f0552080c0e055438090c0e0b0e035a0b0001070427380a035d0560080c0f0562380b0c0f0b0f03680b0001070427059f010a0106020000000000000021036e059b01070c11040c18380c03740577080c100579380d0c100b10037f0b0001070427380e038201058501080c11058701380f0c110b11038d010b00010704273810039001059301080c1205950138110c120b12039f010b00010704270b000107032707082a000c1c0b1c100011030c220e2211080c210a030600000000000000002403ae0105c1010a00110838120c160b160a032403ba010b00010702270a000a0338130c1a07080b1a38140a040600000000000000002403c60105d9010a00110838150c170b170a042403d2010b00010702270a000a0438160c1b07080b1b38170a050600000000000000002403de0105f1010a00110838180c150b150a052403ea010b00010702270a000a0538190c1907080b19381a0a060600000000000000002403f60105f9010e220a06381b0a070600000000000000002403fe010581020e220a07381c0a0806000000000000000024038502070838120c26070838150c280a030a06160602000000000000001a0600000000000000002403940205bd020a010600000000000000002103990205a2020e220a030a06160602000000000000001a060000000000000000381d05bd020a010601000000000000002103a70205b0020e220a030a06160602000000000000001a060000000000000000381e05bd020a010602000000000000002103b50205bd020e220a030a06160602000000000000001a060000000000000000381f0a040a07160602000000000000001a0600000000000000002403c60205ef020a010600000000000000002103cb0205d4020e220a040a07160602000000000000001a060000000000000000382005ef020a010601000000000000002103d90205e2020e220a040a07160602000000000000001a060000000000000000382105ef020a010602000000000000002103e70205ef020e220a040a07160602000000000000001a06000000000000000038220a050a08160602000000000000001a0600000000000000002403f80205b9030a010600000000000000002103fd02058e030e220a050a08160602000000000000001a06000000000000000038230e220a050a08160602000000000000001a060000000000000000382405b9030a010601000000000000002103930305a4030e220a050a08160602000000000000001a06000000000000000038250e220a050a08160602000000000000001a060000000000000000382605b9030a010602000000000000002103a90305b9030e220a050a08160602000000000000001a06000000000000000038270e220a050a08160602000000000000001a0600000000000000003828070838120c25070838150c270a030b25160b26170c130a040b27160b28170c140a130600000000000000002403d00305d5030a14060000000000000000240c0a05d703090c0a0b0a03da0305eb040a010600000000000000002103df0305e6030e220b130b14060000000000000000060000000000000000382905fd030a010601000000000000002103eb0305f2030e220b130b14060000000000000000060000000000000000382a05fd030a010602000000000000002103f70305fd030e220b130b14060000000000000000060000000000000000382b0b0011080c240a213b002003850405ba040b180b241113080b020b030b040b050b060b070b0839010c1d401c000000000000000001401c0000000000000000401c0000000000000000401c000000000000000039000c1f0a0106000000000000000021039e0405a3040d1f36000b1d441c05b6040a010601000000000000002103a80405ad040d1f36010b1d441c05b6040b010602000000000000002103b20405b6040d1f36020b1d441c0e220b1f3f0005ea040b213c000c200b180b241113080b020b030b040b050b060b070b0839010c1e0a010600000000000000002103cf0405d4040b2036000b1e441c05ea040a010601000000000000002103d90405de040b2036010b1e441c05ea040b010602000000000000002103e30405e8040b2036020b1e441c05ea040b200105ed040b0001020000020002010202010b020b030b00"; - let res = run_binary_test("sample_farming", code); - assert!(res.is_ok(), "{:?}", res) -} - -#[test] -fn sample_whitelist() { - let code = "a11ceb0b050000000c01000602060c03123a044c0805545707ab01660891024006d102988b0210e98d02d7010ac08f02090cc98f02a2470debd6020200000101010200030800020a04020301000100040001000005020100000603040000070201000008000100010b0203000204070102030002060a04020300020c010c02030402080d0e020300060607060806090602060c050001060c01050101020507080002050203070b010209000901090009010305070b010205020708000106080002060b0102090009010900010b01020502010b01020900090102070b01020900090109000109010977686974656c697374067369676e6572057461626c650957686974656c69737403616464086164645f6d616e7908636f6e7461696e730a696e697469616c697a650672656d6f766507656e7472696573055461626c650a616464726573735f6f66036e65774419523fdfa01e96fc7c18b67d900be8c863459e25383a5c661b9523631811c1000000000000000000000000000000000000000000000000000000000000000103082003000000000000030822030000000000000308210300000000000005204419523fdfa01e96fc7c18b67d900be8c863459e25383a5c661b9523631811c1052000000000000000000000000000000000000000000000000000000000000000000520000000000000000000000000000000000000000000000000000000000000000105200000000000000000000000000000000000000000000000000000000000000002052000000000000000000000000000000000000000000000000000000000000000030520000000000000000000000000000000000000000000000000000000000000000405200000000000000000000000000000000000000000000000000000000000000005052000000000000000000000000000000000000000000000000000000000000000060520000000000000000000000000000000000000000000000000000000000000000705200000000000000000000000000000000000000000000000000000000000000008052000000000000000000000000000000000000000000000000000000000000000090520000000000000000000000000000000000000000000000000000000000000001005200000000000000000000000000000000000000000000000000000000000000011052000000000000000000000000000000000000000000000000000000000000000120520000000000000000000000000000000000000000000000000000000000000001305200000000000000000000000000000000000000000000000000000000000000014052000000000000000000000000000000000000000000000000000000000000000150520000000000000000000000000000000000000000000000000000000000000001605200000000000000000000000000000000000000000000000000000000000000017052000000000000000000000000000000000000000000000000000000000000000180520000000000000000000000000000000000000000000000000000000000000001905200000000000000000000000000000000000000000000000000000000000000020052000000000000000000000000000000000000000000000000000000000000000210520000000000000000000000000000000000000000000000000000000000000002205200000000000000000000000000000000000000000000000000000000000000023052000000000000000000000000000000000000000000000000000000000000000240520000000000000000000000000000000000000000000000000000000000000002505200000000000000000000000000000000000000000000000000000000000000026052000000000000000000000000000000000000000000000000000000000000000270520000000000000000000000000000000000000000000000000000000000000002805200000000000000000000000000000000000000000000000000000000000000029052000000000000000000000000000000000000000000000000000000000000000300520000000000000000000000000000000000000000000000000000000000000003105200000000000000000000000000000000000000000000000000000000000000032052000000000000000000000000000000000000000000000000000000000000000330520000000000000000000000000000000000000000000000000000000000000003405200000000000000000000000000000000000000000000000000000000000000035052000000000000000000000000000000000000000000000000000000000000000360520000000000000000000000000000000000000000000000000000000000000003705200000000000000000000000000000000000000000000000000000000000000038052000000000000000000000000000000000000000000000000000000000000000390520000000000000000000000000000000000000000000000000000000000000004005200000000000000000000000000000000000000000000000000000000000000041052000000000000000000000000000000000000000000000000000000000000000420520000000000000000000000000000000000000000000000000000000000000004305200000000000000000000000000000000000000000000000000000000000000044052000000000000000000000000000000000000000000000000000000000000000450520000000000000000000000000000000000000000000000000000000000000004605200000000000000000000000000000000000000000000000000000000000000047052000000000000000000000000000000000000000000000000000000000000000480520000000000000000000000000000000000000000000000000000000000000004905200000000000000000000000000000000000000000000000000000000000000050052000000000000000000000000000000000000000000000000000000000000000510520000000000000000000000000000000000000000000000000000000000000005205200000000000000000000000000000000000000000000000000000000000000053052000000000000000000000000000000000000000000000000000000000000000540520000000000000000000000000000000000000000000000000000000000000005505200000000000000000000000000000000000000000000000000000000000000056052000000000000000000000000000000000000000000000000000000000000000570520000000000000000000000000000000000000000000000000000000000000005805200000000000000000000000000000000000000000000000000000000000000059052000000000000000000000000000000000000000000000000000000000000000600520000000000000000000000000000000000000000000000000000000000000006105200000000000000000000000000000000000000000000000000000000000000062052000000000000000000000000000000000000000000000000000000000000000630520000000000000000000000000000000000000000000000000000000000000006405200000000000000000000000000000000000000000000000000000000000000065052000000000000000000000000000000000000000000000000000000000000000660520000000000000000000000000000000000000000000000000000000000000006705200000000000000000000000000000000000000000000000000000000000000068052000000000000000000000000000000000000000000000000000000000000000690520000000000000000000000000000000000000000000000000000000000000007005200000000000000000000000000000000000000000000000000000000000000071052000000000000000000000000000000000000000000000000000000000000000720520000000000000000000000000000000000000000000000000000000000000007305200000000000000000000000000000000000000000000000000000000000000074052000000000000000000000000000000000000000000000000000000000000000750520000000000000000000000000000000000000000000000000000000000000007605200000000000000000000000000000000000000000000000000000000000000077052000000000000000000000000000000000000000000000000000000000000000780520000000000000000000000000000000000000000000000000000000000000007905200000000000000000000000000000000000000000000000000000000000000080052000000000000000000000000000000000000000000000000000000000000000810520000000000000000000000000000000000000000000000000000000000000008205200000000000000000000000000000000000000000000000000000000000000083052000000000000000000000000000000000000000000000000000000000000000840520000000000000000000000000000000000000000000000000000000000000008505200000000000000000000000000000000000000000000000000000000000000086052000000000000000000000000000000000000000000000000000000000000000870520000000000000000000000000000000000000000000000000000000000000008805200000000000000000000000000000000000000000000000000000000000000089052000000000000000000000000000000000000000000000000000000000000000900520000000000000000000000000000000000000000000000000000000000000009105200000000000000000000000000000000000000000000000000000000000000092052000000000000000000000000000000000000000000000000000000000000000930520000000000000000000000000000000000000000000000000000000000000009405200000000000000000000000000000000000000000000000000000000000000095052000000000000000000000000000000000000000000000000000000000000000960520000000000000000000000000000000000000000000000000000000000000009705200000000000000000000000000000000000000000000000000000000000000098052000000000000000000000000000000000000000000000000000000000000000990520000000000000000000000000000000000000000000000000000000000000010005200000000000000000000000000000000000000000000000000000000000000101052000000000000000000000000000000000000000000000000000000000000001020520000000000000000000000000000000000000000000000000000000000000010305200000000000000000000000000000000000000000000000000000000000000104052000000000000000000000000000000000000000000000000000000000000001050520000000000000000000000000000000000000000000000000000000000000010605200000000000000000000000000000000000000000000000000000000000000107052000000000000000000000000000000000000000000000000000000000000001080520000000000000000000000000000000000000000000000000000000000000010905200000000000000000000000000000000000000000000000000000000000000110052000000000000000000000000000000000000000000000000000000000000001110520000000000000000000000000000000000000000000000000000000000000011205200000000000000000000000000000000000000000000000000000000000000113052000000000000000000000000000000000000000000000000000000000000001140520000000000000000000000000000000000000000000000000000000000000011505200000000000000000000000000000000000000000000000000000000000000116052000000000000000000000000000000000000000000000000000000000000001170520000000000000000000000000000000000000000000000000000000000000011805200000000000000000000000000000000000000000000000000000000000000119052000000000000000000000000000000000000000000000000000000000000001200520000000000000000000000000000000000000000000000000000000000000012105200000000000000000000000000000000000000000000000000000000000000122052000000000000000000000000000000000000000000000000000000000000001230520000000000000000000000000000000000000000000000000000000000000012405200000000000000000000000000000000000000000000000000000000000000125052000000000000000000000000000000000000000000000000000000000000001260520000000000000000000000000000000000000000000000000000000000000012705200000000000000000000000000000000000000000000000000000000000000128052000000000000000000000000000000000000000000000000000000000000001290520000000000000000000000000000000000000000000000000000000000000013005200000000000000000000000000000000000000000000000000000000000000131052000000000000000000000000000000000000000000000000000000000000001320520000000000000000000000000000000000000000000000000000000000000013305200000000000000000000000000000000000000000000000000000000000000134052000000000000000000000000000000000000000000000000000000000000001350520000000000000000000000000000000000000000000000000000000000000013605200000000000000000000000000000000000000000000000000000000000000137052000000000000000000000000000000000000000000000000000000000000001380520000000000000000000000000000000000000000000000000000000000000013905200000000000000000000000000000000000000000000000000000000000000140052000000000000000000000000000000000000000000000000000000000000001410520000000000000000000000000000000000000000000000000000000000000014205200000000000000000000000000000000000000000000000000000000000000143052000000000000000000000000000000000000000000000000000000000000001440520000000000000000000000000000000000000000000000000000000000000014505200000000000000000000000000000000000000000000000000000000000000146052000000000000000000000000000000000000000000000000000000000000001470520000000000000000000000000000000000000000000000000000000000000014805200000000000000000000000000000000000000000000000000000000000000149052000000000000000000000000000000000000000000000000000000000000001500520000000000000000000000000000000000000000000000000000000000000015105200000000000000000000000000000000000000000000000000000000000000152052000000000000000000000000000000000000000000000000000000000000001530520000000000000000000000000000000000000000000000000000000000000015405200000000000000000000000000000000000000000000000000000000000000155052000000000000000000000000000000000000000000000000000000000000001560520000000000000000000000000000000000000000000000000000000000000015705200000000000000000000000000000000000000000000000000000000000000158052000000000000000000000000000000000000000000000000000000000000001590520000000000000000000000000000000000000000000000000000000000000016005200000000000000000000000000000000000000000000000000000000000000161052000000000000000000000000000000000000000000000000000000000000001620520000000000000000000000000000000000000000000000000000000000000016305200000000000000000000000000000000000000000000000000000000000000164052000000000000000000000000000000000000000000000000000000000000001650520000000000000000000000000000000000000000000000000000000000000016605200000000000000000000000000000000000000000000000000000000000000167052000000000000000000000000000000000000000000000000000000000000001680520000000000000000000000000000000000000000000000000000000000000016905200000000000000000000000000000000000000000000000000000000000000170052000000000000000000000000000000000000000000000000000000000000001710520000000000000000000000000000000000000000000000000000000000000017205200000000000000000000000000000000000000000000000000000000000000173052000000000000000000000000000000000000000000000000000000000000001740520000000000000000000000000000000000000000000000000000000000000017505200000000000000000000000000000000000000000000000000000000000000176052000000000000000000000000000000000000000000000000000000000000001770520000000000000000000000000000000000000000000000000000000000000017805200000000000000000000000000000000000000000000000000000000000000179052000000000000000000000000000000000000000000000000000000000000001800520000000000000000000000000000000000000000000000000000000000000018105200000000000000000000000000000000000000000000000000000000000000182052000000000000000000000000000000000000000000000000000000000000001830520000000000000000000000000000000000000000000000000000000000000018405200000000000000000000000000000000000000000000000000000000000000185052000000000000000000000000000000000000000000000000000000000000001860520000000000000000000000000000000000000000000000000000000000000018705200000000000000000000000000000000000000000000000000000000000000188052000000000000000000000000000000000000000000000000000000000000001890520000000000000000000000000000000000000000000000000000000000000019005200000000000000000000000000000000000000000000000000000000000000191052000000000000000000000000000000000000000000000000000000000000001920520000000000000000000000000000000000000000000000000000000000000019305200000000000000000000000000000000000000000000000000000000000000194052000000000000000000000000000000000000000000000000000000000000001950520000000000000000000000000000000000000000000000000000000000000019605200000000000000000000000000000000000000000000000000000000000000197052000000000000000000000000000000000000000000000000000000000000001980520000000000000000000000000000000000000000000000000000000000000019905200000000000000000000000000000000000000000000000000000000000000200052000000000000000000000000000000000000000000000000000000000000002010520000000000000000000000000000000000000000000000000000000000000020205200000000000000000000000000000000000000000000000000000000000000203052000000000000000000000000000000000000000000000000000000000000002040520000000000000000000000000000000000000000000000000000000000000020505200000000000000000000000000000000000000000000000000000000000000206052000000000000000000000000000000000000000000000000000000000000002070520000000000000000000000000000000000000000000000000000000000000020805200000000000000000000000000000000000000000000000000000000000000209052000000000000000000000000000000000000000000000000000000000000002100520000000000000000000000000000000000000000000000000000000000000021105200000000000000000000000000000000000000000000000000000000000000212052000000000000000000000000000000000000000000000000000000000000002130520000000000000000000000000000000000000000000000000000000000000021405200000000000000000000000000000000000000000000000000000000000000215052000000000000000000000000000000000000000000000000000000000000002160520000000000000000000000000000000000000000000000000000000000000021705200000000000000000000000000000000000000000000000000000000000000218052000000000000000000000000000000000000000000000000000000000000002190520000000000000000000000000000000000000000000000000000000000000022005200000000000000000000000000000000000000000000000000000000000000221052000000000000000000000000000000000000000000000000000000000000002220520000000000000000000000000000000000000000000000000000000000000022305200000000000000000000000000000000000000000000000000000000000000224052000000000000000000000000000000000000000000000000000000000000002250520000000000000000000000000000000000000000000000000000000000000022605200000000000000000000000000000000000000000000000000000000000000227052000000000000000000000000000000000000000000000000000000000000002280520000000000000000000000000000000000000000000000000000000000000022905200000000000000000000000000000000000000000000000000000000000000230052000000000000000000000000000000000000000000000000000000000000002310520000000000000000000000000000000000000000000000000000000000000023205200000000000000000000000000000000000000000000000000000000000000233052000000000000000000000000000000000000000000000000000000000000002340520000000000000000000000000000000000000000000000000000000000000023505200000000000000000000000000000000000000000000000000000000000000236052000000000000000000000000000000000000000000000000000000000000002370520000000000000000000000000000000000000000000000000000000000000023805200000000000000000000000000000000000000000000000000000000000000239052000000000000000000000000000000000000000000000000000000000000002400520000000000000000000000000000000000000000000000000000000000000024105200000000000000000000000000000000000000000000000000000000000000242052000000000000000000000000000000000000000000000000000000000000002430520000000000000000000000000000000000000000000000000000000000000024405200000000000000000000000000000000000000000000000000000000000000245052000000000000000000000000000000000000000000000000000000000000002460520000000000000000000000000000000000000000000000000000000000000024705200000000000000000000000000000000000000000000000000000000000000248052000000000000000000000000000000000000000000000000000000000000002490520000000000000000000000000000000000000000000000000000000000000025005200000000000000000000000000000000000000000000000000000000000000251052000000000000000000000000000000000000000000000000000000000000002520520000000000000000000000000000000000000000000000000000000000000025305200000000000000000000000000000000000000000000000000000000000000254052000000000000000000000000000000000000000000000000000000000000002550520000000000000000000000000000000000000000000000000000000000000025605200000000000000000000000000000000000000000000000000000000000000257052000000000000000000000000000000000000000000000000000000000000002580520000000000000000000000000000000000000000000000000000000000000025905200000000000000000000000000000000000000000000000000000000000000260052000000000000000000000000000000000000000000000000000000000000002610520000000000000000000000000000000000000000000000000000000000000026205200000000000000000000000000000000000000000000000000000000000000263052000000000000000000000000000000000000000000000000000000000000002640520000000000000000000000000000000000000000000000000000000000000026505200000000000000000000000000000000000000000000000000000000000000266052000000000000000000000000000000000000000000000000000000000000002670520000000000000000000000000000000000000000000000000000000000000026805200000000000000000000000000000000000000000000000000000000000000269052000000000000000000000000000000000000000000000000000000000000002700520000000000000000000000000000000000000000000000000000000000000027105200000000000000000000000000000000000000000000000000000000000000272052000000000000000000000000000000000000000000000000000000000000002730520000000000000000000000000000000000000000000000000000000000000027405200000000000000000000000000000000000000000000000000000000000000275052000000000000000000000000000000000000000000000000000000000000002760520000000000000000000000000000000000000000000000000000000000000027705200000000000000000000000000000000000000000000000000000000000000278052000000000000000000000000000000000000000000000000000000000000002790520000000000000000000000000000000000000000000000000000000000000028005200000000000000000000000000000000000000000000000000000000000000281052000000000000000000000000000000000000000000000000000000000000002820520000000000000000000000000000000000000000000000000000000000000028305200000000000000000000000000000000000000000000000000000000000000284052000000000000000000000000000000000000000000000000000000000000002850520000000000000000000000000000000000000000000000000000000000000028605200000000000000000000000000000000000000000000000000000000000000287052000000000000000000000000000000000000000000000000000000000000002880520000000000000000000000000000000000000000000000000000000000000028905200000000000000000000000000000000000000000000000000000000000000290052000000000000000000000000000000000000000000000000000000000000002910520000000000000000000000000000000000000000000000000000000000000029205200000000000000000000000000000000000000000000000000000000000000293052000000000000000000000000000000000000000000000000000000000000002940520000000000000000000000000000000000000000000000000000000000000029505200000000000000000000000000000000000000000000000000000000000000296052000000000000000000000000000000000000000000000000000000000000002970520000000000000000000000000000000000000000000000000000000000000029805200000000000000000000000000000000000000000000000000000000000000299052000000000000000000000000000000000000000000000000000000000000003000520000000000000000000000000000000000000000000000000000000000000030105200000000000000000000000000000000000000000000000000000000000000302052000000000000000000000000000000000000000000000000000000000000003030520000000000000000000000000000000000000000000000000000000000000030405200000000000000000000000000000000000000000000000000000000000000305052000000000000000000000000000000000000000000000000000000000000003060520000000000000000000000000000000000000000000000000000000000000030705200000000000000000000000000000000000000000000000000000000000000308052000000000000000000000000000000000000000000000000000000000000003090520000000000000000000000000000000000000000000000000000000000000031005200000000000000000000000000000000000000000000000000000000000000311052000000000000000000000000000000000000000000000000000000000000003120520000000000000000000000000000000000000000000000000000000000000031305200000000000000000000000000000000000000000000000000000000000000314052000000000000000000000000000000000000000000000000000000000000003150520000000000000000000000000000000000000000000000000000000000000031605200000000000000000000000000000000000000000000000000000000000000317052000000000000000000000000000000000000000000000000000000000000003180520000000000000000000000000000000000000000000000000000000000000031905200000000000000000000000000000000000000000000000000000000000000320052000000000000000000000000000000000000000000000000000000000000003210520000000000000000000000000000000000000000000000000000000000000032205200000000000000000000000000000000000000000000000000000000000000323052000000000000000000000000000000000000000000000000000000000000003240520000000000000000000000000000000000000000000000000000000000000032505200000000000000000000000000000000000000000000000000000000000000326052000000000000000000000000000000000000000000000000000000000000003270520000000000000000000000000000000000000000000000000000000000000032805200000000000000000000000000000000000000000000000000000000000000329052000000000000000000000000000000000000000000000000000000000000003300520000000000000000000000000000000000000000000000000000000000000033105200000000000000000000000000000000000000000000000000000000000000332052000000000000000000000000000000000000000000000000000000000000003330520000000000000000000000000000000000000000000000000000000000000033405200000000000000000000000000000000000000000000000000000000000000335052000000000000000000000000000000000000000000000000000000000000003360520000000000000000000000000000000000000000000000000000000000000033705200000000000000000000000000000000000000000000000000000000000000338052000000000000000000000000000000000000000000000000000000000000003390520000000000000000000000000000000000000000000000000000000000000034005200000000000000000000000000000000000000000000000000000000000000341052000000000000000000000000000000000000000000000000000000000000003420520000000000000000000000000000000000000000000000000000000000000034305200000000000000000000000000000000000000000000000000000000000000344052000000000000000000000000000000000000000000000000000000000000003450520000000000000000000000000000000000000000000000000000000000000034605200000000000000000000000000000000000000000000000000000000000000347052000000000000000000000000000000000000000000000000000000000000003480520000000000000000000000000000000000000000000000000000000000000034905200000000000000000000000000000000000000000000000000000000000000350052000000000000000000000000000000000000000000000000000000000000003510520000000000000000000000000000000000000000000000000000000000000035205200000000000000000000000000000000000000000000000000000000000000353052000000000000000000000000000000000000000000000000000000000000003540520000000000000000000000000000000000000000000000000000000000000035505200000000000000000000000000000000000000000000000000000000000000356052000000000000000000000000000000000000000000000000000000000000003570520000000000000000000000000000000000000000000000000000000000000035805200000000000000000000000000000000000000000000000000000000000000359052000000000000000000000000000000000000000000000000000000000000003600520000000000000000000000000000000000000000000000000000000000000036105200000000000000000000000000000000000000000000000000000000000000362052000000000000000000000000000000000000000000000000000000000000003630520000000000000000000000000000000000000000000000000000000000000036405200000000000000000000000000000000000000000000000000000000000000365052000000000000000000000000000000000000000000000000000000000000003660520000000000000000000000000000000000000000000000000000000000000036705200000000000000000000000000000000000000000000000000000000000000368052000000000000000000000000000000000000000000000000000000000000003690520000000000000000000000000000000000000000000000000000000000000037005200000000000000000000000000000000000000000000000000000000000000371052000000000000000000000000000000000000000000000000000000000000003720520000000000000000000000000000000000000000000000000000000000000037305200000000000000000000000000000000000000000000000000000000000000374052000000000000000000000000000000000000000000000000000000000000003750520000000000000000000000000000000000000000000000000000000000000037605200000000000000000000000000000000000000000000000000000000000000377052000000000000000000000000000000000000000000000000000000000000003780520000000000000000000000000000000000000000000000000000000000000037905200000000000000000000000000000000000000000000000000000000000000380052000000000000000000000000000000000000000000000000000000000000003810520000000000000000000000000000000000000000000000000000000000000038205200000000000000000000000000000000000000000000000000000000000000383052000000000000000000000000000000000000000000000000000000000000003840520000000000000000000000000000000000000000000000000000000000000038505200000000000000000000000000000000000000000000000000000000000000386052000000000000000000000000000000000000000000000000000000000000003870520000000000000000000000000000000000000000000000000000000000000038805200000000000000000000000000000000000000000000000000000000000000389052000000000000000000000000000000000000000000000000000000000000003900520000000000000000000000000000000000000000000000000000000000000039105200000000000000000000000000000000000000000000000000000000000000392052000000000000000000000000000000000000000000000000000000000000003930520000000000000000000000000000000000000000000000000000000000000039405200000000000000000000000000000000000000000000000000000000000000395052000000000000000000000000000000000000000000000000000000000000003960520000000000000000000000000000000000000000000000000000000000000039705200000000000000000000000000000000000000000000000000000000000000398052000000000000000000000000000000000000000000000000000000000000003990520000000000000000000000000000000000000000000000000000000000000040005200000000000000000000000000000000000000000000000000000000000000401052000000000000000000000000000000000000000000000000000000000000004020520000000000000000000000000000000000000000000000000000000000000040305200000000000000000000000000000000000000000000000000000000000000404052000000000000000000000000000000000000000000000000000000000000004050520000000000000000000000000000000000000000000000000000000000000040605200000000000000000000000000000000000000000000000000000000000000407052000000000000000000000000000000000000000000000000000000000000004080520000000000000000000000000000000000000000000000000000000000000040905200000000000000000000000000000000000000000000000000000000000000410052000000000000000000000000000000000000000000000000000000000000004110520000000000000000000000000000000000000000000000000000000000000041205200000000000000000000000000000000000000000000000000000000000000413052000000000000000000000000000000000000000000000000000000000000004140520000000000000000000000000000000000000000000000000000000000000041505200000000000000000000000000000000000000000000000000000000000000416052000000000000000000000000000000000000000000000000000000000000004170520000000000000000000000000000000000000000000000000000000000000041805200000000000000000000000000000000000000000000000000000000000000419052000000000000000000000000000000000000000000000000000000000000004200520000000000000000000000000000000000000000000000000000000000000042105200000000000000000000000000000000000000000000000000000000000000422052000000000000000000000000000000000000000000000000000000000000004230520000000000000000000000000000000000000000000000000000000000000042405200000000000000000000000000000000000000000000000000000000000000425052000000000000000000000000000000000000000000000000000000000000004260520000000000000000000000000000000000000000000000000000000000000042705200000000000000000000000000000000000000000000000000000000000000428052000000000000000000000000000000000000000000000000000000000000004290520000000000000000000000000000000000000000000000000000000000000043005200000000000000000000000000000000000000000000000000000000000000431052000000000000000000000000000000000000000000000000000000000000004320520000000000000000000000000000000000000000000000000000000000000043305200000000000000000000000000000000000000000000000000000000000000434052000000000000000000000000000000000000000000000000000000000000004350520000000000000000000000000000000000000000000000000000000000000043605200000000000000000000000000000000000000000000000000000000000000437052000000000000000000000000000000000000000000000000000000000000004380520000000000000000000000000000000000000000000000000000000000000043905200000000000000000000000000000000000000000000000000000000000000440052000000000000000000000000000000000000000000000000000000000000004410520000000000000000000000000000000000000000000000000000000000000044205200000000000000000000000000000000000000000000000000000000000000443052000000000000000000000000000000000000000000000000000000000000004440520000000000000000000000000000000000000000000000000000000000000044505200000000000000000000000000000000000000000000000000000000000000446052000000000000000000000000000000000000000000000000000000000000004470520000000000000000000000000000000000000000000000000000000000000044805200000000000000000000000000000000000000000000000000000000000000449052000000000000000000000000000000000000000000000000000000000000004500520000000000000000000000000000000000000000000000000000000000000045105200000000000000000000000000000000000000000000000000000000000000452052000000000000000000000000000000000000000000000000000000000000004530520000000000000000000000000000000000000000000000000000000000000045405200000000000000000000000000000000000000000000000000000000000000455052000000000000000000000000000000000000000000000000000000000000004560520000000000000000000000000000000000000000000000000000000000000045705200000000000000000000000000000000000000000000000000000000000000458052000000000000000000000000000000000000000000000000000000000000004590520000000000000000000000000000000000000000000000000000000000000046005200000000000000000000000000000000000000000000000000000000000000461052000000000000000000000000000000000000000000000000000000000000004620520000000000000000000000000000000000000000000000000000000000000046305200000000000000000000000000000000000000000000000000000000000000464052000000000000000000000000000000000000000000000000000000000000004650520000000000000000000000000000000000000000000000000000000000000046605200000000000000000000000000000000000000000000000000000000000000467052000000000000000000000000000000000000000000000000000000000000004680520000000000000000000000000000000000000000000000000000000000000046905200000000000000000000000000000000000000000000000000000000000000470052000000000000000000000000000000000000000000000000000000000000004710520000000000000000000000000000000000000000000000000000000000000047205200000000000000000000000000000000000000000000000000000000000000473052000000000000000000000000000000000000000000000000000000000000004740520000000000000000000000000000000000000000000000000000000000000047505200000000000000000000000000000000000000000000000000000000000000476052000000000000000000000000000000000000000000000000000000000000004770520000000000000000000000000000000000000000000000000000000000000047805200000000000000000000000000000000000000000000000000000000000000479052000000000000000000000000000000000000000000000000000000000000004800520000000000000000000000000000000000000000000000000000000000000048105200000000000000000000000000000000000000000000000000000000000000482052000000000000000000000000000000000000000000000000000000000000004830520000000000000000000000000000000000000000000000000000000000000048405200000000000000000000000000000000000000000000000000000000000000485052000000000000000000000000000000000000000000000000000000000000004860520000000000000000000000000000000000000000000000000000000000000048705200000000000000000000000000000000000000000000000000000000000000488052000000000000000000000000000000000000000000000000000000000000004890520000000000000000000000000000000000000000000000000000000000000049005200000000000000000000000000000000000000000000000000000000000000491052000000000000000000000000000000000000000000000000000000000000004920520000000000000000000000000000000000000000000000000000000000000049305200000000000000000000000000000000000000000000000000000000000000494052000000000000000000000000000000000000000000000000000000000000004950520000000000000000000000000000000000000000000000000000000000000049605200000000000000000000000000000000000000000000000000000000000000497052000000000000000000000000000000000000000000000000000000000000004980520000000000000000000000000000000000000000000000000000000000000049905200000000000000000000000000000000000000000000000000000000000000500052000000000000000000000000000000000000000000000000000000000000005010520000000000000000000000000000000000000000000000000000000000000050205200000000000000000000000000000000000000000000000000000000000000503052000000000000000000000000000000000000000000000000000000000000005040520000000000000000000000000000000000000000000000000000000000000050505200000000000000000000000000000000000000000000000000000000000000506052000000000000000000000000000000000000000000000000000000000000005070520000000000000000000000000000000000000000000000000000000000000050805200000000000000000000000000000000000000000000000000000000000000509052000000000000000000000000000000000000000000000000000000000000005100520000000000000000000000000000000000000000000000000000000000000051105200000000000000000000000000000000000000000000000000000000000000512052000000000000000000000000000000000000000000000000000000000000005130520000000000000000000000000000000000000000000000000000000000000051405200000000000000000000000000000000000000000000000000000000000000515052000000000000000000000000000000000000000000000000000000000000005160520000000000000000000000000000000000000000000000000000000000000051705200000000000000000000000000000000000000000000000000000000000000518052000000000000000000000000000000000000000000000000000000000000005190520000000000000000000000000000000000000000000000000000000000000052005200000000000000000000000000000000000000000000000000000000000000521052000000000000000000000000000000000000000000000000000000000000005220520000000000000000000000000000000000000000000000000000000000000052305200000000000000000000000000000000000000000000000000000000000000524052000000000000000000000000000000000000000000000000000000000000005250520000000000000000000000000000000000000000000000000000000000000052605200000000000000000000000000000000000000000000000000000000000000527052000000000000000000000000000000000000000000000000000000000000005280520000000000000000000000000000000000000000000000000000000000000052905200000000000000000000000000000000000000000000000000000000000000530052000000000000000000000000000000000000000000000000000000000000005310520000000000000000000000000000000000000000000000000000000000000053205200000000000000000000000000000000000000000000000000000000000000533052000000000000000000000000000000000000000000000000000000000000005340520000000000000000000000000000000000000000000000000000000000000053505200000000000000000000000000000000000000000000000000000000000000536052000000000000000000000000000000000000000000000000000000000000005370520000000000000000000000000000000000000000000000000000000000000053805200000000000000000000000000000000000000000000000000000000000000539052000000000000000000000000000000000000000000000000000000000000005400520000000000000000000000000000000000000000000000000000000000000054105200000000000000000000000000000000000000000000000000000000000000542052000000000000000000000000000000000000000000000000000000000000005430520000000000000000000000000000000000000000000000000000000000000054405200000000000000000000000000000000000000000000000000000000000000545052000000000000000000000000000000000000000000000000000000000000005460520000000000000000000000000000000000000000000000000000000000000054705200000000000000000000000000000000000000000000000000000000000000548052000000000000000000000000000000000000000000000000000000000000005490520000000000000000000000000000000000000000000000000000000000000055005200000000000000000000000000000000000000000000000000000000000000551052000000000000000000000000000000000000000000000000000000000000005520520000000000000000000000000000000000000000000000000000000000000055305200000000000000000000000000000000000000000000000000000000000000554052000000000000000000000000000000000000000000000000000000000000005550520000000000000000000000000000000000000000000000000000000000000055605200000000000000000000000000000000000000000000000000000000000000557052000000000000000000000000000000000000000000000000000000000000005580520000000000000000000000000000000000000000000000000000000000000055905200000000000000000000000000000000000000000000000000000000000000560052000000000000000000000000000000000000000000000000000000000000005610520000000000000000000000000000000000000000000000000000000000000056205200000000000000000000000000000000000000000000000000000000000000563052000000000000000000000000000000000000000000000000000000000000005640520000000000000000000000000000000000000000000000000000000000000056505200000000000000000000000000000000000000000000000000000000000000566052000000000000000000000000000000000000000000000000000000000000005670520000000000000000000000000000000000000000000000000000000000000056805200000000000000000000000000000000000000000000000000000000000000569052000000000000000000000000000000000000000000000000000000000000005700520000000000000000000000000000000000000000000000000000000000000057105200000000000000000000000000000000000000000000000000000000000000572052000000000000000000000000000000000000000000000000000000000000005730520000000000000000000000000000000000000000000000000000000000000057405200000000000000000000000000000000000000000000000000000000000000575052000000000000000000000000000000000000000000000000000000000000005760520000000000000000000000000000000000000000000000000000000000000057705200000000000000000000000000000000000000000000000000000000000000578052000000000000000000000000000000000000000000000000000000000000005790520000000000000000000000000000000000000000000000000000000000000058005200000000000000000000000000000000000000000000000000000000000000581052000000000000000000000000000000000000000000000000000000000000005820520000000000000000000000000000000000000000000000000000000000000058305200000000000000000000000000000000000000000000000000000000000000584052000000000000000000000000000000000000000000000000000000000000005850520000000000000000000000000000000000000000000000000000000000000058605200000000000000000000000000000000000000000000000000000000000000587052000000000000000000000000000000000000000000000000000000000000005880520000000000000000000000000000000000000000000000000000000000000058905200000000000000000000000000000000000000000000000000000000000000590052000000000000000000000000000000000000000000000000000000000000005910520000000000000000000000000000000000000000000000000000000000000059205200000000000000000000000000000000000000000000000000000000000000593052000000000000000000000000000000000000000000000000000000000000005940520000000000000000000000000000000000000000000000000000000000000059505200000000000000000000000000000000000000000000000000000000000000596052000000000000000000000000000000000000000000000000000000000000005970520000000000000000000000000000000000000000000000000000000000000059805200000000000000000000000000000000000000000000000000000000000000599052000000000000000000000000000000000000000000000000000000000000006000520000000000000000000000000000000000000000000000000000000000000060105200000000000000000000000000000000000000000000000000000000000000602052000000000000000000000000000000000000000000000000000000000000006030520000000000000000000000000000000000000000000000000000000000000060405200000000000000000000000000000000000000000000000000000000000000605052000000000000000000000000000000000000000000000000000000000000006060520000000000000000000000000000000000000000000000000000000000000060705200000000000000000000000000000000000000000000000000000000000000608052000000000000000000000000000000000000000000000000000000000000006090520000000000000000000000000000000000000000000000000000000000000061005200000000000000000000000000000000000000000000000000000000000000611052000000000000000000000000000000000000000000000000000000000000006120520000000000000000000000000000000000000000000000000000000000000061305200000000000000000000000000000000000000000000000000000000000000614052000000000000000000000000000000000000000000000000000000000000006150520000000000000000000000000000000000000000000000000000000000000061605200000000000000000000000000000000000000000000000000000000000000617052000000000000000000000000000000000000000000000000000000000000006180520000000000000000000000000000000000000000000000000000000000000061905200000000000000000000000000000000000000000000000000000000000000620052000000000000000000000000000000000000000000000000000000000000006210520000000000000000000000000000000000000000000000000000000000000062205200000000000000000000000000000000000000000000000000000000000000623052000000000000000000000000000000000000000000000000000000000000006240520000000000000000000000000000000000000000000000000000000000000062505200000000000000000000000000000000000000000000000000000000000000626052000000000000000000000000000000000000000000000000000000000000006270520000000000000000000000000000000000000000000000000000000000000062805200000000000000000000000000000000000000000000000000000000000000629052000000000000000000000000000000000000000000000000000000000000006300520000000000000000000000000000000000000000000000000000000000000063105200000000000000000000000000000000000000000000000000000000000000632052000000000000000000000000000000000000000000000000000000000000006330520000000000000000000000000000000000000000000000000000000000000063405200000000000000000000000000000000000000000000000000000000000000635052000000000000000000000000000000000000000000000000000000000000006360520000000000000000000000000000000000000000000000000000000000000063705200000000000000000000000000000000000000000000000000000000000000638052000000000000000000000000000000000000000000000000000000000000006390520000000000000000000000000000000000000000000000000000000000000064005200000000000000000000000000000000000000000000000000000000000000641052000000000000000000000000000000000000000000000000000000000000006420520000000000000000000000000000000000000000000000000000000000000064305200000000000000000000000000000000000000000000000000000000000000644052000000000000000000000000000000000000000000000000000000000000006450520000000000000000000000000000000000000000000000000000000000000064605200000000000000000000000000000000000000000000000000000000000000647052000000000000000000000000000000000000000000000000000000000000006480520000000000000000000000000000000000000000000000000000000000000064905200000000000000000000000000000000000000000000000000000000000000650052000000000000000000000000000000000000000000000000000000000000006510520000000000000000000000000000000000000000000000000000000000000065205200000000000000000000000000000000000000000000000000000000000000653052000000000000000000000000000000000000000000000000000000000000006540520000000000000000000000000000000000000000000000000000000000000065505200000000000000000000000000000000000000000000000000000000000000656052000000000000000000000000000000000000000000000000000000000000006570520000000000000000000000000000000000000000000000000000000000000065805200000000000000000000000000000000000000000000000000000000000000659052000000000000000000000000000000000000000000000000000000000000006600520000000000000000000000000000000000000000000000000000000000000066105200000000000000000000000000000000000000000000000000000000000000662052000000000000000000000000000000000000000000000000000000000000006630520000000000000000000000000000000000000000000000000000000000000066405200000000000000000000000000000000000000000000000000000000000000665052000000000000000000000000000000000000000000000000000000000000006660520000000000000000000000000000000000000000000000000000000000000066705200000000000000000000000000000000000000000000000000000000000000668052000000000000000000000000000000000000000000000000000000000000006690520000000000000000000000000000000000000000000000000000000000000067005200000000000000000000000000000000000000000000000000000000000000671052000000000000000000000000000000000000000000000000000000000000006720520000000000000000000000000000000000000000000000000000000000000067305200000000000000000000000000000000000000000000000000000000000000674052000000000000000000000000000000000000000000000000000000000000006750520000000000000000000000000000000000000000000000000000000000000067605200000000000000000000000000000000000000000000000000000000000000677052000000000000000000000000000000000000000000000000000000000000006780520000000000000000000000000000000000000000000000000000000000000067905200000000000000000000000000000000000000000000000000000000000000680052000000000000000000000000000000000000000000000000000000000000006810520000000000000000000000000000000000000000000000000000000000000068205200000000000000000000000000000000000000000000000000000000000000683052000000000000000000000000000000000000000000000000000000000000006840520000000000000000000000000000000000000000000000000000000000000068505200000000000000000000000000000000000000000000000000000000000000686052000000000000000000000000000000000000000000000000000000000000006870520000000000000000000000000000000000000000000000000000000000000068805200000000000000000000000000000000000000000000000000000000000000689052000000000000000000000000000000000000000000000000000000000000006900520000000000000000000000000000000000000000000000000000000000000069105200000000000000000000000000000000000000000000000000000000000000692052000000000000000000000000000000000000000000000000000000000000006930520000000000000000000000000000000000000000000000000000000000000069405200000000000000000000000000000000000000000000000000000000000000695052000000000000000000000000000000000000000000000000000000000000006960520000000000000000000000000000000000000000000000000000000000000069705200000000000000000000000000000000000000000000000000000000000000698052000000000000000000000000000000000000000000000000000000000000006990520000000000000000000000000000000000000000000000000000000000000070005200000000000000000000000000000000000000000000000000000000000000701052000000000000000000000000000000000000000000000000000000000000007020520000000000000000000000000000000000000000000000000000000000000070305200000000000000000000000000000000000000000000000000000000000000704052000000000000000000000000000000000000000000000000000000000000007050520000000000000000000000000000000000000000000000000000000000000070605200000000000000000000000000000000000000000000000000000000000000707052000000000000000000000000000000000000000000000000000000000000007080520000000000000000000000000000000000000000000000000000000000000070905200000000000000000000000000000000000000000000000000000000000000710052000000000000000000000000000000000000000000000000000000000000007110520000000000000000000000000000000000000000000000000000000000000071205200000000000000000000000000000000000000000000000000000000000000713052000000000000000000000000000000000000000000000000000000000000007140520000000000000000000000000000000000000000000000000000000000000071505200000000000000000000000000000000000000000000000000000000000000716052000000000000000000000000000000000000000000000000000000000000007170520000000000000000000000000000000000000000000000000000000000000071805200000000000000000000000000000000000000000000000000000000000000719052000000000000000000000000000000000000000000000000000000000000007200520000000000000000000000000000000000000000000000000000000000000072105200000000000000000000000000000000000000000000000000000000000000722052000000000000000000000000000000000000000000000000000000000000007230520000000000000000000000000000000000000000000000000000000000000072405200000000000000000000000000000000000000000000000000000000000000725052000000000000000000000000000000000000000000000000000000000000007260520000000000000000000000000000000000000000000000000000000000000072705200000000000000000000000000000000000000000000000000000000000000728052000000000000000000000000000000000000000000000000000000000000007290520000000000000000000000000000000000000000000000000000000000000073005200000000000000000000000000000000000000000000000000000000000000731052000000000000000000000000000000000000000000000000000000000000007320520000000000000000000000000000000000000000000000000000000000000073305200000000000000000000000000000000000000000000000000000000000000734052000000000000000000000000000000000000000000000000000000000000007350520000000000000000000000000000000000000000000000000000000000000073605200000000000000000000000000000000000000000000000000000000000000737052000000000000000000000000000000000000000000000000000000000000007380520000000000000000000000000000000000000000000000000000000000000073905200000000000000000000000000000000000000000000000000000000000000740052000000000000000000000000000000000000000000000000000000000000007410520000000000000000000000000000000000000000000000000000000000000074205200000000000000000000000000000000000000000000000000000000000000743052000000000000000000000000000000000000000000000000000000000000007440520000000000000000000000000000000000000000000000000000000000000074505200000000000000000000000000000000000000000000000000000000000000746052000000000000000000000000000000000000000000000000000000000000007470520000000000000000000000000000000000000000000000000000000000000074805200000000000000000000000000000000000000000000000000000000000000749052000000000000000000000000000000000000000000000000000000000000007500520000000000000000000000000000000000000000000000000000000000000075105200000000000000000000000000000000000000000000000000000000000000752052000000000000000000000000000000000000000000000000000000000000007530520000000000000000000000000000000000000000000000000000000000000075405200000000000000000000000000000000000000000000000000000000000000755052000000000000000000000000000000000000000000000000000000000000007560520000000000000000000000000000000000000000000000000000000000000075705200000000000000000000000000000000000000000000000000000000000000758052000000000000000000000000000000000000000000000000000000000000007590520000000000000000000000000000000000000000000000000000000000000076005200000000000000000000000000000000000000000000000000000000000000761052000000000000000000000000000000000000000000000000000000000000007620520000000000000000000000000000000000000000000000000000000000000076305200000000000000000000000000000000000000000000000000000000000000764052000000000000000000000000000000000000000000000000000000000000007650520000000000000000000000000000000000000000000000000000000000000076605200000000000000000000000000000000000000000000000000000000000000767052000000000000000000000000000000000000000000000000000000000000007680520000000000000000000000000000000000000000000000000000000000000076905200000000000000000000000000000000000000000000000000000000000000770052000000000000000000000000000000000000000000000000000000000000007710520000000000000000000000000000000000000000000000000000000000000077205200000000000000000000000000000000000000000000000000000000000000773052000000000000000000000000000000000000000000000000000000000000007740520000000000000000000000000000000000000000000000000000000000000077505200000000000000000000000000000000000000000000000000000000000000776052000000000000000000000000000000000000000000000000000000000000007770520000000000000000000000000000000000000000000000000000000000000077805200000000000000000000000000000000000000000000000000000000000000779052000000000000000000000000000000000000000000000000000000000000007800520000000000000000000000000000000000000000000000000000000000000078105200000000000000000000000000000000000000000000000000000000000000782052000000000000000000000000000000000000000000000000000000000000007830520000000000000000000000000000000000000000000000000000000000000078405200000000000000000000000000000000000000000000000000000000000000785052000000000000000000000000000000000000000000000000000000000000007860520000000000000000000000000000000000000000000000000000000000000078705200000000000000000000000000000000000000000000000000000000000000788052000000000000000000000000000000000000000000000000000000000000007890520000000000000000000000000000000000000000000000000000000000000079005200000000000000000000000000000000000000000000000000000000000000791052000000000000000000000000000000000000000000000000000000000000007920520000000000000000000000000000000000000000000000000000000000000079305200000000000000000000000000000000000000000000000000000000000000794052000000000000000000000000000000000000000000000000000000000000007950520000000000000000000000000000000000000000000000000000000000000079605200000000000000000000000000000000000000000000000000000000000000797052000000000000000000000000000000000000000000000000000000000000007980520000000000000000000000000000000000000000000000000000000000000079905200000000000000000000000000000000000000000000000000000000000000800052000000000000000000000000000000000000000000000000000000000000008010520000000000000000000000000000000000000000000000000000000000000080205200000000000000000000000000000000000000000000000000000000000000803052000000000000000000000000000000000000000000000000000000000000008040520000000000000000000000000000000000000000000000000000000000000080505200000000000000000000000000000000000000000000000000000000000000806052000000000000000000000000000000000000000000000000000000000000008070520000000000000000000000000000000000000000000000000000000000000080805200000000000000000000000000000000000000000000000000000000000000809052000000000000000000000000000000000000000000000000000000000000008100520000000000000000000000000000000000000000000000000000000000000081105200000000000000000000000000000000000000000000000000000000000000812052000000000000000000000000000000000000000000000000000000000000008130520000000000000000000000000000000000000000000000000000000000000081405200000000000000000000000000000000000000000000000000000000000000815052000000000000000000000000000000000000000000000000000000000000008160520000000000000000000000000000000000000000000000000000000000000081705200000000000000000000000000000000000000000000000000000000000000818052000000000000000000000000000000000000000000000000000000000000008190520000000000000000000000000000000000000000000000000000000000000082005200000000000000000000000000000000000000000000000000000000000000821052000000000000000000000000000000000000000000000000000000000000008220520000000000000000000000000000000000000000000000000000000000000082305200000000000000000000000000000000000000000000000000000000000000824052000000000000000000000000000000000000000000000000000000000000008250520000000000000000000000000000000000000000000000000000000000000082605200000000000000000000000000000000000000000000000000000000000000827052000000000000000000000000000000000000000000000000000000000000008280520000000000000000000000000000000000000000000000000000000000000082905200000000000000000000000000000000000000000000000000000000000000830052000000000000000000000000000000000000000000000000000000000000008310520000000000000000000000000000000000000000000000000000000000000083205200000000000000000000000000000000000000000000000000000000000000833052000000000000000000000000000000000000000000000000000000000000008340520000000000000000000000000000000000000000000000000000000000000083505200000000000000000000000000000000000000000000000000000000000000836052000000000000000000000000000000000000000000000000000000000000008370520000000000000000000000000000000000000000000000000000000000000083805200000000000000000000000000000000000000000000000000000000000000839052000000000000000000000000000000000000000000000000000000000000008400520000000000000000000000000000000000000000000000000000000000000084105200000000000000000000000000000000000000000000000000000000000000842052000000000000000000000000000000000000000000000000000000000000008430520000000000000000000000000000000000000000000000000000000000000084405200000000000000000000000000000000000000000000000000000000000000845052000000000000000000000000000000000000000000000000000000000000008460520000000000000000000000000000000000000000000000000000000000000084705200000000000000000000000000000000000000000000000000000000000000848052000000000000000000000000000000000000000000000000000000000000008490520000000000000000000000000000000000000000000000000000000000000085005200000000000000000000000000000000000000000000000000000000000000851052000000000000000000000000000000000000000000000000000000000000008520520000000000000000000000000000000000000000000000000000000000000085305200000000000000000000000000000000000000000000000000000000000000854052000000000000000000000000000000000000000000000000000000000000008550520000000000000000000000000000000000000000000000000000000000000085605200000000000000000000000000000000000000000000000000000000000000857052000000000000000000000000000000000000000000000000000000000000008580520000000000000000000000000000000000000000000000000000000000000085905200000000000000000000000000000000000000000000000000000000000000860052000000000000000000000000000000000000000000000000000000000000008610520000000000000000000000000000000000000000000000000000000000000086205200000000000000000000000000000000000000000000000000000000000000863052000000000000000000000000000000000000000000000000000000000000008640520000000000000000000000000000000000000000000000000000000000000086505200000000000000000000000000000000000000000000000000000000000000866052000000000000000000000000000000000000000000000000000000000000008670520000000000000000000000000000000000000000000000000000000000000086805200000000000000000000000000000000000000000000000000000000000000869052000000000000000000000000000000000000000000000000000000000000008700520000000000000000000000000000000000000000000000000000000000000087105200000000000000000000000000000000000000000000000000000000000000872052000000000000000000000000000000000000000000000000000000000000008730520000000000000000000000000000000000000000000000000000000000000087405200000000000000000000000000000000000000000000000000000000000000875052000000000000000000000000000000000000000000000000000000000000008760520000000000000000000000000000000000000000000000000000000000000087705200000000000000000000000000000000000000000000000000000000000000878052000000000000000000000000000000000000000000000000000000000000008790520000000000000000000000000000000000000000000000000000000000000088005200000000000000000000000000000000000000000000000000000000000000881052000000000000000000000000000000000000000000000000000000000000008820520000000000000000000000000000000000000000000000000000000000000088305200000000000000000000000000000000000000000000000000000000000000884052000000000000000000000000000000000000000000000000000000000000008850520000000000000000000000000000000000000000000000000000000000000088605200000000000000000000000000000000000000000000000000000000000000887052000000000000000000000000000000000000000000000000000000000000008880520000000000000000000000000000000000000000000000000000000000000088905200000000000000000000000000000000000000000000000000000000000000890052000000000000000000000000000000000000000000000000000000000000008910520000000000000000000000000000000000000000000000000000000000000089205200000000000000000000000000000000000000000000000000000000000000893052000000000000000000000000000000000000000000000000000000000000008940520000000000000000000000000000000000000000000000000000000000000089505200000000000000000000000000000000000000000000000000000000000000896052000000000000000000000000000000000000000000000000000000000000008970520000000000000000000000000000000000000000000000000000000000000089805200000000000000000000000000000000000000000000000000000000000000899052000000000000000000000000000000000000000000000000000000000000009000520000000000000000000000000000000000000000000000000000000000000090105200000000000000000000000000000000000000000000000000000000000000902052000000000000000000000000000000000000000000000000000000000000009030520000000000000000000000000000000000000000000000000000000000000090405200000000000000000000000000000000000000000000000000000000000000905052000000000000000000000000000000000000000000000000000000000000009060520000000000000000000000000000000000000000000000000000000000000090705200000000000000000000000000000000000000000000000000000000000000908052000000000000000000000000000000000000000000000000000000000000009090520000000000000000000000000000000000000000000000000000000000000091005200000000000000000000000000000000000000000000000000000000000000911052000000000000000000000000000000000000000000000000000000000000009120520000000000000000000000000000000000000000000000000000000000000091305200000000000000000000000000000000000000000000000000000000000000914052000000000000000000000000000000000000000000000000000000000000009150520000000000000000000000000000000000000000000000000000000000000091605200000000000000000000000000000000000000000000000000000000000000917052000000000000000000000000000000000000000000000000000000000000009180520000000000000000000000000000000000000000000000000000000000000091905200000000000000000000000000000000000000000000000000000000000000920052000000000000000000000000000000000000000000000000000000000000009210520000000000000000000000000000000000000000000000000000000000000092205200000000000000000000000000000000000000000000000000000000000000923052000000000000000000000000000000000000000000000000000000000000009240520000000000000000000000000000000000000000000000000000000000000092505200000000000000000000000000000000000000000000000000000000000000926052000000000000000000000000000000000000000000000000000000000000009270520000000000000000000000000000000000000000000000000000000000000092805200000000000000000000000000000000000000000000000000000000000000929052000000000000000000000000000000000000000000000000000000000000009300520000000000000000000000000000000000000000000000000000000000000093105200000000000000000000000000000000000000000000000000000000000000932052000000000000000000000000000000000000000000000000000000000000009330520000000000000000000000000000000000000000000000000000000000000093405200000000000000000000000000000000000000000000000000000000000000935052000000000000000000000000000000000000000000000000000000000000009360520000000000000000000000000000000000000000000000000000000000000093705200000000000000000000000000000000000000000000000000000000000000938052000000000000000000000000000000000000000000000000000000000000009390520000000000000000000000000000000000000000000000000000000000000094005200000000000000000000000000000000000000000000000000000000000000941052000000000000000000000000000000000000000000000000000000000000009420520000000000000000000000000000000000000000000000000000000000000094305200000000000000000000000000000000000000000000000000000000000000944052000000000000000000000000000000000000000000000000000000000000009450520000000000000000000000000000000000000000000000000000000000000094605200000000000000000000000000000000000000000000000000000000000000947052000000000000000000000000000000000000000000000000000000000000009480520000000000000000000000000000000000000000000000000000000000000094905200000000000000000000000000000000000000000000000000000000000000950052000000000000000000000000000000000000000000000000000000000000009510520000000000000000000000000000000000000000000000000000000000000095205200000000000000000000000000000000000000000000000000000000000000953052000000000000000000000000000000000000000000000000000000000000009540520000000000000000000000000000000000000000000000000000000000000095505200000000000000000000000000000000000000000000000000000000000000956052000000000000000000000000000000000000000000000000000000000000009570520000000000000000000000000000000000000000000000000000000000000095805200000000000000000000000000000000000000000000000000000000000000959052000000000000000000000000000000000000000000000000000000000000009600520000000000000000000000000000000000000000000000000000000000000096105200000000000000000000000000000000000000000000000000000000000000962052000000000000000000000000000000000000000000000000000000000000009630520000000000000000000000000000000000000000000000000000000000000096405200000000000000000000000000000000000000000000000000000000000000965052000000000000000000000000000000000000000000000000000000000000009660520000000000000000000000000000000000000000000000000000000000000096705200000000000000000000000000000000000000000000000000000000000000968052000000000000000000000000000000000000000000000000000000000000009690520000000000000000000000000000000000000000000000000000000000000097005200000000000000000000000000000000000000000000000000000000000000971052000000000000000000000000000000000000000000000000000000000000009720520000000000000000000000000000000000000000000000000000000000000097305200000000000000000000000000000000000000000000000000000000000000974052000000000000000000000000000000000000000000000000000000000000009750520000000000000000000000000000000000000000000000000000000000000097605200000000000000000000000000000000000000000000000000000000000000977052000000000000000000000000000000000000000000000000000000000000009780520000000000000000000000000000000000000000000000000000000000000097905200000000000000000000000000000000000000000000000000000000000000980052000000000000000000000000000000000000000000000000000000000000009810520000000000000000000000000000000000000000000000000000000000000098205200000000000000000000000000000000000000000000000000000000000000983052000000000000000000000000000000000000000000000000000000000000009840520000000000000000000000000000000000000000000000000000000000000098505200000000000000000000000000000000000000000000000000000000000000986052000000000000000000000000000000000000000000000000000000000000009870520000000000000000000000000000000000000000000000000000000000000098805200000000000000000000000000000000000000000000000000000000000000989052000000000000000000000000000000000000000000000000000000000000009900520000000000000000000000000000000000000000000000000000000000000099105200000000000000000000000000000000000000000000000000000000000000992052000000000000000000000000000000000000000000000000000000000000009930520000000000000000000000000000000000000000000000000000000000000099405200000000000000000000000000000000000000000000000000000000000000995052000000000000000000000000000000000000000000000000000000000000009960520000000000000000000000000000000000000000000000000000000000000099705200000000000000000000000000000000000000000000000000000000000000998052000000000000000000000000000000000000000000000000000000000000009990520e57eb8d10b6eed36a88a464538f8fcedbba7b1a71d6ed52124f77b835807d0fd05201c53ca351e7f26f963ced56cf18f9ebee56535170171b72a0addb4e1613776850520636b8e5a599cfe0833dbe141dbc093d65e0a497451ac21415fbf03698587c7b905204ea21cad94a85adb252b0a76b9826c67d7c697ca386d201752e38f19ed92a223126170746f733a3a6d657461646174615f7630c201032003000000000000134552525f414c52454144595f50524553454e542c4164647265737320697320616c72656164792070726573656e7420696e207468652077686974656c6973742e2103000000000000134552525f4e4f5f535543485f41444452455353214e6f2073756368206164647265737320696e207468652077686974656c6973742e2203000000000000134552525f4e4f545f494e495449414c495a45441d57686974656c697374206973206e6f7420696e697469616c697a65642e000201090b010205020001040100051d0b0011050c020b02070321030907012707032900030e0701270a01110220031407002707032a000c030b030f000b013101380002010104010008b01f0b0011050c010b01070321030907012707032a000c030b030f000c020a020704310138000a020705310138000a020706310138000a020707310138000a020708310138000a020709310138000a02070a310138000a02070b310138000a02070c310138000a02070d310138000a02070e310138000a02070f310138000a020710310138000a020711310138000a020712310138000a020713310138000a020714310138000a020715310138000a020716310138000a020717310138000a020718310138000a020719310138000a02071a310138000a02071b310138000a02071c310138000a02071d310138000a02071e310138000a02071f310138000a020720310138000a020721310138000a020722310138000a020723310138000a020724310138000a020725310138000a020726310138000a020727310138000a020728310138000a020729310138000a02072a310138000a02072b310138000a02072c310138000a02072d310138000a02072e310138000a02072f310138000a020730310138000a020731310138000a020732310138000a020733310138000a020734310138000a020735310138000a020736310138000a020737310138000a020738310138000a020739310138000a02073a310138000a02073b310138000a02073c310138000a02073d310138000a02073e310138000a02073f310138000a020740310138000a020741310138000a020742310138000a020743310138000a020744310138000a020745310138000a020746310138000a020747310138000a020748310138000a020749310138000a02074a310138000a02074b310138000a02074c310138000a02074d310138000a02074e310138000a02074f310138000a020750310138000a020751310138000a020752310138000a020753310138000a020754310138000a020755310138000a020756310138000a020757310138000a020758310138000a020759310138000a02075a310138000a02075b310138000a02075c310138000a02075d310138000a02075e310138000a02075f310138000a020760310138000a020761310138000a020762310138000a020763310138000a020764310138000a020765310138000a020766310138000a020767310138000a020768310138000a020769310138000a02076a310138000a02076b310138000a02076c310138000a02076d310138000a02076e310138000a02076f310138000a020770310138000a020771310138000a020772310138000a020773310138000a020774310138000a020775310138000a020776310138000a020777310138000a020778310138000a020779310138000a02077a310138000a02077b310138000a02077c310138000a02077d310138000a02077e310138000a02077f310138000a02078001310138000a02078101310138000a02078201310138000a02078301310138000a02078401310138000a02078501310138000a02078601310138000a02078701310138000a02078801310138000a02078901310138000a02078a01310138000a02078b01310138000a02078c01310138000a02078d01310138000a02078e01310138000a02078f01310138000a02079001310138000a02079101310138000a02079201310138000a02079301310138000a02079401310138000a02079501310138000a02079601310138000a02079701310138000a02079801310138000a02079901310138000a02079a01310138000a02079b01310138000a02079c01310138000a02079d01310138000a02079e01310138000a02079f01310138000a0207a001310138000a0207a101310138000a0207a201310138000a0207a301310138000a0207a401310138000a0207a501310138000a0207a601310138000a0207a701310138000a0207a801310138000a0207a901310138000a0207aa01310138000a0207ab01310138000a0207ac01310138000a0207ad01310138000a0207ae01310138000a0207af01310138000a0207b001310138000a0207b101310138000a0207b201310138000a0207b301310138000a0207b401310138000a0207b501310138000a0207b601310138000a0207b701310138000a0207b801310138000a0207b901310138000a0207ba01310138000a0207bb01310138000a0207bc01310138000a0207bd01310138000a0207be01310138000a0207bf01310138000a0207c001310138000a0207c101310138000a0207c201310138000a0207c301310138000a0207c401310138000a0207c501310138000a0207c601310138000a0207c701310138000a0207c801310138000a0207c901310138000a0207ca01310138000a0207cb01310138000a0207cc01310138000a0207cd01310138000a0207ce01310138000a0207cf01310138000a0207d001310138000a0207d101310138000a0207d201310138000a0207d301310138000a0207d401310138000a0207d501310138000a0207d601310138000a0207d701310138000a0207d801310138000a0207d901310138000a0207da01310138000a0207db01310138000a0207dc01310138000a0207dd01310138000a0207de01310138000a0207df01310138000a0207e001310138000a0207e101310138000a0207e201310138000a0207e301310138000a0207e401310138000a0207e501310138000a0207e601310138000a0207e701310138000a0207e801310138000a0207e901310138000a0207ea01310138000a0207eb01310138000a0207ec01310138000a0207ed01310138000a0207ee01310138000a0207ef01310138000a0207f001310138000a0207f101310138000a0207f201310138000a0207f301310138000a0207f401310138000a0207f501310138000a0207f601310138000a0207f701310138000a0207f801310138000a0207f901310138000a0207fa01310138000a0207fb01310138000a0207fc01310138000a0207fd01310138000a0207fe01310138000a0207ff01310138000a02078002310138000a02078102310138000a02078202310138000a02078302310138000a02078402310138000a02078502310138000a02078602310138000a02078702310138000a02078802310138000a02078902310138000a02078a02310138000a02078b02310138000a02078c02310138000a02078d02310138000a02078e02310138000a02078f02310138000a02079002310138000a02079102310138000a02079202310138000a02079302310138000a02079402310138000a02079502310138000a02079602310138000a02079702310138000a02079802310138000a02079902310138000a02079a02310138000a02079b02310138000a02079c02310138000a02079d02310138000a02079e02310138000a02079f02310138000a0207a002310138000a0207a102310138000a0207a202310138000a0207a302310138000a0207a402310138000a0207a502310138000a0207a602310138000a0207a702310138000a0207a802310138000a0207a902310138000a0207aa02310138000a0207ab02310138000a0207ac02310138000a0207ad02310138000a0207ae02310138000a0207af02310138000a0207b002310138000a0207b102310138000a0207b202310138000a0207b302310138000a0207b402310138000a0207b502310138000a0207b602310138000a0207b702310138000a0207b802310138000a0207b902310138000a0207ba02310138000a0207bb02310138000a0207bc02310138000a0207bd02310138000a0207be02310138000a0207bf02310138000a0207c002310138000a0207c102310138000a0207c202310138000a0207c302310138000a0207c402310138000a0207c502310138000a0207c602310138000a0207c702310138000a0207c802310138000a0207c902310138000a0207ca02310138000a0207cb02310138000a0207cc02310138000a0207cd02310138000a0207ce02310138000a0207cf02310138000a0207d002310138000a0207d102310138000a0207d202310138000a0207d302310138000a0207d402310138000a0207d502310138000a0207d602310138000a0207d702310138000a0207d802310138000a0207d902310138000a0207da02310138000a0207db02310138000a0207dc02310138000a0207dd02310138000a0207de02310138000a0207df02310138000a0207e002310138000a0207e102310138000a0207e202310138000a0207e302310138000a0207e402310138000a0207e502310138000a0207e602310138000a0207e702310138000a0207e802310138000a0207e902310138000a0207ea02310138000a0207eb02310138000a0207ec02310138000a0207ed02310138000a0207ee02310138000a0207ef02310138000a0207f002310138000a0207f102310138000a0207f202310138000a0207f302310138000a0207f402310138000a0207f502310138000a0207f602310138000a0207f702310138000a0207f802310138000a0207f902310138000a0207fa02310138000a0207fb02310138000a0207fc02310138000a0207fd02310138000a0207fe02310138000a0207ff02310138000a02078003310138000a02078103310138000a02078203310138000a02078303310138000a02078403310138000a02078503310138000a02078603310138000a02078703310138000a02078803310138000a02078903310138000a02078a03310138000a02078b03310138000a02078c03310138000a02078d03310138000a02078e03310138000a02078f03310138000a02079003310138000a02079103310138000a02079203310138000a02079303310138000a02079403310138000a02079503310138000a02079603310138000a02079703310138000a02079803310138000a02079903310138000a02079a03310138000a02079b03310138000a02079c03310138000a02079d03310138000a02079e03310138000a02079f03310138000a0207a003310138000a0207a103310138000a0207a203310138000a0207a303310138000a0207a403310138000a0207a503310138000a0207a603310138000a0207a703310138000a0207a803310138000a0207a903310138000a0207aa03310138000a0207ab03310138000a0207ac03310138000a0207ad03310138000a0207ae03310138000a0207af03310138000a0207b003310138000a0207b103310138000a0207b203310138000a0207b303310138000a0207b403310138000a0207b503310138000a0207b603310138000a0207b703310138000a0207b803310138000a0207b903310138000a0207ba03310138000a0207bb03310138000a0207bc03310138000a0207bd03310138000a0207be03310138000a0207bf03310138000a0207c003310138000a0207c103310138000a0207c203310138000a0207c303310138000a0207c403310138000a0207c503310138000a0207c603310138000a0207c703310138000a0207c803310138000a0207c903310138000a0207ca03310138000a0207cb03310138000a0207cc03310138000a0207cd03310138000a0207ce03310138000a0207cf03310138000a0207d003310138000a0207d103310138000a0207d203310138000a0207d303310138000a0207d403310138000a0207d503310138000a0207d603310138000a0207d703310138000a0207d803310138000a0207d903310138000a0207da03310138000a0207db03310138000a0207dc03310138000a0207dd03310138000a0207de03310138000a0207df03310138000a0207e003310138000a0207e103310138000a0207e203310138000a0207e303310138000a0207e403310138000a0207e503310138000a0207e603310138000a0207e703310138000a0207e803310138000a0207e903310138000a0207ea03310138000a0207eb03310138000a0207ec03310138000a0207ed03310138000a0207ee03310138000a0207ef03310138000a0207f003310138000a0207f103310138000a0207f203310138000a0207f303310138000a0207f403310138000a0207f503310138000a0207f603310138000a0207f703310138000a0207f803310138000a0207f903310138000a0207fa03310138000a0207fb03310138000a0207fc03310138000a0207fd03310138000a0207fe03310138000a0207ff03310138000a02078004310138000a02078104310138000a02078204310138000a02078304310138000a02078404310138000a02078504310138000a02078604310138000a02078704310138000a02078804310138000a02078904310138000a02078a04310138000a02078b04310138000a02078c04310138000a02078d04310138000a02078e04310138000a02078f04310138000a02079004310138000a02079104310138000a02079204310138000a02079304310138000a02079404310138000a02079504310138000a02079604310138000a02079704310138000a02079804310138000a02079904310138000a02079a04310138000a02079b04310138000a02079c04310138000a02079d04310138000a02079e04310138000a02079f04310138000a0207a004310138000a0207a104310138000a0207a204310138000a0207a304310138000a0207a404310138000a0207a504310138000a0207a604310138000a0207a704310138000a0207a804310138000a0207a904310138000a0207aa04310138000a0207ab04310138000a0207ac04310138000a0207ad04310138000a0207ae04310138000a0207af04310138000a0207b004310138000a0207b104310138000a0207b204310138000a0207b304310138000a0207b404310138000a0207b504310138000a0207b604310138000a0207b704310138000a0207b804310138000a0207b904310138000a0207ba04310138000a0207bb04310138000a0207bc04310138000a0207bd04310138000a0207be04310138000a0207bf04310138000a0207c004310138000a0207c104310138000a0207c204310138000a0207c304310138000a0207c404310138000a0207c504310138000a0207c604310138000a0207c704310138000a0207c804310138000a0207c904310138000a0207ca04310138000a0207cb04310138000a0207cc04310138000a0207cd04310138000a0207ce04310138000a0207cf04310138000a0207d004310138000a0207d104310138000a0207d204310138000a0207d304310138000a0207d404310138000a0207d504310138000a0207d604310138000a0207d704310138000a0207d804310138000a0207d904310138000a0207da04310138000a0207db04310138000a0207dc04310138000a0207dd04310138000a0207de04310138000a0207df04310138000a0207e004310138000a0207e104310138000a0207e204310138000a0207e304310138000a0207e404310138000a0207e504310138000a0207e604310138000a0207e704310138000a0207e804310138000a0207e904310138000a0207ea04310138000a0207eb04310138000a0207ec04310138000a0207ed04310138000a0207ee04310138000a0207ef04310138000a0207f004310138000a0207f104310138000a0207f204310138000a0207f304310138000a0207f404310138000a0207f504310138000a0207f604310138000a0207f704310138000a0207f804310138000a0207f904310138000a0207fa04310138000a0207fb04310138000a0207fc04310138000a0207fd04310138000a0207fe04310138000a0207ff04310138000a02078005310138000a02078105310138000a02078205310138000a02078305310138000a02078405310138000a02078505310138000a02078605310138000a02078705310138000a02078805310138000a02078905310138000a02078a05310138000a02078b05310138000a02078c05310138000a02078d05310138000a02078e05310138000a02078f05310138000a02079005310138000a02079105310138000a02079205310138000a02079305310138000a02079405310138000a02079505310138000a02079605310138000a02079705310138000a02079805310138000a02079905310138000a02079a05310138000a02079b05310138000a02079c05310138000a02079d05310138000a02079e05310138000a02079f05310138000a0207a005310138000a0207a105310138000a0207a205310138000a0207a305310138000a0207a405310138000a0207a505310138000a0207a605310138000a0207a705310138000a0207a805310138000a0207a905310138000a0207aa05310138000a0207ab05310138000a0207ac05310138000a0207ad05310138000a0207ae05310138000a0207af05310138000a0207b005310138000a0207b105310138000a0207b205310138000a0207b305310138000a0207b405310138000a0207b505310138000a0207b605310138000a0207b705310138000a0207b805310138000a0207b905310138000a0207ba05310138000a0207bb05310138000a0207bc05310138000a0207bd05310138000a0207be05310138000a0207bf05310138000a0207c005310138000a0207c105310138000a0207c205310138000a0207c305310138000a0207c405310138000a0207c505310138000a0207c605310138000a0207c705310138000a0207c805310138000a0207c905310138000a0207ca05310138000a0207cb05310138000a0207cc05310138000a0207cd05310138000a0207ce05310138000a0207cf05310138000a0207d005310138000a0207d105310138000a0207d205310138000a0207d305310138000a0207d405310138000a0207d505310138000a0207d605310138000a0207d705310138000a0207d805310138000a0207d905310138000a0207da05310138000a0207db05310138000a0207dc05310138000a0207dd05310138000a0207de05310138000a0207df05310138000a0207e005310138000a0207e105310138000a0207e205310138000a0207e305310138000a0207e405310138000a0207e505310138000a0207e605310138000a0207e705310138000a0207e805310138000a0207e905310138000a0207ea05310138000a0207eb05310138000a0207ec05310138000a0207ed05310138000a0207ee05310138000a0207ef05310138000a0207f005310138000a0207f105310138000a0207f205310138000a0207f305310138000a0207f405310138000a0207f505310138000a0207f605310138000a0207f705310138000a0207f805310138000a0207f905310138000a0207fa05310138000a0207fb05310138000a0207fc05310138000a0207fd05310138000a0207fe05310138000a0207ff05310138000a02078006310138000a02078106310138000a02078206310138000a02078306310138000a02078406310138000a02078506310138000a02078606310138000a02078706310138000a02078806310138000a02078906310138000a02078a06310138000a02078b06310138000a02078c06310138000a02078d06310138000a02078e06310138000a02078f06310138000a02079006310138000a02079106310138000a02079206310138000a02079306310138000a02079406310138000a02079506310138000a02079606310138000a02079706310138000a02079806310138000a02079906310138000a02079a06310138000a02079b06310138000a02079c06310138000a02079d06310138000a02079e06310138000a02079f06310138000a0207a006310138000a0207a106310138000a0207a206310138000a0207a306310138000a0207a406310138000a0207a506310138000a0207a606310138000a0207a706310138000a0207a806310138000a0207a906310138000a0207aa06310138000a0207ab06310138000a0207ac06310138000a0207ad06310138000a0207ae06310138000a0207af06310138000a0207b006310138000a0207b106310138000a0207b206310138000a0207b306310138000a0207b406310138000a0207b506310138000a0207b606310138000a0207b706310138000a0207b806310138000a0207b906310138000a0207ba06310138000a0207bb06310138000a0207bc06310138000a0207bd06310138000a0207be06310138000a0207bf06310138000a0207c006310138000a0207c106310138000a0207c206310138000a0207c306310138000a0207c406310138000a0207c506310138000a0207c606310138000a0207c706310138000a0207c806310138000a0207c906310138000a0207ca06310138000a0207cb06310138000a0207cc06310138000a0207cd06310138000a0207ce06310138000a0207cf06310138000a0207d006310138000a0207d106310138000a0207d206310138000a0207d306310138000a0207d406310138000a0207d506310138000a0207d606310138000a0207d706310138000a0207d806310138000a0207d906310138000a0207da06310138000a0207db06310138000a0207dc06310138000a0207dd06310138000a0207de06310138000a0207df06310138000a0207e006310138000a0207e106310138000a0207e206310138000a0207e306310138000a0207e406310138000a0207e506310138000a0207e606310138000a0207e706310138000a0207e806310138000a0207e906310138000a0207ea06310138000a0207eb06310138000a0207ec06310138000a0207ed06310138000a0207ee06310138000a0207ef06310138000a0207f006310138000a0207f106310138000a0207f206310138000a0207f306310138000a0207f406310138000a0207f506310138000a0207f606310138000a0207f706310138000a0207f806310138000a0207f906310138000a0207fa06310138000a0207fb06310138000a0207fc06310138000a0207fd06310138000a0207fe06310138000a0207ff06310138000a02078007310138000a02078107310138000a02078207310138000a02078307310138000a02078407310138000a02078507310138000a02078607310138000a02078707310138000a02078807310138000a02078907310138000a02078a07310138000a02078b07310138000a02078c07310138000a02078d07310138000a02078e07310138000a02078f07310138000a02079007310138000a02079107310138000a02079207310138000a02079307310138000a02079407310138000a02079507310138000a02079607310138000a02079707310138000a02079807310138000a02079907310138000a02079a07310138000a02079b07310138000a02079c07310138000a02079d07310138000a02079e07310138000a02079f07310138000a0207a007310138000a0207a107310138000a0207a207310138000a0207a307310138000a0207a407310138000a0207a507310138000a0207a607310138000a0207a707310138000a0207a807310138000a0207a907310138000a0207aa07310138000a0207ab07310138000a0207ac07310138000a0207ad07310138000a0207ae07310138000a0207af07310138000a0207b007310138000a0207b107310138000a0207b207310138000a0207b307310138000a0207b407310138000a0207b507310138000a0207b607310138000a0207b707310138000a0207b807310138000a0207b907310138000a0207ba07310138000a0207bb07310138000a0207bc07310138000a0207bd07310138000a0207be07310138000a0207bf07310138000a0207c007310138000a0207c107310138000a0207c207310138000a0207c307310138000a0207c407310138000a0207c507310138000a0207c607310138000a0207c707310138000a0207c807310138000a0207c907310138000a0207ca07310138000a0207cb07310138000a0207cc07310138000a0207cd07310138000a0207ce07310138000a0207cf07310138000a0207d007310138000a0207d107310138000a0207d207310138000a0207d307310138000a0207d407310138000a0207d507310138000a0207d607310138000a0207d707310138000a0207d807310138000a0207d907310138000a0207da07310138000a0207db07310138000a0207dc07310138000a0207dd07310138000a0207de07310138000a0207df07310138000a0207e007310138000a0207e107310138000a0207e207310138000a0207e307310138000a0207e407310138000a0207e507310138000a0207e607310138000a0207e707310138000a0207e807310138000a0207e907310138000a0207ea07310138000b0207eb0731013800020201000100090807032b000c010b0110000b00380102030100000b1f38020c010d0107ec07310138000d0107ed07310138000d0107ee07310138000d0107ef07310138000d01071a310138000d01071b310138000b000b0112002d00020401040100051c0b0011050c020b02070321030907012707032900030e0701270a011102031307022707032a000c030b030f000b0138030102000000"; - let res = run_binary_test("sample_whitelist", code); - assert!(res.is_ok(), "{:?}", res) -} - -#[test] -fn sample_coin_store() { - let code = "a11ceb0b050000000e01001e021e0c032acb0604f5065405c907a41207ed19e80908d523800206d5252c108126420ac326090bcc26040cd026fd86010dcdad01020ecfad01040000010101020103020402050306030704080509050a0607060b070c070d000e08010001011104010001000f00010200000010010201000012030101000013040103000000001404010300000000150401030000000016040103000000001704010300000000180401030000000019040103000000001a040103000000001b040103000000001c040103000000001d040103000000001e040103000000001f0401030000000020040103000000002104010300000000220401030000000023040103000000002404010300000000250401030000000026040103000000002704010300000000280401030000000029040103000000002a040103000000002b040103000000002c040103000000002d040103000000002e040103000000002f0401030000000030040103000000003104010300000000320401030000000033050103000000003405010300000000350501030000000036050103000000003705010300000000380501030000000039050103000000003a050103000000003b050103000000003c050103000000003d050103000000003e050103000000003f0501030000000040050103000000004105010300000000420501030000000043050103000000004405010300000000450501030000000046050103000000004705010300000000480501030000000049050103000000004a050103000000004b050103000000004c050103000000004d050103000000004e050103000000004f050103000000005005010300000000510601010000520701010000530801010000540901020000005509010200000056000102000000570a010200000058070102000000590a01020000005a0b01020000005b0001020000005c0c0103000000005d0c01020000005e0c01020000005f0701010000600701010000610201010000620701010000630d01010000640e010100006502030100006601030100006702030100016810020100016911010100096a0114020000046b0100020000016c16030100016d01030100090b1819020000040b1a1b020000016e030101000c6f011d0200000b70031e020000066b0100030000000771221e030000000872010202000008730102020000087424000200000e6a01140200000d0b261e020000037508400002760202000165070301000477014200057801430200000a790100020000060b1a1b03000000011226010100017a48030100580f590f5a135a155b135c0f5d175e135e1559175d0f5f155f136017611361156215600f6320632164216513661366156515671568136815691562136420671369136c0f6e136f135c17702070215817710f720f020303000103010b010109000d030403040404010101010404040d0304030404010101010404040402060c0b0101090002060c0301060c0b030403040404010104040403060c030304060c0303010a060c03040403030404010102050303060c050301090001060b0101090002070b010109000b01010900230b010109000b010109010403040b010109000403040404040b010109010403030304040b010109000b010109000b01010901070b00010900040404040b010109000b010109000b0101090104040b0101090104040209000901020404020901090002070b0101090003010901040b01010900040b0101090104040b010109000b010109010b010109000b01010901040b01010900030b0101090103020b010109000b01010901250303030403040b010109000403040404040b0101090103030304040b010109000b010109010b01010900070b000109000404040b010109000b0101090003040404030b0101090104030403030303010b0101090122040303040b010109000403040404040b0101090103030304040b010109000b010109000b01010901070b000109000404040b0101090003040b010109000404030b0101090104040309000901090203090109000902020b010109000323040404040b010109000403040404040b0101090103030304040b010109000b010109000b01010901070b000109000404050b01010900040b010109000b01010901040b0101090004040b0101090104040805070b01010900070b01010901030301040423040404040b010109000403040404040b0101090103030304040b010109000b010109010b01010900070b00010900040405040b0101090004040b010109000404040b01010901040402050b01010900240403040403040404040403030304040b010109000b010109010b01010900070b000109000b0101090104040504040b010109010b010109000b01010900040b01010900040b010109010b0101090104040b01010900200303030403030404030404040403030304040b010109000b010109010b01010900070b000109000b010109010404030b01010900040303040b010109001d040303030404030404040403030304040b010109000b010109010b01010900070b000109000b01010901040403040b0101090003040b010109001e040404030404030404040403030304040b010109000b010109010b01010900070b000109000b010109010404050b01010900040b010109000b01010901040b010109001e040404030404030404040403030304040b010109000b010109010b01010900070b000109000b0101090104040504040b0101090004040b010109002603030304030403040404040403030304040b010109010b01010900070b00010900040405030b010109000b0101090104040b01010900040b01010900030b01010901040b01010901040304200303030b010109000b010109010403030403040404040403030304040b010109010b01010900070b000109000404030b010109000b01010901040303041d0303030403030304030404040403030304040b01010900070b0001090004040303040303030421030303040404030404030404040403030304040b010109010b01010900070b000109000404050b01010900030b010109000b01010901040303041f0303030404040304030404040403030304040b010109010b01010900070b0001090004040503040403040304230403030403040404040403030304040b010109000b01010901070b0001090004040503040b01010901040b010109000b01010900040b01010900030b01010901040b0101090104041d0b010109000b01010901040303030403040404040403030304040b010109000b01010901070b00010900040403040b010109000b0101090103041e04040403030404030404040403030304040b010109000b01010901070b000109000404050b0101090003040b010109000b0101090103041c040404030304030404040403030304040b010109000b01010901070b00010900040405030404030404240404040403040404040403030304040b010109000b010109000b01010901070b000109000404050b01010901040b01010901040b010109010b010109000b01010900040b01010900040b010109010b0101090104041f04040b010109000b0101090104030403040404040403030304040b010109000b010109000b01010901070b000109000404050b01010901040b010109010b010109000b0101090104200404030303040304030404040403030304040b010109000b01010900070b000109000404050b01010901030b010109010b01010900040303041d040404030304030404040403030304040b010109000b01010900070b000109000404050b0101090103040b010109010b0101090003041e040404040404030404040403030304040b010109000b010109010b01010900070b000109000404050b01010901040b01010900040b010109010404240404040403040404040403030304040b010109000b010109000b01010901070b00010900040405040b010109000b0101090104040b01010900040b01010900040b01010901040b0101090104041f04040b010109000b0101090104030403040404040403030304040b010109000b010109000b01010901070b0001090004040504040b010109000b0101090104041f0404030303040304030404040403030304040b010109000b01010900070b00010900040405040304040303041c040404030304030404040403030304040b010109000b01010900070b000109000404050403040403041f04040404040404030404040403030304040b010109000b010109000b01010901070b000109000404050b01010900040b010109000b01010901040404010b0001090001050d05030403070b000109000b01010901040b01010900040303030b01010900040302010101011a0504040404070b00010900070b000109010404030303030b01010901040404040b010109000b010109000b010109000b010109000b010109010b010109010b010109010b010109010f03030305040404030b010109010b01010901040b0101090003030b010109000e04040305040404030b010109000b01010901040b010109010b010109010b010109000f030303030305040404030b010109010403030301070b01010900030b0101090003070b000109000a636f696e5f73746f726504636f696e056572726f72067369676e65720f416e696d6553776170506f6f6c563116416e696d6553776170506f6f6c56314c6962726172790e6c69717569646974795f706f6f6c06726f7574657203616d6d09546f6b656e537761700f546f6b656e53776170436f6e66696704737761700a616d6d5f726f7574657208616d6d5f737761700b4d79436f696e53746f726512616e696d65737761705f73746172737761700762616c616e636504436f696e076465706f736974066c3073307431066c3073317430066c3173307431066c3173307432066c3173307433066c3173307434066c3173307435066c3173317430066c3173317432066c3173317433066c3173317434066c3173317435066c3173327430066c3173327431066c3173327433066c3173327434066c3173327435066c3173337430066c3173337431066c3173337432066c3173337434066c3173337435066c3173347430066c3173347431066c3173347432066c3173347433066c3173347435066c3173357430066c3173357431066c3173357432066c3173357433066c3173357434066c3273307431066c3273307432066c3273307433066c3273307434066c3273307435066c3273317430066c3273317432066c3273317433066c3273317434066c3273317435066c3273327430066c3273327431066c3273327433066c3273327434066c3273327435066c3273337430066c3273337431066c3273337432066c3273337434066c3273337435066c3273347430066c3273347431066c3273347432066c3273347433066c3273347435066c3273357430066c3273357431066c3273357432066c3273357433066c3273357434036e65770d6e65775f66726f6d5f6d61696e0d6e65775f66726f6d5f7a65726f047330743104733174301073696d706c655f616e696d65737761701373696d706c655f616e696d65737761705f76320f73696d706c655f73746172737761701273696d706c655f73746172737761705f76321273696d706c655f73746172737761705f76331273746172737761705f616e696d657377617012737761705f61625f6c69717569647377617008737761705f61757810737761705f70616e63616b6573776170127472616e736665725f66726f6d5f6d61696e197472616e736665725f66726f6d5f6d61696e5f736372697074107472616e736665725f746f5f6d61696e177472616e736665725f746f5f6d61696e5f736372697074117472616e736665725f746f5f6f74686572187472616e736665725f746f5f6f746865725f7363726970740877697468647261770c77697468647261775f616c6c0c77697468647261775f616e790576616c7565056d657267650c6765745f7265736572766573116765745f72657365727665735f73697a650765787472616374047a65726f0c64657374726f795f7a65726f0e746f6b656e5f726573657276657321737761705f65786163745f785f746f5f795f6469726563745f65787465726e616c18737761705f65786163745f636f696e5f666f725f636f696e04785f617504795f61751c737761705f65786163745f636f696e5f666f725f636f696e5f6d75740a616464726573735f6f66117065726d697373696f6e5f64656e6965640e6765745f61646d696e5f6461746107636f6d70617265116765745f706f756e646167655f726174650b657874726163745f616c6cd1b58e44ea11ffd326a280c453b080fd8af294298815a00e65b6e2bffc48d6ac000000000000000000000000000000000000000000000000000000000000000116fe2df00ea7dde4a63409201f7f4e536bde7bb7335526a35d05111e68aa322c190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12bd35135844473187163ca197ca93b2ab014370587bb0ed3befff9e902d6bb541c755e4c8d7a6ab6d56f9289d97c43c1c94bde75ec09147c90d35cd1be61c8fb9c7efb4076dbe143cbcd98cfaaa929ecfc8f299203dfff63b95ccb6bfe19850faec42a352cc65eca17a9fa85d0fc602295897ed6b8b8af6a6c79ef490eb8f9eba0308915f0100000000000520d1b58e44ea11ffd326a280c453b080fd8af294298815a00e65b6e2bffc48d6ac126170746f733a3a6d657461646174615f76302e01915f010000000000234552524f525f5448455f4f55545055545f4c4553535f5448414e5f4d494e5f5245435600000201010b01010900000f001700010400010206ffffffffffffffff270101000100010507013c0037003800020201000100010607013c0036000b0038010203010400010206ffffffffffffffff2704010400010206ffffffffffffffff2705010400010206ffffffffffffffff2706010400010206ffffffffffffffff2707010400010206ffffffffffffffff2708010400010206ffffffffffffffff2709010400010206ffffffffffffffff270a010400010206ffffffffffffffff270b010400010206ffffffffffffffff270c010400010206ffffffffffffffff270d010400010206ffffffffffffffff270e010400010206ffffffffffffffff270f010400010206ffffffffffffffff2710010400010206ffffffffffffffff2711010400010206ffffffffffffffff2712010400010206ffffffffffffffff2713010400010206ffffffffffffffff2714010400010206ffffffffffffffff2715010400010206ffffffffffffffff2716010400010206ffffffffffffffff2717010400010206ffffffffffffffff2718010400010206ffffffffffffffff2719010400010206ffffffffffffffff271a010400010206ffffffffffffffff271b010400010206ffffffffffffffff271c010400010206ffffffffffffffff271d010400010206ffffffffffffffff271e010400010206ffffffffffffffff271f010400010206ffffffffffffffff2720010400010206ffffffffffffffff2721010400010206ffffffffffffffff2722010400010206ffffffffffffffff27230104010012f1010b05040638020c2c0c26050d38030c2b0c2e0b2b0c260b2e0c2c0b260b2c0c180c1738040c10350b10350c1f0c1e0a0432000000000000000000000000000000002104660a180a0c180a0a1a0a1f160c110a170a1f180a111a0c0f0a1e0a18180a0c180a0a1a0b111a0c110a0f0a11180a0b180a091a0c2f0a0f0a11180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2f23045e054d0a270c2f0a0f0a11180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705480b2f0b0f170a0b180a091a0c040a040b0b180c150b170b09180a15160c240b150b18180b241a320b000000000000000000000000000000170c130a130b0c180c160b1f0b0a180a16160c250b160b1e180b251a320b000000000000000000000000000000170c1a0a1a0a04170b0317010b04340c1407013c000c230a23370038000c1b0a2336000b1438050c200b0804ab010b200b133806320000000000000000000000000000000038070c190c120c2d0c2805b401380632000000000000000000000000000000000b200b1338080c120c190c280c2d0d280b1238010d2d0b1938090b2d0c220a2336000b283801380a0c290b0704cd010b220600000000000000000b290b1a34380b0c0d0c0e05d5010b290b1a340b22060000000000000000380c0c0e0c0d0b0e0b0d0c210c2a0a2336000b2138010b1b0b02160c1c0b23370038000c1d0a1d0a1c2404ea0105ee010b1c0b1d17270b2a380d0224010401001cef010b05040638020c2c0c26050d38030c2b0c2f0b2b0c260b2f0c2c0b260b2c0c190c180b060418380e0c0f0c0e0c0d0522380f0c300c290c2d0b290b2d0b300c0f0c0e0c0d0b0d0b0e0b0f010c11350b11350c1f0c1e0a04320000000000000000000000000000000021047a0a190a0c180a0a1a0a1f160c120a180a1f180a121a0c100a1e0a19180a0c180a0a1a0b121a0c120a100a12180a0b180a091a0c310a100a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c2a0a2a0a3123047205610a2a0c310a100a12180a0b180a091a0a2a1a0b2a1632020000000000000000000000000000001a0c2a055c0b310b10170a0b180a091a0c040a040b0b180c160b180b09180a16160c240b160b19180b241a320b000000000000000000000000000000170c140a140b0c180c170b1f0b0a180a17160c250b170b1e180b251a320b000000000000000000000000000000170a04170b0317010b04340c1507013c000c230a23370038000c1b0a2336000b1538050c200b0804bd010b200b143806320000000000000000000000000000000038070c1a0c130c2e0c2705c601380632000000000000000000000000000000000b200b1438080c130c1a0c270c2e0d270b1338010d2e0b1a38090b2e0c210a2336000b273801380a0c280b2138100c220a2336000b2238010b1b0b02160c1c0b23370038000c1d0a1d0a1c2404e80105ec010b1c0b1d17270b2838110225010401001fe8010b05040638020c2a0c24050d38030c290c2d0b290c240b2d0c2a0b240b2a0c170c160b06041738120c0f0c0e051e38130c260c2b0b260c0e0b2b0c0f0b0e350b0f350c1d0c1c0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1d160c100a160a1d180a101a0c0d0a1c0a17180a0c180a0a1a0b101a0c100a0d0a10180a0b180a091a0c2e0a0d0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2e23046a05590a270c2e0a0d0a10180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705540b2e0b0d170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1d0b0a180a15160c230b150b1c180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307013c000c210a21370038000c190a2136000b1338050c1e0b0804b5010b1e0b123806320000000000000000000000000000000038070c180c110c2c0c2805be01380632000000000000000000000000000000000b1e0b1238080c110c180c280c2c0d280b1138010d2c0b1838090b2c0c200a2136000b283801380a0c250b2006000000000000000038140c1f0a2136000b1f38010b190b02160c1a0b21370038000c1b0a1b0a1a2404e10105e5010b1a0b1b17270b25381102260104010023f8010b05040638020c2c0c26050d38030c2b0c2e0b2b0c260b2e0c2c0b260b2c0c170c160b06041a3815353816350c0e0c0d05203817353818350c0e0c0d0b0d0b0e0c1d0c1c0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1d160c100a160a1d180a101a0c0f0a1c0a17180a0c180a0a1a0b101a0c100a0f0a10180a0b180a091a0c2f0a0f0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c290a290a2f23046a05590a290c2f0a0f0a10180a0b180a091a0a291a0b291632020000000000000000000000000000001a0c2905540b2f0b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1d0b0a180a15160c230b150b1c180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307010c240a243c000c210a21370038000c190a2136000b1338050c1e0b0804b7010b1e0a123806320000000000000000000000000000000038070c180c110c2d0c2a05c001380632000000000000000000000000000000000b1e0a1238080c110c180c2a0c2d0d2a0b1138010d2d0b1838090b2d0c200a2136000b2a3801380a0c270b240d200d270b12340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b270c250b200c280b250c1f0a2136000b1f38010b190b02160c1a0b21370038000c1b0a1b0a1a2404f10105f5010b1a0b1b17270b28380d02270104010025e8010b05040638020c2b0c25050d38030c2a0c2e0b2a0c250b2e0c2b0b250b2b0c170c160b060417381a0c0e0c0d051e381b0c270c2c0b270b2c0c0e0c0d0b0d0b0e0c1d0c1c0a0432000000000000000000000000000000002104700a170a0c180a0a1a0a1d160c100a160a1d180a101a0c0f0a1c0a17180a0c180a0a1a0b101a0c100a0f0a10180a0b180a091a0c2f0a0f0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c280a280a2f23046805570a280c2f0a0f0a10180a0b180a091a0a281a0b281632020000000000000000000000000000001a0c2805520b2f0b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1d0b0a180a15160c230b150b1c180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307010c240a243c000c210a21370038000c190a2136000b1338050c1e0b0804b5010b1e0b123806320000000000000000000000000000000038070c180c110c2d0c2905be01380632000000000000000000000000000000000b1e0b1238080c110c180c290c2d0d290b1138010d2d0b1838090b2d0c1f0a2136000b293801380a0c260b240b1f381c0c200a2136000b2038010b190b02160c1a0b21370038000c1b0a1b0a1a2404e10105e5010b1a0b1b17270b26381102280104010027f20138040c0e350b0e350c150c140b06040d38020c2b0c24051438030c290c2e0b290c240b2e0c2b0b240b2b0c1b0c1a0a0432000000000000000000000000000000002104660a150a0c180a0a1a0a1b160c0f0a140a1b180a0f1a0c0d0a1a0a15180a0c180a0a1a0b0f1a0c0f0a0d0a0f180a0b180a091a0c2f0a0d0a0f180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2f23045e054d0a250c2f0a0d0a0f180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505480b2f0b0d170a0b180a091a0c040a040b0b180c120b140b09180a12160c210b120b15180b211a320b000000000000000000000000000000170c100a100b0c180c130b1b0b0a180a13160c220b130b1a180b221a320b000000000000000000000000000000170c160a160a04170b0317010b04340c1107010c230a233c000c1f0a1f370038000c170a1f36000b1138050c1c0b0804ac010b1c06000000000000000038060b1034380c0c200c3005b40138060b10340b1c060000000000000000380b0c300c200b300b200c1d0c270b0704c4010b1d0b160b27320000000000000000000000000000000038080c280c2d0c2a0c2c05cd010b2732000000000000000000000000000000000b1d0b1638070c2d0c280c2c0c2a0d2a0b2838010d2c0b2d38090b2a0c1e0b2c0c260a1f36000b1e38010b170b02160c180b1f370038000c190a190a182404e80105ec010b180b1917270b233c0136010b26380902290104010028d90138040c11350b11350c190c180b06040e380e0c0f0c0e0c0d0518380f0c2a0c260c290b260b290b2a0c0f0c0e0c0d0b0d0b0e0b0f010c12350b12350c1e0c1d0a0432000000000000000000000000000000002104700a190a0c180a0a1a0a1e160c130a180a1e180a131a0c100a1d0a19180a0c180a0a1a0b131a0c130a100a13180a0b180a091a0c2b0a100a13180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c280a280a2b23046805570a280c2b0a100a13180a0b180a091a0a281a0b281632020000000000000000000000000000001a0c2805520b2b0b10170a0b180a091a0c040a040b0b180c160b180b09180a16160c240b160b19180b241a320b000000000000000000000000000000170c140a140b0c180c170b1e0b0a180a17160c250b170b1d180b251a320b000000000000000000000000000000170a04170b0317010b04340c1507013c000c220a22370038000c1a0a2236000b1538050c1f0b0804b2010b1f06000000000000000038060b1434380c0c230c2c05ba0138060b14340b1f060000000000000000380b0c2c0c230b2c0b230c200c270b2038100c210a2236000b2138010b1a0b02160c1b0b22370038000c1c0a1c0a1b2404d20105d6010b1b0b1c17270b273811022a0104010029d20138040c0f350b0f350c170c160b06040d38120c100c0e051438130c240c270b240c0e0b270c100b0e350b10350c1c0c1b0a0432000000000000000000000000000000002104680a170a0c180a0a1a0a1c160c110a160a1c180a111a0c0d0a1b0a17180a0c180a0a1a0b111a0c110a0d0a11180a0b180a091a0c280a0d0a11180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a28230460054f0a250c280a0d0a11180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c25054a0b280b0d170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1c0b0a180a15160c230b150b1b180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307013c000c200a20370038000c180a2036000b1338050c1d0b0804aa010b1d06000000000000000038060b1234380c0c210c2905b20138060b12340b1d060000000000000000380b0c290c210b290b210c1e0c260b1e06000000000000000038140c1f0a2036000b1f38010b180b02160c190b20370038000c1a0a1a0a192404cb0105cf010b190b1a17270b263811022b010401002ae20138040c10350b10350c170c160b0604103815353816350c0e0c0d05163817353818350c0e0c0d0b0d0b0e0c1c0c1b0a0432000000000000000000000000000000002104680a170a0c180a0a1a0a1c160c110a160a1c180a111a0c0f0a1b0a17180a0c180a0a1a0b111a0c110a0f0a11180a0b180a091a0c290a0f0a11180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c260a260a29230460054f0a260c290a0f0a11180a0b180a091a0a261a0b261632020000000000000000000000000000001a0c26054a0b290b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1c0b0a180a15160c230b150b1b180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307010c240a243c000c200a20370038000c180a2036000b1338050c1d0b0804ac010b1d06000000000000000038060a1234380c0c210c2a05b40138060a12340b1d060000000000000000380b0c2a0c210b2a0b210c1e0c270b240d1e0d270b12340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b270c250b1e0c280b250c1f0a2036000b1f38010b180b02160c190b20370038000c1a0a1a0a192404db0105df010b190b1a17270b28380d022c010401002bd20138040c10350b10350c170c160b06040d381a0c0e0c0d0514381b0c250c280b250b280c0e0c0d0b0d0b0e0c1c0c1b0a0432000000000000000000000000000000002104660a170a0c180a0a1a0a1c160c110a160a1c180a111a0c0f0a1b0a17180a0c180a0a1a0b111a0c110a0f0a11180a0b180a091a0c290a0f0a11180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c260a260a2923045e054d0a260c290a0f0a11180a0b180a091a0a261a0b261632020000000000000000000000000000001a0c2605480b290b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c220b140b17180b221a320b000000000000000000000000000000170c120a120b0c180c150b1c0b0a180a15160c230b150b1b180b231a320b000000000000000000000000000000170a04170b0317010b04340c1307010c240a243c000c200a20370038000c180a2036000b1338050c1d0b0804aa010b1d06000000000000000038060b1234380c0c210c2a05b20138060b12340b1d060000000000000000380b0c2a0c210b2a0b210c1e0c270b240b1e381c0c1f0a2036000b1f38010b180b02160c190b20370038000c1a0a1a0a192404cb0105cf010b190b1a17270b273811022d010401002cec010b050407380e0c0f0c0e0c0d0511380f0c310c240c2c0b240b2c0b310c0f0c0e0c0d0b0d0b0e0b0f010c11350b11350c170c160b06042138020c2e0c27052838030c2a0c300b2a0c270b300c2e0b270b2e0c1d0c1c0a04320000000000000000000000000000000021047a0a170a0c180a0a1a0a1d160c120a160a1d180a121a0c100a1c0a17180a0c180a0a1a0b121a0c120a100a12180a0b180a091a0c320a100a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c280a280a3223047205610a280c320a100a12180a0b180a091a0a281a0b281632020000000000000000000000000000001a0c28055c0b320b10170a0b180a091a0c040a040b0b180c140b160b09180a14160c210b140b17180b211a0b0c180c150b1d0b0a180a15160c220b150b1c180b221a0c180a180a04170b0317010b04340c1307010c230a233c000c200a20370038000c190a2036000b133805381d0c1e380a0c250b0704be010b1e0b180b25320000000000000000000000000000000038080c290c2f0c2b0c2d05c7010b2532000000000000000000000000000000000b1e0b1838070c2f0c290c2d0c2b0d2b0b2938010d2d0b2f38090b2b0c1f0b2d0c260a2036000b1f38010b190b02160c1a0b20370038000c1b0a1b0a1a2404e20105e6010b1a0b1b17270b233c0136010b263809022e010401002dd5010b050407380e0c0f0c0e0c0d0511380f0c2b0c260c2a0b260b2a0b2b0c0f0c0e0c0d0b0d0b0e0b0f010c13350b13350c1a0c1938040c14350b14350c200c1f0a0432000000000000000000000000000000002104700a1a0a0c180a0a1a0a20160c150a190a20180a151a0c120a1f0a1a180a0c180a0a1a0b151a0c150a120a15180a0b180a091a0c2c0a120a15180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c290a290a2c23046805570a290c2c0a120a15180a0b180a091a0a291a0b291632020000000000000000000000000000001a0c2905520b2c0b12170a0b180a091a0c040a040b0b180c170b190b09180a17160c240b170b1a180b241a0b0c180c180b200b0a180a18160c250b180b1f180b251a0c1b0a1b0a04170b0317010b04340c1607013c000c230a23370038000c1c0a2336000b163805381d0c21380a0c270b0704b1010b210600000000000000000b270b1b34380b0c100c1105b9010b270b1b340b21060000000000000000380c0c110c100b110b100c220c280a2336000b2238010b1c0b02160c1d0b23370038000c1e0a1e0a1d2404ce0105d2010b1d0b1e17270b28380d022f010401002ec6010b050407380e0c0f0c0e0c0d0511380f0c280c230c260b230b260b280c0f0c0e0c0d0b0d0b0e0b0f010c12350b12350c190c180b06042138120c130c11052838130c240c270b240c110b270c130b11350b13350c1e0c1d0a04320000000000000000000000000000000021047c0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c100a1d0a19180a0c180a0a1a0b141a0c140a100a14180a0b180a091a0c290a100a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2923047405630a250c290a100a14180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c25055e0b290b10170a0b180a091a0c040a040b0b180c160b180b09180a16160c210b160b19180b211a0b0c180c170b1e0b0a180a17160c220b170b1d180b221a0a04170b0317010b04340c1507013c000c200a20370038000c1a0a2036000b153805381d06000000000000000038140c1f0a2036000b1f38010b1a0b02160c1b0b20370038000c1c0a1c0a1b2404c10105c5010b1b0b1c17270230010401002fde010b050407380e0c0f0c0e0c0d0511380f0c2c0c270c2b0b270b2b0b2c0c0f0c0e0c0d0b0d0b0e0b0f010c13350b13350c1a0c190b0604243815353816350c110c10052a3817353818350c110c100b100b110c1f0c1e0a04320000000000000000000000000000000021047c0a1a0a0c180a0a1a0a1f160c140a190a1f180a141a0c120a1e0a1a180a0c180a0a1a0b141a0c140a120a14180a0b180a091a0c2d0a120a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c2a0a2a0a2d23047405630a2a0c2d0a120a14180a0b180a091a0a2a1a0b2a1632020000000000000000000000000000001a0c2a055e0b2d0b12170a0b180a091a0c040a040b0b180c170b190b09180a17160c230b170b1a180b231a0c150a150b0c180c180b1f0b0a180a18160c240b180b1e180b241a0a04170b0317010b04340c1607010c250a253c000c220a22370038000c1b0a2236000b163805381d0c20380a0c280b250d200d280b15340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b280c260b200c290b260c210a2236000b2138010b1b0b02160c1c0b22370038000c1d0a1d0a1c2404d70105db010b1c0b1d17270b29380d02310104010030c8010b050407380e0c0f0c0e0c0d0511380f0c2a0c250c280b250b280b2a0c0f0c0e0c0d0b0d0b0e0b0f010c13350b13350c190c180b060421381a0c110c100528381b0c260c290b260b290c110c100b100b110c1e0c1d0a04320000000000000000000000000000000021047a0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c120a1d0a19180a0c180a0a1a0b141a0c140a120a14180a0b180a091a0c2b0a120a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2b23047205610a270c2b0a120a14180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c27055c0b2b0b12170a0b180a091a0c040a040b0b180c160b180b09180a16160c220b160b19180b221a0b0c180c170b1e0b0a180a17160c230b170b1d180b231a0a04170b0317010b04340c1507010c240a243c000c210a21370038000c1a0a2136000b153805381d0c1f0b240b1f381c0c200a2136000b2038010b1a0b02160c1b0b21370038000c1c0a1c0a1b2404c30105c7010b1b0b1c172702320104010031e5010b05040638120c0f0c0e050d38130c220c2a0b220c0e0b2a0c0f0b0e350b0f350c150c140b06041938020c2c0c23052038030c280c2e0b280c230b2e0c2c0b230b2c0c1b0c1a0a0432000000000000000000000000000000002104720a150a0c180a0a1a0a1b160c100a140a1b180a101a0c0d0a1a0a15180a0c180a0a1a0b101a0c100a0d0a10180a0b180a091a0c2f0a0d0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2f23046a05590a250c2f0a0d0a10180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505540b2f0b0d170a0b180a091a0c040a040b0b180c120b140b09180a12160c1f0b120b15180b1f1a0b0c180c130b1b0b0a180a13160c200b130b1a180b201a0c160a160a04170b0317010b04340c1107010c210a213c000c1e0a1e370038000c170a1e36000b113805060000000000000000381e0c1d380a0c260b0704b7010b1d0b160b26320000000000000000000000000000000038080c270c2d0c290c2b05c0010b2632000000000000000000000000000000000b1d0b1638070c2d0c270c2b0c290d290b2738010d2b0b2d38090b290c1c0b2b0c240a1e36000b1c38010b170b02160c180b1e370038000c190a190a182404db0105df010b180b1917270b213c0136010b24380902330104010032ce010b05040638120c110c10050d38130c240c280b240c100b280c110b10350b11350c180c1738040c12350b12350c1e0c1d0a0432000000000000000000000000000000002104680a180a0c180a0a1a0a1e160c130a170a1e180a131a0c0f0a1d0a18180a0c180a0a1a0b131a0c130a0f0a13180a0b180a091a0c290a0f0a13180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a29230460054f0a250c290a0f0a13180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c25054a0b290b0f170a0b180a091a0c040a040b0b180c150b170b09180a15160c220b150b18180b221a0b0c180c160b1e0b0a180a16160c230b160b1d180b231a0c190a190a04170b0317010b04340c1407013c000c210a21370038000c1a0a2136000b143805060000000000000000381e0c20380a0c260b0704aa010b200600000000000000000b260b1934380b0c0d0c0e05b2010b260b19340b20060000000000000000380c0c0e0c0d0b0e0b0d0c1f0c270a2136000b1f38010b1a0b02160c1b0b21370038000c1c0a1c0a1b2404c70105cb010b1b0b1c17270b27380d0234010401002ec6010b05040638120c120c11050d38130c230c260b230c110b260c120b11350b12350c190c180b06041a380e0c0f0c0e0c0d0524380f0c280c240c270b240b270b280c0f0c0e0c0d0b0d0b0e0b0f010c13350b13350c1e0c1d0a04320000000000000000000000000000000021047c0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c100a1d0a19180a0c180a0a1a0b141a0c140a100a14180a0b180a091a0c290a100a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2923047405630a250c290a100a14180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c25055e0b290b10170a0b180a091a0c040a040b0b180c160b180b09180a16160c210b160b19180b211a0b0c180c170b1e0b0a180a17160c220b170b1d180b221a0a04170b0317010b04340c1507013c000c200a20370038000c1a0a2036000b153805060000000000000000381e38100c1f0a2036000b1f38010b1a0b02160c1b0b20370038000c1c0a1c0a1b2404c10105c5010b1b0b1c172702350104010033d7010b05040638120c110c10050d38130c250c290b250c100b290c110b10350b11350c180c170b06041c3815353816350c0e0c0d05223817353818350c0e0c0d0b0d0b0e0c1d0c1c0a0432000000000000000000000000000000002104740a180a0c180a0a1a0a1d160c120a170a1d180a121a0c0f0a1c0a18180a0c180a0a1a0b121a0c120a0f0a12180a0b180a091a0c2a0a0f0a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c260a260a2a23046c055b0a260c2a0a0f0a12180a0b180a091a0a261a0b261632020000000000000000000000000000001a0c2605560b2a0b0f170a0b180a091a0c040a040b0b180c150b170b09180a15160c210b150b18180b211a0c130a130b0c180c160b1d0b0a180a16160c220b160b1c180b221a0a04170b0317010b04340c1407010c230a233c000c200a20370038000c190a2036000b143805060000000000000000381e0c1f380a0c270b230d1f0d270b13340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b270c240b1f0c280b240c1e0a2036000b1e38010b190b02160c1a0b20370038000c1b0a1b0a1a2404d00105d4010b1a0b1b17270b28380d02360104010034c1010b05040638120c110c10050d38130c230c260b230c100b260c110b10350b11350c170c160b060419381a0c0e0c0d0520381b0c240c270b240b270c0e0c0d0b0d0b0e0c1c0c1b0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1c160c120a160a1c180a121a0c0f0a1b0a17180a0c180a0a1a0b121a0c120a0f0a12180a0b180a091a0c280a0f0a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2823046a05590a250c280a0f0a12180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505540b280b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c200b140b17180b201a0b0c180c150b1c0b0a180a15160c210b150b1b180b211a0a04170b0317010b04340c1307010c220a223c000c1f0a1f370038000c180a1f36000b133805060000000000000000381e0c1e0b220b1e381c0c1d0a1f36000b1d38010b180b02160c190b1f370038000c1a0a1a0a192404bc0105c0010b190b1a172702370104010035f9010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c150c140b06041938020c2c0c24052038030c2a0c2f0b2a0c240b2f0c2c0b240b2c0c1b0c1a0a0432000000000000000000000000000000002104720a150a0c180a0a1a0a1b160c100a140a1b180a101a0c0f0a1a0a15180a0c180a0a1a0b101a0c100a0f0a10180a0b180a091a0c300a0f0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c260a260a3023046a05590a260c300a0f0a10180a0b180a091a0a261a0b261632020000000000000000000000000000001a0c2605540b300b0f170a0b180a091a0c040a040b0b180c120b140b09180a12160c200b120b15180b201a320b000000000000000000000000000000170b0c180c130b1b0b0a180a13160c210b130b1a180b211a320b000000000000000000000000000000170c160a160a04170b0317010b04340c1107010c220a223c000c1f0a1f370038000c170a1f36000a1138050c1c38060c270a220d1c0d270b11340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b270c230b1c0c280b230c1e0b0704cb010b1e0b160b28320000000000000000000000000000000038080c290c2e0c2b0c2d05d4010b2832000000000000000000000000000000000b1e0b1638070c2e0c290c2d0c2b0d2b0b2938010d2d0b2e38090b2b0c1d0b2d0c250a1f36000b1d38010b170b02160c180b1f370038000c190a190a182404ef0105f3010b180b1917270b223c0136010b25380902380104010036e4010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c180c1738040c12350b12350c1e0c1d0a0432000000000000000000000000000000002104680a180a0c180a0a1a0a1e160c130a170a1e180a131a0c110a1d0a18180a0c180a0a1a0b131a0c130a110a13180a0b180a091a0c2b0a110a13180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2b230460054f0a270c2b0a110a13180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c27054a0b2b0b11170a0b180a091a0c040a040b0b180c150b170b09180a15160c230b150b18180b231a320b000000000000000000000000000000170b0c180c160b1e0b0a180a16160c240b160b1d180b241a320b000000000000000000000000000000170c190a190a04170b0317010b04340c1407010c250a253c000c220a22370038000c1a0a2236000a1438050c1f38060c280b250d1f0d280b14340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b280c260b1f0c290b260c210b0704c0010b210600000000000000000b290b1934380b0c0f0c1005c8010b290b19340b21060000000000000000380c0c100c0f0b100b0f0c200c2a0a2236000b2038010b1a0b02160c1b0b22370038000c1c0a1c0a1b2404dd0105e1010b1b0b1c17270b2a380d02390104010037e0010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c190c180b06041a380e0c110c100c0f0524380f0c2b0c260c2a0b260b2a0b2b0c110c100c0f0b0f0b100b11010c13350b13350c1e0c1d0a04320000000000000000000000000000000021047c0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c120a1d0a19180a0c180a0a1a0b141a0c140a120a14180a0b180a091a0c2c0a120a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c290a290a2c23047405630a290c2c0a120a14180a0b180a091a0a291a0b291632020000000000000000000000000000001a0c29055e0b2c0b12170a0b180a091a0c040a040b0b180c160b180b09180a16160c220b160b19180b221a320b000000000000000000000000000000170b0c180c170b1e0b0a180a17160c230b170b1d180b231a320b000000000000000000000000000000170a04170b0317010b04340c1507010c240a243c000c210a21370038000c1a0a2136000a1538050c1f38060c270b240d1f0d270b15340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b270c250b1f0c280b2538100c200a2136000b2038010b1a0b02160c1b0b21370038000c1c0a1c0a1b2404d90105dd010b1b0b1c17270b283811023a0104010038d9010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c170c160b06041938120c110c10052038130c240c280b240c100b280c110b10350b11350c1c0c1b0a0432000000000000000000000000000000002104740a170a0c180a0a1a0a1c160c120a160a1c180a121a0c0f0a1b0a17180a0c180a0a1a0b121a0c120a0f0a12180a0b180a091a0c290a0f0a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2923046c055b0a250c290a0f0a12180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505560b290b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c200b140b17180b201a320b000000000000000000000000000000170b0c180c150b1c0b0a180a15160c210b150b1b180b211a320b000000000000000000000000000000170a04170b0317010b04340c1307010c220a223c000c1f0a1f370038000c180a1f36000a1338050c1d38060c260b220d1d0d260b13340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b260c230b1d0c270b2306000000000000000038140c1e0a1f36000b1e38010b180b02160c190b1f370038000c1a0a1a0a192404d20105d6010b190b1a17270b273811023b0104010039d9010b0504093815353816350c0e0c0d050f3817353818350c0e0c0d0b0d0b0e0c170c160b060419381a0c100c0f0520381b0c250c290b250b290c100c0f0b0f0b100c1c0c1b0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1c160c120a160a1c180a121a0c110a1b0a17180a0c180a0a1a0b121a0c120a110a12180a0b180a091a0c2a0a110a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2a23046a05590a270c2a0a110a12180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705540b2a0b11170a0b180a091a0c040a040b0b180c140b160b09180a14160c210b140b17180b211a320b000000000000000000000000000000170b0c180c150b1c0b0a180a15160c220b150b1b180b221a320b000000000000000000000000000000170a04170b0317010b04340c1307010c230a233c000c200a20370038000c180a2036000a1338050c1d38060c280a230d1d0d280b13340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b280c240b1d0c260b240c1e0b230b1e381c0c1f0a2036000b1f38010b180b02160c190b20370038000c1a0a1a0a192404d20105d6010b190b1a17270b263811023c010401003ae5010b050406381a0c0e0c0d050d381b0c230c2b0b230b2b0c0e0c0d0b0d0b0e0c150c140b06041738020c2d0c26051e38030c290c2f0b290c260b2f0c2d0b260b2d0c1b0c1a0a0432000000000000000000000000000000002104700a150a0c180a0a1a0a1b160c100a140a1b180a101a0c0f0a1a0a15180a0c180a0a1a0b101a0c100a0f0a10180a0b180a091a0c300a0f0a10180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a3023046805570a270c300a0f0a10180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705520b300b0f170a0b180a091a0c040a040b0b180c120b140b09180a12160c200b120b15180b201a0b0c180c130b1b0b0a180a13160c210b130b1a180b211a0c160a160a04170b0317010b04340c1107010c220a223c000c1f0a1f370038000c170a1f36000b1138050c1c0a220b1c38200c1e380a0c240b0704b7010b1e0b160b24320000000000000000000000000000000038080c280c2e0c2a0c2c05c0010b2432000000000000000000000000000000000b1e0b1638070c2e0c280c2c0c2a0d2a0b2838010d2c0b2e38090b2a0c1d0b2c0c250a1f36000b1d38010b170b02160c180b1f370038000c190a190a182404db0105df010b180b1917270b223c0136010b253809023d010401003bd0010b050406381a0c0e0c0d050d381b0c260c2a0b260b2a0c0e0c0d0b0d0b0e0c180c1738040c12350b12350c1e0c1d0a0432000000000000000000000000000000002104660a180a0c180a0a1a0a1e160c130a170a1e180a131a0c110a1d0a18180a0c180a0a1a0b131a0c130a110a13180a0b180a091a0c2b0a110a13180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2b23045e054d0a270c2b0a110a13180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c2705480b2b0b11170a0b180a091a0c040a040b0b180c150b170b09180a15160c230b150b18180b231a0b0c180c160b1e0b0a180a16160c240b160b1d180b241a0c190a190a04170b0317010b04340c1407010c250a253c000c220a22370038000c1a0a2236000b1438050c1f0b250b1f38200c21380a0c280b0704ac010b210600000000000000000b280b1934380b0c0f0c1005b4010b280b19340b21060000000000000000380c0c100c0f0b100b0f0c200c290a2236000b2038010b1a0b02160c1b0b22370038000c1c0a1c0a1b2404c90105cd010b1b0b1c17270b29380d023e010401003cc8010b050406381a0c0e0c0d050d381b0c250c280b250b280c0e0c0d0b0d0b0e0c190c180b060418380e0c110c100c0f0522380f0c2a0c260c290b260b290b2a0c110c100c0f0b0f0b100b11010c13350b13350c1e0c1d0a04320000000000000000000000000000000021047a0a190a0c180a0a1a0a1e160c140a180a1e180a141a0c120a1d0a19180a0c180a0a1a0b141a0c140a120a14180a0b180a091a0c2b0a120a14180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c270a270a2b23047205610a270c2b0a120a14180a0b180a091a0a271a0b271632020000000000000000000000000000001a0c27055c0b2b0b12170a0b180a091a0c040a040b0b180c160b180b09180a16160c220b160b19180b221a0b0c180c170b1e0b0a180a17160c230b170b1d180b231a0a04170b0317010b04340c1507010c240a243c000c210a21370038000c1a0a2136000b1538050c1f0b240b1f382038100c200a2136000b2038010b1a0b02160c1b0b21370038000c1c0a1c0a1b2404c30105c7010b1b0b1c1727023f010401003dc1010b050406381a0c0e0c0d050d381b0c230c260b230b260c0e0c0d0b0d0b0e0c170c160b06041738120c110c10051e38130c240c270b240c100b270c110b10350b11350c1c0c1b0a0432000000000000000000000000000000002104720a170a0c180a0a1a0a1c160c120a160a1c180a121a0c0f0a1b0a17180a0c180a0a1a0b121a0c120a0f0a12180a0b180a091a0c280a0f0a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c250a250a2823046a05590a250c280a0f0a12180a0b180a091a0a251a0b251632020000000000000000000000000000001a0c2505540b280b0f170a0b180a091a0c040a040b0b180c140b160b09180a14160c200b140b17180b201a0b0c180c150b1c0b0a180a15160c210b150b1b180b211a0a04170b0317010b04340c1307010c220a223c000c1f0a1f370038000c180a1f36000b1338050c1d0b220b1d382006000000000000000038140c1e0a1f36000b1e38010b180b02160c190b1f370038000c1a0a1a0a192404bc0105c0010b190b1a17270240010401003ed7010b050406381a0c0e0c0d050d381b0c260c2a0b260b2a0c0e0c0d0b0d0b0e0c180c170b06041a3815353816350c100c0f05203817353818350c100c0f0b0f0b100c1d0c1c0a0432000000000000000000000000000000002104720a180a0c180a0a1a0a1d160c120a170a1d180a121a0c110a1c0a18180a0c180a0a1a0b121a0c120a110a12180a0b180a091a0c2b0a110a12180a0b180a091a32020000000000000000000000000000001a3201000000000000000000000000000000160c290a290a2b23046a05590a290c2b0a110a12180a0b180a091a0a291a0b291632020000000000000000000000000000001a0c2905540b2b0b11170a0b180a091a0c040a040b0b180c150b170b09180a15160c220b150b18180b221a0c130a130b0c180c160b1d0b0a180a16160c230b160b1c180b231a0a04170b0317010b04340c1407010c240a243c000c210a21370038000c190a2136000b1438050c1e0a240b1e38200c20380a0c270b240d200d270b13340600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381901010b270c250b200c280b250c1f0a2136000b1f38010b190b02160c1a0b21370038000c1b0a1b0a1a2404d00105d4010b1a0b1b17270b28380d02410300003f070b0139000c020b000b023f0002420104003f140a00116a0701210406050b0b0001060000000000000000116b270a000b01382139000c020b000b023f0002430104003f120a00116a0701210406050b0b0001060000000000000000116b27380a39000c010b000b013f000244010400010206ffffffffffffffff2745010400010206ffffffffffffffff27460104000102060000000000000000274701040100415b0b00116a0c030a030701210408050b060000000000000000116b270a033c000c070a0736000b0138050c0a0e0a38000c04116d0101010c0e38040c0d0c0c0b04350610270000000000000b0e1735180c050a050b0d35180c0b0b0c353210270000000000000000000000000000180b05160c090b0b0b091a340c060a060b0226043c05400b07010700273822044a0b0a06000000000000000038060b06380c0c080c0f055138060b060b0a060000000000000000380b0c0f0c080b0736000b0f38010b033c0136010b0838090248010400010206000000000000000027490104000102060000000000000000274a010401004493010b00116a0c040a040701210408050b060000000000000000116b270b03044f38020c140c1238230c0d0c0f0a01350a0d0b0f1735180c050b120b0d35180a05160c0b0b050b14180b0b1a0c070a070b023524042e05300700270a043c000c090a0936000b0138050b073806320000000000000000000000000000000038070c1c0c180c1a0c160d160b1838010d1a0b1c38090b0936000b1638010b043c0136010b1a380905920138020c130c1538230c0e0c100a01350a0e0b101735180c060b130b0e35180a06160c0c0b060b15180b0c1a0c080a080b023524047005720700270a043c010c0a0a0a36010b0138240c11380a32000000000000000000000000000000000b110b0838070c1d0c190c1b0c170d170b1938010d1b0b1d38090b0a36010b1b38090b043c0036000b173801024b010400010206ffffffffffffffff274c0104010045650b00116a0c0d0a0d0701210408050b060000000000000000116b270b08041138120c0b0c0a051838130c160c170b160c0a0b170c0b0b0a350b0b350c100c0f0b030b07180c0e0b0f0b06180a0e160c140b0e0b10180b141a340c0c0a0c0a0526043405380b050b0c17270a0d3c0036000b0438050c150b0904480b1506000000000000000038060b0c38250c130c18054f38060b0c0b1506000000000000000038260c180c130b180b130c1238110e1238270c110a110a0524045b055f0b050b1117270b0d3c0136010b123809024d0104010046650b00116a0c0d0a0d0701210408050b060000000000000000116b270b0804143815353816350c0b0c0a051a3817353818350c0b0c0a0b0a0b0b0c100c0f0b030b07180c0e0b0f0b06180a0e160c140b0e0b10180b141a340c0c0a0c0a0526043405380b050b0c17270a0d3c0036000a0438050c1238060c160a0d0d120d160b040600000000000000000932000000000000000000000000000000003200000000000000000000000000000000381f01010b160c150b120c170b150c130e1338270c110a110a05240459055d0b050b1117270b0d3c0136010b1338090b173811024e0104010047590b00116a0c0f0a0f0701210408050b060000000000000000116b270b080412380e0c0c0c0b0c0a051c380f0c180c160c170b160b170b180c0c0c0b0c0a0b0a0b0b0b0c010c0d350b0d350c120c110b030b07180c100b110b06180a10160c150b100b12180b151a340c0e0a0e0a0526043c05400b050b0e17270a0f3c0036000b043805381d0c140e1438270c130a130a0524044f05530b050b1317270b0f3c0136010b143809024f03000100030a0b000b0138210c0207013c0036000b02380102500004010026170a00116a0c020a020701210408050d0b0001060000000000000000116b270b000b0138210c030b023c0036000b033801025103000100260c07010c010a013c0036000b0038050c020b010b02382802520004010026150b00116a0c020a020701210408050b060000000000000000116b270a023c0036000b0138050c030b020b033828025303000100030a07013c0036000b0138050c020b000b02382802540004010026150b00116a0c030a030701210408050b060000000000000000116b270b033c0036000b0238050c040b010b043828025503000100010607013c0036000b003805025603000100010507013c0036003829025703000100491707013c000c030a03370038000c020a000b022404110b0336000b0038050c0105150b03360038290c010b01020000000f001700"; - let res = run_binary_test("sample_coin_store", code); - assert!(res.is_ok(), "{:?}", res) -} - -#[test] -fn sample_liquidity_pool() { - let code = "a11ceb0b050000000e0100240224ab0103cf01b6030485056405e905eb0507d40bde0d08b2196006921ab80110ca1bd8070aa223ef010b9125160ca725c9120df0372a0e9a38280000010101020103010401050106000700080009000a000b000c000d000e000f021002110012080300010001000100130003000100010001001406030001000100010015060300010001000100160803000100010001001706030001000100010018060300010001000100190800001a0603000100010001001b0603000100010001001c0603000100010001001d06030001000100010220040100010d210003000100010001033804010601024f05010001025105010001015b0600105e0700027305010001057407001185010700001e00010100001f01010300000000220203030000000023040503000000002401060300000000250107030000000026010403000000002701040300000000280107030000000029010403000000002a010403000000002b080100002c010903000000002d010903000000002e030203000000002f0a0b01000030050103000000003108010300000000320c010300000000330c010300000000340d010300000000350e030300000000360d0103000000085f010901000f6011120010611314000862010901001063151200106407120010651612000766010902000002671c0701000768011501000e691e0700026a1f200100022221010100036b230101060a6c010100046d0828000c6e0827000b2b0801000a2b0801000e6f0415000e7015070002712a010100022e2b2001000e722e070007750101010008760101010001773334000778013503000000022b36370100027938010100027a011401000e7b140700027c012001000b7d010701000b7e0107000931080103000000017f083a01060b80010128000b81010701000b82010701000983014101030000000684010107001186010444001187014415000e88010b150017101a101e1a01181f1b201b1f101f1d2210221d1618231b2422051808182c102c1d2d1b242c0f300030141824312f102f1d30303218331b341b17303510351d3710371d38303a183b393b2c3b223b3b3b313b3c3b3d3b3e2439243e243d3f18243b243c0603030404040400010b0c010b0d03090009010902020b0c0109000b0c010901020303030b0c0109000b0c0109010b010309000901090203040403010301060c010105030303030302040402060c0303070b04030900090109020303040b0c010900030b0c0109010307020208120812081204081201090004040304030108120206081206081201020104020812081201060b0403090009010902030900090109020b0103070b000309000901090204070b04030900090109020b0c01090003030b0c01090103030209000901010b0d0309000901090201060b0c0109000109010304040402070b0c01090003010b0c010900020b0c010900060b10010900010b050309000901090202070b0e01090009000601070b040309000901090203030b0c0109000b0c01090104030404060b040309000901090203060b0403090009010902030301081101050e0303070b0003090009010902030b0c010b0d0309000901090204070b04030900090109020303030303030302070b0c0109000b0c0109000203060b0f010900010b030309000901090206040404040404030303030b01070b0003090009010902070b04030900090109020303040303030403010902010b02030900090109020b0b00030900090109020b10010b0d030900090109020b13010b0d030900090109020b0f010b0d03090009010902081408140b04030900090109020c060807030301060811010c020814081405060c081408140201030b100109000b130109000b0f010900010b13010900010b0803090009010902010b0e010900010b0903090009010902010b0603090009010902010b0b03090009010902010b0a0309000901090202070b0003090009010902070b040309000901090208030303030b0c010900030b0c0109010303050b0c0109000b0c010901100103030303070b0e010b0903090009010902070b0003090009010902070b04030900090109020304030b0c0109000304030b0c01090108010103070b0003090009010902030404040108150e6c69717569646974795f706f6f6c076163636f756e7404636f696e056576656e74067369676e657206737472696e670974696d657374616d700b636f696e5f68656c706572066375727665730b64616f5f73746f7261676509656d657267656e63790d676c6f62616c5f636f6e6669670a6c705f6163636f756e74076c705f636f696e046d6174680c737461626c655f6375727665047532353607757136347836340b4576656e747353746f726509466c6173686c6f616e0e466c6173686c6f616e4576656e74134c697175696469747941646465644576656e740d4c6971756964697479506f6f6c154c697175696469747952656d6f7665644576656e74124f7261636c65557064617465644576656e7415506f6f6c4163636f756e744361706162696c69747910506f6f6c437265617465644576656e7409537761704576656e741155706461746544414f4665654576656e740e5570646174654665654576656e741c6173736572745f6c705f76616c75655f69735f696e63726561736564146173736572745f706f6f6c5f756e6c6f636b656404436f696e024c50046275726e09666c6173686c6f616e156765745f63756d756c61746976655f7072696365730b6765745f64616f5f666565136765745f64616f5f666565735f636f6e666967136765745f646563696d616c735f7363616c6573076765745f6665650f6765745f666565735f636f6e666967116765745f72657365727665735f73697a650a696e697469616c697a650e69735f706f6f6c5f6578697374730e69735f706f6f6c5f6c6f636b6564046d696e741e6e65775f72657365727665735f61667465725f666565735f7363616c65640d7061795f666c6173686c6f616e0872656769737465720b7365745f64616f5f666565077365745f6665651073706c69745f6665655f746f5f64616f04737761700d7570646174655f6f7261636c6513706f6f6c5f637265617465645f68616e646c650b4576656e7448616e646c65166c69717569646974795f61646465645f68616e646c65186c69717569646974795f72656d6f7665645f68616e646c650b737761705f68616e646c6510666c6173686c6f616e5f68616e646c65156f7261636c655f757064617465645f68616e646c65117570646174655f6665655f68616e646c65157570646174655f64616f5f6665655f68616e646c6506785f6c6f616e06795f6c6f616e04785f696e05785f6f757404795f696e05795f6f75740b61646465645f785f76616c0b61646465645f795f76616c126c705f746f6b656e735f72656365697665640e636f696e5f785f726573657276650e636f696e5f795f72657365727665146c6173745f626c6f636b5f74696d657374616d70176c6173745f70726963655f785f63756d756c6174697665176c6173745f70726963655f795f63756d756c61746976650b6c705f6d696e745f6361700e4d696e744361706162696c6974790b6c705f6275726e5f6361700e4275726e4361706162696c69747907785f7363616c6507795f7363616c65066c6f636b6564036665650764616f5f6665650e72657475726e65645f785f76616c0e72657475726e65645f795f76616c106c705f746f6b656e735f6275726e65640a7369676e65725f636170105369676e65724361706162696c6974790763726561746f72076e65775f66656504553235360969735f737461626c65086c705f76616c756507636f6d706172650f69735f756e636f7272656c617465640966726f6d5f753132380866726f6d5f753634036d756c0969735f736f727465640576616c756506737570706c790c6d756c5f6469765f7531323807657874726163740a656d69745f6576656e74136173736572745f6e6f5f656d657267656e63790a616464726573735f6f661372657472696576655f7369676e65725f6361700b6d756c5f746f5f753132380473717274056d65726765076d756c5f64697610467265657a654361706162696c69747906537472696e670e6173736572745f69735f636f696e126173736572745f76616c69645f63757276651d6372656174655f7369676e65725f776974685f6361706162696c6974791b67656e65726174655f6c705f6e616d655f616e645f73796d626f6c1264657374726f795f667265657a655f63617008646563696d616c7306706f775f3130047a65726f0f6765745f64656661756c745f666565136765745f64656661756c745f64616f5f666565106e65775f6576656e745f68616e646c650d6765745f6665655f61646d696e146173736572745f76616c69645f64616f5f666565106173736572745f76616c69645f666565076465706f7369740b6e6f775f7365636f6e64730755513634783634086672616374696f6e07746f5f753132380c6f766572666c6f775f61646449bcc662ad23bb4f134aad8c8117c03f238bf3f03f324afe91ce231a559e8a6b00000000000000000000000000000000000000000000000000000000000000014e9fce03284c0ce0b86c88dd5a46f050cad2f4f33c4cdd29d98f501868558c81030864000000000000000308680000000000000003086e0000000000000003086a000000000000000308690000000000000003087000000000000000030866000000000000000308670000000000000003086d0000000000000003086b000000000000000308650000000000000003086f0000000000000003086c00000000000000030810270000000000000308e803000000000000052049bcc662ad23bb4f134aad8c8117c03f238bf3f03f324afe91ce231a559e8a6b126170746f733a3a6d657461646174615f7630c3070d6400000000000000174552525f57524f4e475f504149525f4f52444552494e47335768656e20636f696e73207573656420746f20637265617465207061697220686176652077726f6e67206f72646572696e672e6500000000000000184552525f504f4f4c5f4558495354535f464f525f50414952245768656e207061697220616c726561647920657869737473206f6e206163636f756e742e6600000000000000204552525f4e4f545f454e4f5547485f494e495449414c5f4c4951554944495459215768656e206e6f7420656e6f756768206c6971756964697479206d696e7465642e6700000000000000184552525f4e4f545f454e4f5547485f4c4951554944495459215768656e206e6f7420656e6f756768206c6971756964697479206d696e7465642e6800000000000000114552525f454d5054595f434f494e5f494e335768656e20626f7468205820616e6420592070726f766964656420666f7220737761702061726520657175616c207a65726f2e6900000000000000124552525f494e434f52524543545f535741504b5768656e20696e636f727265637420494e732f4f55547320617267756d656e74732070617373656420647572696e67207377617020616e64206d61746820646f65736e277420776f726b2e6a00000000000000194552525f494e434f52524543545f4255524e5f56414c5545531d496e636f7272656374206c7020636f696e206275726e2076616c7565736b00000000000000174552525f504f4f4c5f444f45535f4e4f545f4558495354225768656e20706f6f6c20646f65736e27742065786973747320666f7220706169722e6c000000000000000f4552525f554e524541434841424c451353686f756c64206e65766572206f636375722e6d00000000000000284552525f4e4f545f454e4f5547485f5045524d495353494f4e535f544f5f494e495449414c495a45525768656e2060696e697469616c697a65282960207472616e73616374696f6e206973207369676e6564207769746820616e79206163636f756e74206f74686572207468616e20406c6971756964737761702e6e00000000000000134552525f454d5054595f434f494e5f4c4f414e385768656e20626f7468205820616e6420592070726f766964656420666f7220666c6173686c6f616e2061726520657175616c207a65726f2e6f00000000000000124552525f504f4f4c5f49535f4c4f434b4544145768656e20706f6f6c206973206c6f636b65642e70000000000000000d4552525f4e4f545f41444d494e165768656e2075736572206973206e6f742061646d696e000208370b0e010b0803090009010902390b0e010b03030900090109023a0b0e010b05030900090109023b0b0e010b09030900090109023c0b0e010b02030900090109023d0b0e010b06030900090109023e0b0e010b0b030900090109023f0b0e010b0a0309000901090201020240034103020204420343034403450303020346034703480304020c490b0c0109004a0b0c0109014b034c044d044e0b0f010b0d03090009010902500b10010b0d03090009010902520353035401550356030502035703580359030602024c044d040702015a08110802015c0509020442034303440345030a02015d030b02015d0304180018051801180318021808180a180b1809180618000000000f3c38000303051a0b020a000b030a0111180c0a0b040b000b050b0111180c080e080e0a11190c060b063102210319070427053b3801031d05390b020b03180c0b0b0b111b070d070d18111c111d0c0c0b04111b0b05111b111d0c090e090e0c11190c070b07310221033b070427070c27020100000104170c070f3d000c000b003700140921030b070b2702020100020004195938020304070027070f3b00030907092738030e0038040c02070f3c000c0538050c040a05370138060c070a05370238070c0a0a02350a07350a0411210c080a02350a0a350b0411210c0b0a0806000000000000000024032d05320a0b060000000000000000240c010534090c010b01033a0b05010703270a0536010a0838080c060a0536020a0b38090c090a050b070b0a380a0b000b053703380b070f3c010c030b0336040b080b0b0b023902380c0b060b0902030100020004243e112538020305070027070f3b00030a07092738030a000600000000000000002403100513080c0205170a01060000000000000000240c020b02031b070227070f3c000c030a03370138060c040a03370238070c050a0336010a0038080c060a0336020a0138090c07080a033600150b030b040b05380a0b060b070b000b013903020401000104251e112538020305070027070f3b00030a0709273803070f3d000c030a033705140c010a033706140c020b033707140c000b010b020b00020501000104171038020304070027070f3b000309070927070f3d000c000b003708140206010001040103380d0700020701000104171338020304070027070f3b000309070927070f3d000c000a003709140b00370a14020801000104171038020304070027070f3b000309070927070f3d000c000b00370b140209010001040103380e070d020a010001042619112538020305070027070f3b00030a0709273803070f3d000c000a00370138060c010b00370238070c020b010b02020b01040027150a001126070f2103090b00010708270a0011270c010a000b0112072d070a0011280b001129020c010000010738020304070027070f3b00020d01000104171038020304070027070f3b000309070927070f3d000c000b00370014020e01000200042976112538020305070027070f3b00030a070927380338050c07070f3c000c080a08370138060c0c0a08370238070c0f0e0038060c0b0e0138070c0e0a07320000000000000000000000000000000021032305350a0b0a0e112a112b0c050a05070e2403300b08010706270b05070e170c03054f0a0b350a070a0c3511210c0a0a0e350b070a0f3511210c0d0a0a0a0d230348054b0b0a0c02054d0b0d0c020b020c030b030c090a090600000000000000002403590b08010707270a0836010b00380f0a0836020b0138100a090a08370c38110c060b080b0c0b0f380a070f3c010c040b04360d0b0b0b0e0b09390438120b06020f0000002d3b38010303050c0b00070d112a0b020a04112a170c06051a38000310070c270b000b020a04070d112e17350c050b050c060b060c093801031f05280b01070d112a0b030b04112a170c0805363800032c070c270b010b030b04070d112e17350c070b070c080b080c0a0b090b0a021001000200042f6e112538020305070027070f3b00030a0709270b023a030c0b0c070e0038060c060e0138070c0a0a06060000000000000000240319051c080c0305200a0a060000000000000000240c030b030324070127070f3c000c050a05370138060c090a05370238070c0d0b090a07160c090b0d0a0b160c0d0a0536010b00380f0a0536020b0138100a05370138060a05370238070a060a0a0a05370b1438130c0c0c080a053709140a05370a140b09350b0d350b080b0c38140a050a060a0a3815090b05360015070f3c010c040b04360e0b060b070b0a0b0b390538160211010001073263112538173818380203090b00010700273819070f3b002003120b0001070a27070f2b070c090b09100f11310c08381a0c060c050e080b050b06310608381b0c040c030c020b03381c0600000000000000000c0a0600000000000000000c0b381d032e0534381e11360c0a381f11360c0b38203821060000000000000000320000000000000000000000000000000032000000000000000000000000000000000b040b020b0a0b0b093822113939000c070e080b073f000e0838230e0838240e0838250e0838260e0838270e0838280e0838290e08382a0e08382b39010c010d01360f0b0011263906382c0e080b013f01021201040200043f27380203060b0001070027070f3b00030d0b000107092738030b001126113c2103150705270a01113d070f3c000c030a010b03360815070f3c010c020b0236100b013907382d021301040200043f27380203060b0001070027070f3b00030d0b000107092738030b001126113c2103150705270a01113e070f3c000c030a010b03360b15070f3c010c020b0236110b013908382e0214000000403b0a00370b140c0a0a003708140c040a0a0a0418070019060000000000000000220311051a0b0a0b041807001a060100000000000000160c0305200b0a0b041807001a0c030b030c050b010a05070d112e0c060b020b05070d112e0c080a0036010b0638080c070b0036020b0838090c09070f0b070b09382f02150100020004427b112538020305070027070f3b00030a07092738030e0038060c0c0e0238070c100a0c0600000000000000002403160519080c04051d0a10060000000000000000240c040b040321070127070f3c000c0b0a0b370138060c0e0a0b370238070c120a0b36010b00380f0a0b36020b0238100a0b36010a0138080c0f0a0b36020a0338090c130a0b370138060a0b370238070a0c0a100a0b370b1438130c110c0d0a0b3709140a0b370a140a0e350a12350b0d350b113538140a0b0a0c0a1038150b0b0b0e0b12380a070f3c010c0a0b0a36120c090b0c0c050b100c060b010c070b030c080b090b050b070b060b08390938300b0f0b1302160000010043540a003707140c0711400c050a050b0717350c0a0a0a320000000000000000000000000000000024031005150a01060000000000000000220c030517090c030b03031a051f0a02060000000000000000220c040521090c040b040324054f0a020a01114111420a0a180c080b010b02114111420b0a180c090a003705140b0811430a003605150a003706140b0911430a00360615070f3c010c060b0636130a003705140a00370614390a38310b050b003607150204090400040104060002040304040402040b04070408040a04050001000407000000000700060003000500180118021803180418051806180718081809180a180b180c180d180e181018111812181318141800"; - let res = run_binary_test("sample_liquidity_pool", code); - assert!(res.is_ok(), "{:?}", res) -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.proptest-regressions deleted file mode 100644 index 3945bd370c9..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/bounds_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 2beb0a0e65962432af560e626fa109d269b07db8807968413425f0bb14bb3667 # shrinks to module = CompiledModule: { datatype_handles: [ DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { 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, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ 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 c14ae393a6eefae82c0f4ede2acaa0aa0e993c1bba3fe3e5958e6e31cb5d2957 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] datatype_handles: [ DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { 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, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ 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]),] } , oob_mutations = [] -cc 88615e15ef42d29405cd91d6d0a573ccbeb833d0c7471f718ee794bc5ba399ca # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] datatype_handles: [ DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { 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, access: 0x4, field_count: 0, fields: 0 }, StructDefinition { struct_handle: 2, access: 0x4, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x2, code: CodeUnit { max_stack_size: 0, locals: 0 code: [] } },] type_signatures: [ 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]),] } , oob_mutations = [OutOfBoundsMutation { src_kind: StructDefinition, src_idx: Index(0), dst_kind: FieldDefinition, offset: 0 }] -cc a34039f5d57751762a6eacf3ca3a2857781fb0bd0af0b7a06a9427f896f29aa9 # shrinks to module = CompiledModule: { module_handles: [ ModuleHandle { address: AddressPoolIndex(0), name: IdentifierIndex(0) },] datatype_handles: [ DatatypeHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), is_resource: false }, DatatypeHandle { 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, access: 0x2, field_count: 0, fields: 0 },] field_defs: [] function_defs: [ FunctionDefinition { function: 1, access: 0x0, code: CodeUnit { max_stack_size: 0, locals: 0 code: [ BrTrue(1),] } },] 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]),] } , oob_mutations = [] diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs deleted file mode 100644 index bdd3dd765f3..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/bounds_tests.rs +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::{check_bounds::BoundsChecker, file_format::*, file_format_common}; -use move_core_types::vm_status::StatusCode; - -#[test] -fn empty_module_no_errors() { - BoundsChecker::verify_module(&basic_test_module()).unwrap(); -} - -#[test] -fn invalid_default_module() { - BoundsChecker::verify_module(&CompiledModule { - version: file_format_common::VERSION_MAX, - ..Default::default() - }) - .unwrap_err(); -} - -#[test] -fn invalid_self_module_handle_index() { - let mut m = basic_test_module(); - m.self_module_handle_idx = ModuleHandleIndex(12); - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_type_param_in_fn_return_() { - use SignatureToken::*; - - let mut m = basic_test_module(); - m.function_handles[0].return_ = SignatureIndex(1); - m.signatures.push(Signature(vec![TypeParameter(0)])); - assert_eq!(m.signatures.len(), 2); - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_type_param_in_fn_parameters() { - use SignatureToken::*; - - let mut m = basic_test_module(); - m.function_handles[0].parameters = SignatureIndex(1); - m.signatures.push(Signature(vec![TypeParameter(0)])); - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_struct_in_fn_return_() { - use SignatureToken::*; - - let mut m = basic_test_module(); - m.function_handles[0].return_ = SignatureIndex(1); - m.signatures - .push(Signature(vec![Datatype(DatatypeHandleIndex::new(1))])); - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_type_param_in_field() { - use SignatureToken::*; - - let mut m = basic_test_module(); - match &mut m.struct_defs[0].field_information { - StructFieldInformation::Declared(ref mut fields) => { - fields[0].signature.0 = TypeParameter(0); - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); - } - _ => panic!("attempt to change a field that does not exist"), - } -} - -#[test] -fn invalid_struct_in_field() { - use SignatureToken::*; - - let mut m = basic_test_module(); - match &mut m.struct_defs[0].field_information { - StructFieldInformation::Declared(ref mut fields) => { - fields[0].signature.0 = Datatype(DatatypeHandleIndex::new(3)); - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); - } - _ => panic!("attempt to change a field that does not exist"), - } -} - -#[test] -fn invalid_struct_with_actuals_in_field() { - use SignatureToken::*; - - let mut m = basic_test_module(); - match &mut m.struct_defs[0].field_information { - StructFieldInformation::Declared(ref mut fields) => { - fields[0].signature.0 = DatatypeInstantiation(Box::new(( - DatatypeHandleIndex::new(0), - vec![TypeParameter(0)], - ))); - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::NUMBER_OF_TYPE_ARGUMENTS_MISMATCH - ); - } - _ => panic!("attempt to change a field that does not exist"), - } -} - -#[test] -fn invalid_locals_id_in_call() { - use Bytecode::*; - - let mut m = basic_test_module(); - m.function_instantiations.push(FunctionInstantiation { - handle: FunctionHandleIndex::new(0), - type_parameters: SignatureIndex::new(1), - }); - let func_inst_idx = FunctionInstantiationIndex(m.function_instantiations.len() as u16 - 1); - m.function_defs[0].code.as_mut().unwrap().code = vec![CallGeneric(func_inst_idx)]; - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_type_param_in_call() { - use Bytecode::*; - use SignatureToken::*; - - let mut m = basic_test_module(); - m.signatures.push(Signature(vec![TypeParameter(0)])); - m.function_instantiations.push(FunctionInstantiation { - handle: FunctionHandleIndex::new(0), - type_parameters: SignatureIndex::new(1), - }); - let func_inst_idx = FunctionInstantiationIndex(m.function_instantiations.len() as u16 - 1); - m.function_defs[0].code.as_mut().unwrap().code = vec![CallGeneric(func_inst_idx)]; - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_struct_as_type_actual_in_exists() { - use Bytecode::*; - use SignatureToken::*; - - let mut m = basic_test_module(); - m.signatures - .push(Signature(vec![Datatype(DatatypeHandleIndex::new(3))])); - m.function_instantiations.push(FunctionInstantiation { - handle: FunctionHandleIndex::new(0), - type_parameters: SignatureIndex::new(1), - }); - let func_inst_idx = FunctionInstantiationIndex(m.function_instantiations.len() as u16 - 1); - m.function_defs[0].code.as_mut().unwrap().code = vec![CallGeneric(func_inst_idx)]; - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_friend_module_address() { - let mut m = basic_test_module(); - m.friend_decls.push(ModuleHandle { - address: AddressIdentifierIndex::new(m.address_identifiers.len() as TableIndex), - name: IdentifierIndex::new(0), - }); - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_friend_module_name() { - let mut m = basic_test_module(); - m.friend_decls.push(ModuleHandle { - address: AddressIdentifierIndex::new(0), - name: IdentifierIndex::new(m.identifiers.len() as TableIndex), - }); - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_signature_for_vector_operation() { - use Bytecode::*; - - let skeleton = basic_test_module(); - let sig_index = SignatureIndex(skeleton.signatures.len() as u16); - for bytecode in [ - VecPack(sig_index, 0), - VecLen(sig_index), - VecImmBorrow(sig_index), - VecMutBorrow(sig_index), - VecPushBack(sig_index), - VecPopBack(sig_index), - VecUnpack(sig_index, 0), - VecSwap(sig_index), - ] { - let mut m = skeleton.clone(); - m.function_defs[0].code.as_mut().unwrap().code = vec![bytecode]; - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); - } -} - -#[test] -fn invalid_struct_for_vector_operation() { - use Bytecode::*; - use SignatureToken::*; - - let mut skeleton = basic_test_module(); - skeleton - .signatures - .push(Signature(vec![Datatype(DatatypeHandleIndex::new(3))])); - let sig_index = SignatureIndex((skeleton.signatures.len() - 1) as u16); - for bytecode in [ - VecPack(sig_index, 0), - VecLen(sig_index), - VecImmBorrow(sig_index), - VecMutBorrow(sig_index), - VecPushBack(sig_index), - VecPopBack(sig_index), - VecUnpack(sig_index, 0), - VecSwap(sig_index), - ] { - let mut m = skeleton.clone(); - m.function_defs[0].code.as_mut().unwrap().code = vec![bytecode]; - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); - } -} - -#[test] -fn invalid_type_param_for_vector_operation() { - use Bytecode::*; - use SignatureToken::*; - - let mut skeleton = basic_test_module(); - skeleton.signatures.push(Signature(vec![TypeParameter(0)])); - let sig_index = SignatureIndex((skeleton.signatures.len() - 1) as u16); - for bytecode in [ - VecPack(sig_index, 0), - VecLen(sig_index), - VecImmBorrow(sig_index), - VecMutBorrow(sig_index), - VecPushBack(sig_index), - VecPopBack(sig_index), - VecUnpack(sig_index, 0), - VecSwap(sig_index), - ] { - let mut m = skeleton.clone(); - m.function_defs[0].code.as_mut().unwrap().code = vec![bytecode]; - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); - } -} - -#[test] -fn invalid_variant_handle_index_for_enum_operation() { - use Bytecode::*; - - let skeleton = basic_test_module(); - let variant_handle_index = VariantHandleIndex(skeleton.variant_handles.len() as u16); - let variant_handle_inst_index = - VariantInstantiationHandleIndex(skeleton.variant_instantiation_handles.len() as u16); - for bytecode in [ - PackVariant(variant_handle_index), - UnpackVariant(variant_handle_index), - UnpackVariantImmRef(variant_handle_index), - UnpackVariantMutRef(variant_handle_index), - PackVariantGeneric(variant_handle_inst_index), - UnpackVariantGeneric(variant_handle_inst_index), - UnpackVariantGenericImmRef(variant_handle_inst_index), - UnpackVariantGenericMutRef(variant_handle_inst_index), - ] { - let mut m = skeleton.clone(); - m.function_defs[0].code.as_mut().unwrap().code = vec![bytecode]; - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); - } -} - -#[test] -fn invalid_variant_jump_table_index() { - use Bytecode::*; - - let skeleton = basic_test_module(); - let jt_index = VariantJumpTableIndex( - skeleton.function_defs[0] - .code - .as_ref() - .map(|c| c.jump_tables.len() as u16) - .unwrap_or(0u16), - ); - let mut m = skeleton.clone(); - m.function_defs[0].code.as_mut().unwrap().code = vec![VariantSwitch(jt_index)]; - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} - -#[test] -fn invalid_variant_jump_table_code_offset() { - use Bytecode::*; - - let mut skeleton = basic_test_module_with_enum(); - let enum_index = EnumDefinitionIndex(0); - skeleton.function_defs[0].code.as_mut().unwrap().code = vec![LdU64(0), Pop, Ret]; - skeleton.function_defs[0].code.as_mut().unwrap().jump_tables = vec![VariantJumpTable { - head_enum: enum_index, - jump_table: JumpTableInner::Full(vec![100]), - }]; - - let jt_index = VariantJumpTableIndex( - skeleton.function_defs[0] - .code - .as_ref() - .map(|c| c.jump_tables.len() as u16) - .unwrap_or(0u16), - ); - let mut m = skeleton.clone(); - m.function_defs[0].code.as_mut().unwrap().code = vec![VariantSwitch(jt_index)]; - assert_eq!( - BoundsChecker::verify_module(&m).unwrap_err().major_status(), - StatusCode::INDEX_OUT_OF_BOUNDS - ); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/catch_unwind.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/catch_unwind.rs deleted file mode 100644 index 6b9fc629db0..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/catch_unwind.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use std::panic::{self, PanicInfo}; - -use fail::FailScenario; -use move_binary_format::file_format::empty_module; -use move_core_types::{ - state::{self, VMState}, - vm_status::StatusCode, -}; -use move_vm_config::verifier::VerifierConfig; - -#[ignore] -#[test] -fn test_unwind() { - let scenario = FailScenario::setup(); - fail::cfg("verifier-failpoint-panic", "panic").unwrap(); - - panic::set_hook(Box::new(move |_: &PanicInfo<'_>| { - assert_eq!(state::get_state(), VMState::VERIFIER); - })); - - let m = empty_module(); - let res = move_bytecode_verifier::verify_module_with_config(&VerifierConfig::unbounded(), &m) - .unwrap_err(); - assert_eq!(res.major_status(), StatusCode::VERIFIER_INVARIANT_VIOLATION); - scenario.teardown(); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/code_unit_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/code_unit_tests.rs deleted file mode 100644 index b380560a91a..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/code_unit_tests.rs +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::Bytecode; -use move_bytecode_verifier::{ability_cache::AbilityCache, code_unit_verifier}; -use move_bytecode_verifier_meter::dummy::DummyMeter; -use move_core_types::vm_status::StatusCode; -use move_vm_config::verifier::VerifierConfig; - -use crate::support::dummy_procedure_module; - -#[test] -fn invalid_fallthrough_br_true() { - let module = &dummy_procedure_module(vec![Bytecode::LdFalse, Bytecode::BrTrue(1)]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::INVALID_FALL_THROUGH - ); -} - -#[test] -fn invalid_fallthrough_br_false() { - let module = &dummy_procedure_module(vec![Bytecode::LdTrue, Bytecode::BrFalse(1)]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::INVALID_FALL_THROUGH - ); -} - -// all non-branch instructions should trigger invalid fallthrough; just check -// one of them -#[test] -fn invalid_fallthrough_non_branch() { - let module = &dummy_procedure_module(vec![Bytecode::LdTrue, Bytecode::Pop]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::INVALID_FALL_THROUGH - ); -} - -#[test] -fn valid_fallthrough_branch() { - let module = &dummy_procedure_module(vec![Bytecode::Branch(0)]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert!(result.is_ok()); -} - -#[test] -fn valid_fallthrough_ret() { - let module = &dummy_procedure_module(vec![Bytecode::Ret]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert!(result.is_ok()); -} - -#[test] -fn valid_fallthrough_abort() { - let module = &dummy_procedure_module(vec![Bytecode::LdU64(7), Bytecode::Abort]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert!(result.is_ok()); -} - -#[test] -fn test_max_number_of_bytecode() { - let mut nops = vec![]; - for _ in 0..u16::MAX - 1 { - nops.push(Bytecode::Nop); - } - nops.push(Bytecode::Ret); - let module = &dummy_procedure_module(nops); - let ability_cache = &mut AbilityCache::new(module); - - let result = code_unit_verifier::verify_module( - &VerifierConfig::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert!(result.is_ok()); -} - -#[test] -fn test_max_basic_blocks() { - let mut code = (0..17) - .map(|idx| Bytecode::Branch(idx + 1)) - .collect::>(); - code.push(Bytecode::Ret); - let module = &dummy_procedure_module(code); - let ability_cache = &mut AbilityCache::new(module); - - let result = code_unit_verifier::verify_module( - &VerifierConfig { - max_basic_blocks: Some(16), - ..Default::default() - }, - module, - ability_cache, - &mut DummyMeter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::TOO_MANY_BASIC_BLOCKS - ); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs deleted file mode 100644 index 1dc747b5af0..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/constants_tests.rs +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::{Constant, SignatureToken, empty_module}; -use move_bytecode_verifier::constants; -use move_core_types::vm_status::StatusCode; - -#[test] -fn valid_primitives() { - let mut module = empty_module(); - module.constant_pool = vec![ - Constant { - type_: SignatureToken::Bool, - data: vec![0], - }, - Constant { - type_: SignatureToken::U8, - data: vec![0], - }, - Constant { - type_: SignatureToken::U16, - data: vec![0, 0], - }, - Constant { - type_: SignatureToken::U32, - data: vec![0, 0, 0, 0], - }, - Constant { - type_: SignatureToken::U64, - data: vec![0, 0, 0, 0, 0, 0, 0, 0], - }, - Constant { - type_: SignatureToken::U128, - data: vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - }, - Constant { - type_: SignatureToken::U256, - data: 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, 0, 0, - 0, 0, 0, 0, - ], - }, - Constant { - type_: SignatureToken::Address, - data: 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, 0, 0, - 0, 0, 0, 0, - ], - }, - ]; - assert!(constants::verify_module(&module).is_ok()); -} - -#[test] -fn invalid_primitives() { - malformed(SignatureToken::U8, vec![0, 0]); - malformed(SignatureToken::U16, vec![0, 0, 0, 0]); - malformed(SignatureToken::U32, vec![0, 0, 0]); - malformed(SignatureToken::U64, vec![0]); - malformed(SignatureToken::U128, vec![0]); - malformed(SignatureToken::U256, vec![0, 0]); - let data = 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ]; - malformed(SignatureToken::Address, data); -} - -#[test] -fn valid_vectors() { - let double_vec = |item: Vec| -> Vec { - let mut items = vec![2]; - items.extend(item.clone()); - items.extend(item); - items - }; - let large_vec = |item: Vec| -> Vec { - let mut items = vec![0xFF, 0xFF, 3]; - (0..0xFFFF).for_each(|_| items.extend(item.clone())); - items - }; - let mut module = empty_module(); - module.constant_pool = vec![ - // empty - Constant { - type_: tvec(SignatureToken::Bool), - data: vec![0], - }, - Constant { - type_: tvec(tvec(SignatureToken::Bool)), - data: vec![0], - }, - Constant { - type_: tvec(tvec(tvec(tvec(SignatureToken::Bool)))), - data: vec![0], - }, - Constant { - type_: tvec(tvec(tvec(tvec(SignatureToken::Bool)))), - data: double_vec(vec![0]), - }, - // small - Constant { - type_: tvec(SignatureToken::Bool), - data: vec![9, 1, 1, 1, 1, 1, 1, 1, 1, 1], - }, - Constant { - type_: tvec(SignatureToken::U8), - data: vec![9, 1, 1, 1, 1, 1, 1, 1, 1, 1], - }, - // large - Constant { - type_: tvec(SignatureToken::Bool), - data: large_vec(vec![0]), - }, - Constant { - type_: tvec(SignatureToken::U8), - data: large_vec(vec![0]), - }, - Constant { - type_: tvec(SignatureToken::U16), - data: large_vec(vec![0, 0]), - }, - Constant { - type_: tvec(SignatureToken::U32), - data: large_vec(vec![0, 0, 0, 0]), - }, - Constant { - type_: tvec(SignatureToken::U64), - data: large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0]), - }, - Constant { - type_: tvec(SignatureToken::U128), - data: large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - }, - Constant { - type_: tvec(SignatureToken::U256), - data: large_vec(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, 0, 0, - 0, 0, 0, 0, - ]), - }, - Constant { - type_: tvec(SignatureToken::Address), - data: large_vec(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, 0, 0, - 0, 0, 0, 0, - ]), - }, - // double large - Constant { - type_: tvec(tvec(SignatureToken::Bool)), - data: double_vec(large_vec(vec![0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U8)), - data: double_vec(large_vec(vec![0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U16)), - data: double_vec(large_vec(vec![0, 0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U32)), - data: double_vec(large_vec(vec![0, 0, 0, 0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U64)), - data: double_vec(large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U128)), - data: double_vec(large_vec(vec![ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U256)), - data: double_vec(large_vec(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, 0, 0, - 0, 0, 0, 0, - ])), - }, - Constant { - type_: tvec(tvec(SignatureToken::Address)), - data: double_vec(large_vec(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, 0, 0, - 0, 0, 0, 0, - ])), - }, - ]; - assert!(constants::verify_module(&module).is_ok()); -} - -#[test] -fn invalid_vectors() { - let double_vec = |item: Vec| -> Vec { - let mut items = vec![2]; - items.extend(item.clone()); - items.extend(item); - items - }; - let too_large_vec = |item: Vec| -> Vec { - let mut items = vec![0xFF, 0xFF, 3]; - (0..(0xFFFF + 1)).for_each(|_| items.extend(item.clone())); - items - }; - // wrong inner - malformed(tvec(SignatureToken::U16), vec![1, 0]); - malformed(tvec(SignatureToken::U32), vec![1, 0]); - malformed(tvec(SignatureToken::U64), vec![1, 0]); - malformed(tvec(SignatureToken::Address), vec![ - 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - ]); - // wrong lens - malformed(tvec(SignatureToken::U8), vec![0, 0]); - malformed(tvec(SignatureToken::U8), vec![0, 1]); - malformed(tvec(SignatureToken::U8), vec![2, 1, 1, 1]); - malformed(tvec(tvec(SignatureToken::U8)), double_vec(vec![0, 0])); - // too large - malformed(tvec(SignatureToken::U8), too_large_vec(vec![0])); -} - -#[test] -fn invalid_types() { - invalid_type(SignatureToken::TypeParameter(0), vec![0]); - invalid_type(SignatureToken::TypeParameter(0xFA), vec![0]); - invalid_type(tvec(SignatureToken::TypeParameter(0)), vec![0]); - invalid_type(tvec(SignatureToken::TypeParameter(0xAF)), vec![0]); - - invalid_type(SignatureToken::Signer, vec![0]); - invalid_type(tvec(SignatureToken::Signer), vec![0]); - - // TODO cannot check structs are banned currently. This can be handled by IR - // and source lang tests - // invalid_type(SignatureToken::Datatype(DatatypeHandleIndex(0)), vec![0]); -} - -fn tvec(s: SignatureToken) -> SignatureToken { - SignatureToken::Vector(Box::new(s)) -} - -fn malformed(type_: SignatureToken, data: Vec) { - error(type_, data, StatusCode::MALFORMED_CONSTANT_DATA) -} - -fn invalid_type(type_: SignatureToken, data: Vec) { - error(type_, data, StatusCode::INVALID_CONSTANT_TYPE) -} - -fn error(type_: SignatureToken, data: Vec, code: StatusCode) { - let mut module = empty_module(); - module.constant_pool = vec![Constant { type_, data }]; - assert!( - constants::verify_module(&module) - .unwrap_err() - .major_status() - == code - ) -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/control_flow_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/control_flow_tests.rs deleted file mode 100644 index 2f5d9070bf1..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/control_flow_tests.rs +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::{ - errors::PartialVMResult, - file_format::{Bytecode, CompiledModule, FunctionDefinitionIndex, TableIndex}, -}; -use move_bytecode_verifier::control_flow; -use move_bytecode_verifier_meter::dummy::DummyMeter; -use move_core_types::vm_status::StatusCode; -use move_vm_config::verifier::VerifierConfig; - -use crate::support::dummy_procedure_module; - -fn verify_module(verifier_config: &VerifierConfig, module: &CompiledModule) -> PartialVMResult<()> { - for (idx, function_definition) in module - .function_defs() - .iter() - .enumerate() - .filter(|(_, def)| !def.is_native()) - { - let current_function = FunctionDefinitionIndex(idx as TableIndex); - let code = function_definition - .code - .as_ref() - .expect("unexpected native function"); - - control_flow::verify_function( - verifier_config, - module, - current_function, - function_definition, - code, - &mut DummyMeter, - )?; - } - Ok(()) -} - -//************************************************************************************************** -// Simple cases - Copied from code unit verifier -//************************************************************************************************** - -#[test] -fn empty_bytecode() { - let module = dummy_procedure_module(vec![]); - let result = verify_module(&Default::default(), &module); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::EMPTY_CODE_UNIT, - ); -} - -#[test] -fn empty_bytecode_v5() { - let mut module = dummy_procedure_module(vec![]); - module.version = 5; - - let result = verify_module(&Default::default(), &module); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::EMPTY_CODE_UNIT, - ); -} - -#[test] -fn invalid_fallthrough_br_true() { - let module = dummy_procedure_module(vec![Bytecode::LdFalse, Bytecode::BrTrue(1)]); - let result = verify_module(&Default::default(), &module); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::INVALID_FALL_THROUGH - ); -} - -#[test] -fn invalid_fallthrough_br_false() { - let module = dummy_procedure_module(vec![Bytecode::LdTrue, Bytecode::BrFalse(1)]); - let result = verify_module(&Default::default(), &module); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::INVALID_FALL_THROUGH - ); -} - -// all non-branch instructions should trigger invalid fallthrough; just check -// one of them -#[test] -fn invalid_fallthrough_non_branch() { - let module = dummy_procedure_module(vec![Bytecode::LdTrue, Bytecode::Pop]); - let result = verify_module(&Default::default(), &module); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::INVALID_FALL_THROUGH - ); -} - -#[test] -fn valid_fallthrough_branch() { - let module = dummy_procedure_module(vec![Bytecode::Branch(0)]); - let result = verify_module(&Default::default(), &module); - assert!(result.is_ok()); -} - -#[test] -fn valid_fallthrough_ret() { - let module = dummy_procedure_module(vec![Bytecode::Ret]); - let result = verify_module(&Default::default(), &module); - assert!(result.is_ok()); -} - -#[test] -fn valid_fallthrough_abort() { - let module = dummy_procedure_module(vec![Bytecode::LdU64(7), Bytecode::Abort]); - let result = verify_module(&Default::default(), &module); - assert!(result.is_ok()); -} - -#[test] -fn nested_loops_max_depth() { - let module = dummy_procedure_module(vec![ - Bytecode::LdFalse, - Bytecode::LdFalse, - Bytecode::BrFalse(1), - Bytecode::BrFalse(0), - Bytecode::Ret, - ]); - let result = verify_module( - &VerifierConfig { - max_loop_depth: Some(2), - ..VerifierConfig::default() - }, - &module, - ); - assert!(result.is_ok()); -} - -#[test] -fn nested_loops_exceed_max_depth() { - let module = dummy_procedure_module(vec![ - Bytecode::LdFalse, - Bytecode::LdFalse, - Bytecode::LdFalse, - Bytecode::BrFalse(2), - Bytecode::BrFalse(1), - Bytecode::BrFalse(0), - Bytecode::Ret, - ]); - let result = verify_module( - &VerifierConfig { - max_loop_depth: Some(2), - ..VerifierConfig::default() - }, - &module, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::LOOP_MAX_DEPTH_REACHED - ); -} - -#[test] -fn non_loop_backward_jump() { - let module = dummy_procedure_module(vec![ - Bytecode::Branch(2), - Bytecode::Ret, - Bytecode::Branch(1), - ]); - let result = verify_module(&Default::default(), &module); - assert!(result.is_ok()); -} - -#[test] -fn non_loop_backward_jump_v5() { - let mut module = dummy_procedure_module(vec![ - Bytecode::Branch(2), - Bytecode::Ret, - Bytecode::Branch(1), - ]); - - module.version = 5; - let result = verify_module(&Default::default(), &module); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::INVALID_LOOP_SPLIT, - ); -} - -#[test] -fn irreducible_control_flow_graph() { - let module = dummy_procedure_module(vec![ - Bytecode::LdTrue, - Bytecode::BrTrue(3), - Bytecode::Nop, - Bytecode::LdFalse, - Bytecode::BrFalse(2), - Bytecode::Ret, - ]); - let result = verify_module(&Default::default(), &module); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::INVALID_LOOP_SPLIT, - ); -} - -#[test] -fn nested_loop_break() { - let module = dummy_procedure_module(vec![ - Bytecode::LdFalse, - Bytecode::LdFalse, - Bytecode::LdFalse, - Bytecode::Branch(7), - Bytecode::BrFalse(2), - Bytecode::BrFalse(1), - Bytecode::BrFalse(0), - Bytecode::Ret, - ]); - let result = verify_module(&Default::default(), &module); - assert!(result.is_ok()); -} - -#[test] -fn nested_loop_break_v5() { - let mut module = dummy_procedure_module(vec![ - Bytecode::LdFalse, - Bytecode::LdFalse, - Bytecode::LdFalse, - Bytecode::Branch(7), - Bytecode::BrFalse(2), - Bytecode::BrFalse(1), - Bytecode::BrFalse(0), - Bytecode::Ret, - ]); - - module.version = 5; - let result = verify_module(&Default::default(), &module); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::INVALID_LOOP_BREAK, - ); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs deleted file mode 100644 index 5c40fa75adb..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/duplication_tests.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::*; -use move_bytecode_verifier::DuplicationChecker; - -#[test] -fn duplicated_friend_decls() { - let mut m = basic_test_module(); - let handle = ModuleHandle { - address: AddressIdentifierIndex::new(0), - name: IdentifierIndex::new(0), - }; - m.friend_decls.push(handle.clone()); - m.friend_decls.push(handle); - DuplicationChecker::verify_module(&m).unwrap_err(); -} - -#[test] -fn duplicated_variant_handles() { - let mut m = basic_test_module_with_enum(); - m.variant_handles.push(m.variant_handles[0].clone()); - DuplicationChecker::verify_module(&m).unwrap_err(); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs deleted file mode 100644 index c45ad03375d..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::*; -use move_bytecode_verifier::InstructionConsistency; -use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, -}; - -// Make a Module with 2 structs and 2 resources with one field each, and 2 -// functions. One of the struct/resource and one of the function is generic, the -// other "normal". Also make a test function whose body will be filled by given -// test cases. -fn make_module() -> CompiledModule { - CompiledModule { - version: move_binary_format::file_format_common::VERSION_MAX, - module_handles: vec![ - // only self module - ModuleHandle { - address: AddressIdentifierIndex(0), - name: IdentifierIndex(0), - }, - ], - self_module_handle_idx: ModuleHandleIndex(0), - identifiers: vec![ - Identifier::new("M").unwrap(), // Module name - Identifier::new("S").unwrap(), // Struct name - Identifier::new("GS").unwrap(), // Generic struct name - Identifier::new("R").unwrap(), // Resource name - Identifier::new("GR").unwrap(), // Generic resource name - Identifier::new("f").unwrap(), // Field name - Identifier::new("fn").unwrap(), // Function name - Identifier::new("g_fn").unwrap(), // Generic function name - Identifier::new("test_fn").unwrap(), // Test function name - ], - address_identifiers: vec![ - AccountAddress::ZERO, // Module address - ], - datatype_handles: vec![ - DatatypeHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(1), - abilities: AbilitySet::PRIMITIVES, - type_parameters: vec![], - }, - DatatypeHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(2), - abilities: AbilitySet::PRIMITIVES, - type_parameters: vec![DatatypeTyParameter { - constraints: AbilitySet::PRIMITIVES, - is_phantom: false, - }], - }, - DatatypeHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(3), - abilities: AbilitySet::EMPTY | Ability::Key, - type_parameters: vec![], - }, - DatatypeHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(4), - abilities: AbilitySet::EMPTY | Ability::Key, - type_parameters: vec![DatatypeTyParameter { - constraints: AbilitySet::PRIMITIVES, - is_phantom: false, - }], - }, - ], - struct_defs: vec![ - // struct S { f: u64 } - StructDefinition { - struct_handle: DatatypeHandleIndex(0), - field_information: StructFieldInformation::Declared(vec![FieldDefinition { - name: IdentifierIndex(5), - signature: TypeSignature(SignatureToken::U64), - }]), - }, - // struct GS { f: T } - StructDefinition { - struct_handle: DatatypeHandleIndex(1), - field_information: StructFieldInformation::Declared(vec![FieldDefinition { - name: IdentifierIndex(5), - signature: TypeSignature(SignatureToken::TypeParameter(0)), - }]), - }, - // struct R has key { f: u64 } - StructDefinition { - struct_handle: DatatypeHandleIndex(2), - field_information: StructFieldInformation::Declared(vec![FieldDefinition { - name: IdentifierIndex(5), - signature: TypeSignature(SignatureToken::U64), - }]), - }, - // struct GR has key { f: T } - StructDefinition { - struct_handle: DatatypeHandleIndex(3), - field_information: StructFieldInformation::Declared(vec![FieldDefinition { - name: IdentifierIndex(5), - signature: TypeSignature(SignatureToken::TypeParameter(0)), - }]), - }, - ], - function_handles: vec![ - // fun fn() - FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(6), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }, - // fun g_fn() - FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(7), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![AbilitySet::EMPTY | Ability::Key], - }, - // fun test_fn(Sender) - FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(8), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }, - ], - function_defs: vec![ - // public fun fn() { return; } - FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Visibility::Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Ret], - jump_tables: vec![], - }), - }, - // fun g_fn() { return; } - FunctionDefinition { - function: FunctionHandleIndex(1), - visibility: Visibility::Private, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Ret], - jump_tables: vec![], - }), - }, - // fun test_fn() { ... } - tests will fill up the code - FunctionDefinition { - function: FunctionHandleIndex(2), - visibility: Visibility::Private, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![], - jump_tables: vec![], - }), - }, - ], - signatures: vec![ - Signature(vec![]), // void - Signature(vec![SignatureToken::Signer]), // Signer - ], - constant_pool: vec![ - // an address - Constant { - type_: SignatureToken::Address, - data: AccountAddress::random().to_vec(), - }, - ], - metadata: vec![], - field_handles: vec![], - friend_decls: vec![], - struct_def_instantiations: vec![], - function_instantiations: vec![], - field_instantiations: vec![], - enum_defs: vec![], - enum_def_instantiations: vec![], - variant_handles: vec![], - variant_instantiation_handles: vec![], - } -} - -#[test] -fn generic_call_to_non_generic_func() { - let mut module = make_module(); - // bogus `CallGeneric fn()` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![ - Bytecode::CallGeneric(FunctionInstantiationIndex(0)), - Bytecode::Ret, - ], - jump_tables: vec![], - }); - module.function_instantiations.push(FunctionInstantiation { - handle: FunctionHandleIndex(0), - type_parameters: SignatureIndex(2), - }); - module.signatures.push(Signature(vec![SignatureToken::U64])); - let err = InstructionConsistency::verify_module(&module) - .expect_err("CallGeneric to non generic function must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} - -#[test] -fn non_generic_call_to_generic_func() { - let mut module = make_module(); - // bogus `Call g_fn()` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], - jump_tables: vec![], - }); - let err = InstructionConsistency::verify_module(&module) - .expect_err("Call to generic function must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} - -#[test] -fn generic_pack_on_non_generic_struct() { - let mut module = make_module(); - // bogus `PackGeneric S` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![ - Bytecode::LdU64(10), - Bytecode::PackGeneric(StructDefInstantiationIndex(0)), - Bytecode::Pop, - Bytecode::Ret, - ], - jump_tables: vec![], - }); - module - .struct_def_instantiations - .push(StructDefInstantiation { - def: StructDefinitionIndex(0), - type_parameters: SignatureIndex(2), - }); - module.signatures.push(Signature(vec![SignatureToken::U64])); - let err = InstructionConsistency::verify_module(&module) - .expect_err("PackGeneric to non generic struct must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} - -#[test] -fn non_generic_pack_on_generic_struct() { - let mut module = make_module(); - // bogus `Pack GS` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![ - Bytecode::LdU64(10), - Bytecode::Pack(StructDefinitionIndex(1)), - Bytecode::Pop, - Bytecode::Ret, - ], - jump_tables: vec![], - }); - let err = InstructionConsistency::verify_module(&module) - .expect_err("Pack to generic struct must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} - -#[test] -fn generic_unpack_on_non_generic_struct() { - let mut module = make_module(); - // bogus `UnpackGeneric S` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![ - Bytecode::LdU64(10), - Bytecode::Pack(StructDefinitionIndex(0)), - Bytecode::UnpackGeneric(StructDefInstantiationIndex(0)), - Bytecode::Pop, - Bytecode::Ret, - ], - jump_tables: vec![], - }); - module - .struct_def_instantiations - .push(StructDefInstantiation { - def: StructDefinitionIndex(0), - type_parameters: SignatureIndex(2), - }); - module.signatures.push(Signature(vec![SignatureToken::U64])); - let err = InstructionConsistency::verify_module(&module) - .expect_err("UnpackGeneric to non generic struct must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} - -#[test] -fn non_generic_unpack_on_generic_struct() { - let mut module = make_module(); - // bogus `Unpack GS` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![ - Bytecode::LdU64(10), - Bytecode::PackGeneric(StructDefInstantiationIndex(0)), - Bytecode::Unpack(StructDefinitionIndex(1)), - Bytecode::Pop, - Bytecode::Ret, - ], - jump_tables: vec![], - }); - module - .struct_def_instantiations - .push(StructDefInstantiation { - def: StructDefinitionIndex(1), - type_parameters: SignatureIndex(2), - }); - module.signatures.push(Signature(vec![SignatureToken::U64])); - let err = InstructionConsistency::verify_module(&module) - .expect_err("Unpack to generic struct must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} - -#[test] -fn generic_mut_borrow_field_on_non_generic_struct() { - let mut module = make_module(); - // bogus `MutBorrowFieldGeneric S.t` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![ - Bytecode::LdU64(10), - Bytecode::Pack(StructDefinitionIndex(0)), - Bytecode::MutBorrowFieldGeneric(FieldInstantiationIndex(0)), - Bytecode::Pop, - Bytecode::Ret, - ], - jump_tables: vec![], - }); - module.field_instantiations.push(FieldInstantiation { - handle: FieldHandleIndex(0), - type_parameters: SignatureIndex(2), - }); - module.field_handles.push(FieldHandle { - owner: StructDefinitionIndex(0), - field: 0, - }); - module.signatures.push(Signature(vec![SignatureToken::U64])); - let err = InstructionConsistency::verify_module(&module) - .expect_err("MutBorrowFieldGeneric to non generic struct must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} - -#[test] -fn non_generic_mut_borrow_field_on_generic_struct() { - let mut module = make_module(); - // bogus `MutBorrowField GS.f` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![ - Bytecode::LdU64(10), - Bytecode::PackGeneric(StructDefInstantiationIndex(0)), - Bytecode::MutBorrowField(FieldHandleIndex(0)), - Bytecode::Pop, - Bytecode::Ret, - ], - jump_tables: vec![], - }); - module - .struct_def_instantiations - .push(StructDefInstantiation { - def: StructDefinitionIndex(1), - type_parameters: SignatureIndex(2), - }); - module.field_handles.push(FieldHandle { - owner: StructDefinitionIndex(1), - field: 0, - }); - module.signatures.push(Signature(vec![SignatureToken::U64])); - let err = InstructionConsistency::verify_module(&module) - .expect_err("MutBorrowField to generic struct must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} - -#[test] -fn generic_borrow_field_on_non_generic_struct() { - let mut module = make_module(); - // bogus `ImmBorrowFieldGeneric S.f` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![ - Bytecode::LdU64(10), - Bytecode::Pack(StructDefinitionIndex(0)), - Bytecode::ImmBorrowFieldGeneric(FieldInstantiationIndex(0)), - Bytecode::Pop, - Bytecode::Ret, - ], - jump_tables: vec![], - }); - module.field_instantiations.push(FieldInstantiation { - handle: FieldHandleIndex(0), - type_parameters: SignatureIndex(2), - }); - module.field_handles.push(FieldHandle { - owner: StructDefinitionIndex(0), - field: 0, - }); - module.signatures.push(Signature(vec![SignatureToken::U64])); - let err = InstructionConsistency::verify_module(&module) - .expect_err("ImmBorrowFieldGeneric to non generic struct must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} - -#[test] -fn non_generic_borrow_field_on_generic_struct() { - let mut module = make_module(); - // bogus `ImmBorrowField GS.f` - module.function_defs[2].code = Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![ - Bytecode::LdU64(10), - Bytecode::PackGeneric(StructDefInstantiationIndex(0)), - Bytecode::ImmBorrowField(FieldHandleIndex(0)), - Bytecode::Pop, - Bytecode::Ret, - ], - jump_tables: vec![], - }); - module - .struct_def_instantiations - .push(StructDefInstantiation { - def: StructDefinitionIndex(1), - type_parameters: SignatureIndex(2), - }); - module.field_handles.push(FieldHandle { - owner: StructDefinitionIndex(1), - field: 0, - }); - module.signatures.push(Signature(vec![SignatureToken::U64])); - let err = InstructionConsistency::verify_module(&module) - .expect_err("ImmBorrowField to generic struct must fail"); - assert_eq!( - err.major_status(), - StatusCode::GENERIC_MEMBER_OPCODE_MISMATCH - ); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs deleted file mode 100644 index 3b565fa979b..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/large_type_test.rs +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::{ - empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, - IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, - Visibility::Public, -}; -use move_bytecode_verifier_meter::bound::BoundMeter; -use move_core_types::{identifier::Identifier, vm_status::StatusCode}; - -use crate::unit_tests::production_config; - -const NUM_LOCALS: u8 = 64; -const NUM_CALLS: u16 = 77; -const NUM_FUNCTIONS: u16 = 177; - -fn get_nested_vec_type(len: usize) -> SignatureToken { - let mut ret = SignatureToken::Bool; - for _ in 0..len { - ret = SignatureToken::Vector(Box::new(ret)); - } - ret -} - -#[test] -fn test_large_types() { - // See also: github.com/aptos-labs/aptos-core/security/advisories/ - // GHSA-37qw-jfpw-8899 - 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(), - )); - - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(0), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - // returns_vecs - m.identifiers.push(Identifier::new("returns_vecs").unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(1), - parameters: SignatureIndex(0), - return_: SignatureIndex(1), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(1), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - // takes_and_returns_vecs - m.identifiers - .push(Identifier::new("takes_and_returns_vecs").unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(2), - parameters: SignatureIndex(1), - return_: SignatureIndex(1), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(2), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - // takes_vecs - m.identifiers.push(Identifier::new("takes_vecs").unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(3), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(3), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Ret], - jump_tables: vec![], - }), - }); - - // other fcts - for i in 0..NUM_FUNCTIONS { - m.identifiers - .push(Identifier::new(format!("f{}", i)).unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(i + 4), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(i + 4), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![], - jump_tables: vec![], - }), - }); - - let code = &mut m.function_defs[i as usize + 4].code.as_mut().unwrap().code; - code.clear(); - code.push(Bytecode::Call(FunctionHandleIndex(1))); - for _ in 0..NUM_CALLS { - code.push(Bytecode::Call(FunctionHandleIndex(2))); - } - code.push(Bytecode::Call(FunctionHandleIndex(3))); - code.push(Bytecode::Ret); - } - - let (verifier_config, meter_config) = production_config(); - let mut meter = BoundMeter::new(meter_config); - let result = move_bytecode_verifier::verify_module_with_config_for_test( - "test_large_types", - &verifier_config, - &m, - &mut meter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::CONSTRAINT_NOT_SATISFIED, - ); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs deleted file mode 100644 index 271e1cf955e..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/limit_tests.rs +++ /dev/null @@ -1,827 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::*; -use move_bytecode_verifier::{limits::LimitsVerifier, verify_module_with_config_for_test}; -use move_bytecode_verifier_meter::dummy::DummyMeter; -use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, -}; -use move_vm_config::verifier::{VerifierConfig, DEFAULT_MAX_IDENTIFIER_LENGTH}; - -use crate::unit_tests::production_config; - -#[test] -fn test_function_handle_type_instantiation() { - let mut m = basic_test_module(); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex::new(0), - name: IdentifierIndex::new(0), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: std::iter::repeat(AbilitySet::ALL).take(10).collect(), - }); - - assert_eq!( - LimitsVerifier::verify_module( - &VerifierConfig { - max_generic_instantiation_length: Some(9), - ..Default::default() - }, - &m - ) - .unwrap_err() - .major_status(), - StatusCode::TOO_MANY_TYPE_PARAMETERS - ); -} - -#[test] -fn test_struct_handle_type_instantiation() { - let mut m = basic_test_module(); - m.datatype_handles.push(DatatypeHandle { - module: ModuleHandleIndex::new(0), - name: IdentifierIndex::new(0), - abilities: AbilitySet::ALL, - type_parameters: std::iter::repeat(DatatypeTyParameter { - constraints: AbilitySet::ALL, - is_phantom: false, - }) - .take(10) - .collect(), - }); - - assert_eq!( - LimitsVerifier::verify_module( - &VerifierConfig { - max_generic_instantiation_length: Some(9), - ..Default::default() - }, - &m - ) - .unwrap_err() - .major_status(), - StatusCode::TOO_MANY_TYPE_PARAMETERS - ); -} - -#[test] -fn test_function_handle_parameters() { - let mut m = basic_test_module(); - m.signatures.push(Signature( - std::iter::repeat(SignatureToken::Bool).take(10).collect(), - )); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex::new(0), - name: IdentifierIndex::new(0), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - - assert_eq!( - LimitsVerifier::verify_module( - &VerifierConfig { - max_function_parameters: Some(9), - ..Default::default() - }, - &m - ) - .unwrap_err() - .major_status(), - StatusCode::TOO_MANY_PARAMETERS - ); -} - -#[test] -fn big_vec_unpacks() { - const N_TYPE_PARAMS: usize = 16; - let mut st = SignatureToken::Vector(Box::new(SignatureToken::U8)); - let type_params = vec![st; N_TYPE_PARAMS]; - st = SignatureToken::DatatypeInstantiation(Box::new((DatatypeHandleIndex(0), type_params))); - const N_VEC_PUSH: u16 = 1000; - let mut code = vec![]; - // 1. CopyLoc: ... -> ... st - // 2. VecPack: ... st -> ... Vec - // 3. VecUnpack: ... Vec -> ... st, st, st, ... st - for _ in 0..N_VEC_PUSH { - code.push(Bytecode::CopyLoc(0)); - code.push(Bytecode::VecPack(SignatureIndex(1), 1)); - code.push(Bytecode::VecUnpack(SignatureIndex(1), 1 << 15)); - } - // 1. VecPack: ... st, st, st, ... st -> ... Vec - // 2. Pop: ... Vec -> ... - for _ in 0..N_VEC_PUSH { - code.push(Bytecode::VecPack(SignatureIndex(1), 1 << 15)); - code.push(Bytecode::Pop); - } - code.push(Bytecode::Ret); - let type_param_constraints = DatatypeTyParameter { - constraints: AbilitySet::EMPTY, - is_phantom: false, - }; - let module = CompiledModule { - version: 5, - self_module_handle_idx: ModuleHandleIndex(0), - module_handles: vec![ModuleHandle { - address: AddressIdentifierIndex(0), - name: IdentifierIndex(0), - }], - datatype_handles: vec![DatatypeHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(1), - abilities: AbilitySet::ALL, - type_parameters: vec![type_param_constraints; N_TYPE_PARAMS], - }], - function_handles: vec![FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(0), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }], - field_handles: vec![], - friend_decls: vec![], - struct_def_instantiations: vec![], - function_instantiations: vec![], - field_instantiations: vec![], - signatures: vec![Signature(vec![]), Signature(vec![st])], - identifiers: vec![ - Identifier::new("f").unwrap(), - Identifier::new("generic_struct").unwrap(), - ], - address_identifiers: vec![AccountAddress::ONE], - constant_pool: vec![], - metadata: vec![], - struct_defs: vec![StructDefinition { - struct_handle: DatatypeHandleIndex(0), - field_information: StructFieldInformation::Native, - }], - function_defs: vec![FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Visibility::Public, - is_entry: true, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code, - jump_tables: vec![], - }), - }], - enum_defs: vec![], - enum_def_instantiations: vec![], - variant_handles: vec![], - variant_instantiation_handles: vec![], - }; - - // save module and verify that it can ser/de - let mut mvbytes = vec![]; - module.serialize(&mut mvbytes).unwrap(); - let module = CompiledModule::deserialize_with_defaults(&mvbytes).unwrap(); - - let res = verify_module_with_config_for_test( - "big_vec_unpacks", - &VerifierConfig { - max_loop_depth: Some(5), - max_generic_instantiation_length: Some(32), - max_function_parameters: Some(128), - max_basic_blocks: Some(1024), - max_push_size: Some(10000), - ..Default::default() - }, - &module, - &mut DummyMeter, - ); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::VALUE_STACK_PUSH_OVERFLOW - ); -} - -const MAX_STRUCTS: usize = 200; -const MAX_FIELDS: usize = 30; -const MAX_FUNCTIONS: usize = 1000; - -#[test] -fn max_struct_test() { - let config = VerifierConfig { - max_data_definitions: Some(MAX_STRUCTS), - max_fields_in_struct: Some(MAX_FIELDS), - max_function_definitions: Some(MAX_FUNCTIONS), - ..Default::default() - }; - let mut module = leaf_module("M"); - multi_struct(&mut module, 0); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - multi_struct(&mut module, 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS / 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS * 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_STRUCT_DEFINITIONS_REACHED, - ); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS + 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_STRUCT_DEFINITIONS_REACHED, - ); -} - -#[test] -fn max_fields_test() { - let config = VerifierConfig { - max_data_definitions: Some(MAX_STRUCTS), - max_fields_in_struct: Some(MAX_FIELDS), - max_function_definitions: Some(MAX_FUNCTIONS), - ..Default::default() - }; - let mut module = leaf_module("M"); - multi_struct(&mut module, 1); - multi_fields(&mut module, MAX_FIELDS / 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, 10); - multi_fields(&mut module, MAX_FIELDS - 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, 50); - multi_fields(&mut module, MAX_FIELDS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, 100); - multi_fields(&mut module, MAX_FIELDS + 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FIELD_DEFINITIONS_REACHED, - ); - let mut module = leaf_module("M"); - multi_struct(&mut module, 2); - multi_fields(&mut module, MAX_FIELDS * 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FIELD_DEFINITIONS_REACHED, - ); - let mut module = leaf_module("M"); - multi_struct(&mut module, 50); - multi_fields_except_one(&mut module, 0, 2, MAX_FIELDS + 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FIELD_DEFINITIONS_REACHED, - ); - let mut module = leaf_module("M"); - multi_struct(&mut module, 20); - multi_fields_except_one(&mut module, 19, MAX_FIELDS, MAX_FIELDS + 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FIELD_DEFINITIONS_REACHED, - ); - let mut module = leaf_module("M"); - multi_struct(&mut module, 100); - multi_fields_except_one(&mut module, 50, 1, MAX_FIELDS * 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FIELD_DEFINITIONS_REACHED, - ); -} - -#[test] -fn max_functions_test() { - let config = VerifierConfig { - max_data_definitions: Some(MAX_STRUCTS), - max_fields_in_struct: Some(MAX_FIELDS), - max_function_definitions: Some(MAX_FUNCTIONS), - ..Default::default() - }; - let mut module = leaf_module("M"); - multi_struct(&mut module, 1); - multi_functions(&mut module, 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, 10); - multi_functions(&mut module, MAX_FUNCTIONS / 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, 5); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, 5); - multi_functions(&mut module, MAX_FUNCTIONS - 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, 5); - multi_functions(&mut module, MAX_FUNCTIONS + 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FUNCTION_DEFINITIONS_REACHED, - ); - let mut module = leaf_module("M"); - multi_functions(&mut module, MAX_FUNCTIONS * 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FUNCTION_DEFINITIONS_REACHED, - ); -} - -#[test] -fn max_mixed_config_test() { - let config = VerifierConfig { - max_data_definitions: Some(MAX_STRUCTS), - max_fields_in_struct: Some(MAX_FIELDS), - max_function_definitions: Some(MAX_FUNCTIONS), - ..Default::default() - }; - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - - let config = VerifierConfig { - max_function_definitions: None, - max_data_definitions: None, - max_fields_in_struct: None, - ..Default::default() - }; - let mut module = leaf_module("M"); - multi_struct(&mut module, 1); - multi_fields(&mut module, 1); - multi_functions(&mut module, 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS * 2); - multi_fields(&mut module, MAX_FIELDS * 2); - multi_functions(&mut module, MAX_FUNCTIONS * 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS + 1); - multi_fields(&mut module, MAX_FIELDS + 1); - multi_functions(&mut module, MAX_FUNCTIONS + 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - - let config = VerifierConfig { - max_data_definitions: Some(MAX_STRUCTS), - max_fields_in_struct: Some(MAX_FIELDS), - ..Default::default() - }; - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS + 10); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS * 3); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS * 2); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS + 1); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_STRUCT_DEFINITIONS_REACHED, - ); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS * 2); - multi_functions(&mut module, MAX_FUNCTIONS * 3); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FIELD_DEFINITIONS_REACHED, - ); - - let config = VerifierConfig { - max_data_definitions: Some(MAX_STRUCTS), - max_function_definitions: Some(MAX_FUNCTIONS), - ..Default::default() - }; - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS + 1); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS * 3); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS * 2); - multi_fields(&mut module, MAX_FIELDS * 3); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_STRUCT_DEFINITIONS_REACHED, - ); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS * 2); - multi_functions(&mut module, MAX_FUNCTIONS * 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FUNCTION_DEFINITIONS_REACHED, - ); - - let config = VerifierConfig { - max_fields_in_struct: Some(MAX_FIELDS), - max_function_definitions: Some(MAX_FUNCTIONS), - ..Default::default() - }; - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS * 3); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS + 1); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!(res, Ok(())); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS + 1); - multi_fields(&mut module, MAX_FIELDS * 3); - multi_functions(&mut module, MAX_FUNCTIONS); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FIELD_DEFINITIONS_REACHED, - ); - let mut module = leaf_module("M"); - multi_struct(&mut module, MAX_STRUCTS * 2); - multi_fields(&mut module, MAX_FIELDS); - multi_functions(&mut module, MAX_FUNCTIONS * 2); - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::MAX_FUNCTION_DEFINITIONS_REACHED, - ); -} - -#[test] -fn max_identifier_len() { - let (config, _) = production_config(); - let max_ident = "z".repeat( - config - .max_identifier_len - .unwrap_or(DEFAULT_MAX_IDENTIFIER_LENGTH) as usize, - ); - let good_module = leaf_module(&max_ident); - - let res = LimitsVerifier::verify_module(&config, &good_module); - assert!(res.is_ok()); - - let max_ident = "z".repeat( - (config - .max_identifier_len - .unwrap_or(DEFAULT_MAX_IDENTIFIER_LENGTH) as usize) - / 2, - ); - let good_module = leaf_module(&max_ident); - - let res = LimitsVerifier::verify_module(&config, &good_module); - assert!(res.is_ok()); - - let over_max_ident = "z".repeat( - 1 + config - .max_identifier_len - .unwrap_or(DEFAULT_MAX_IDENTIFIER_LENGTH) as usize, - ); - let bad_module = leaf_module(&over_max_ident); - let res = LimitsVerifier::verify_module(&config, &bad_module); - - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::IDENTIFIER_TOO_LONG, - ); - - let over_max_ident = "zx".repeat( - 1 + config - .max_identifier_len - .unwrap_or(DEFAULT_MAX_IDENTIFIER_LENGTH) as usize, - ); - let bad_module = leaf_module(&over_max_ident); - let res = LimitsVerifier::verify_module(&config, &bad_module); - - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::IDENTIFIER_TOO_LONG, - ); -} - -#[test] -fn max_vec_len() { - let config = VerifierConfig { - max_constant_vector_len: Some(0xFFFF - 1), - ..Default::default() - }; - let double_vec = |item: Vec| -> Vec { - let mut items = vec![2]; - items.extend(item.clone()); - items.extend(item); - items - }; - let large_vec = |item: Vec| -> Vec { - let mut items = vec![0xFF, 0xFF, 3]; - (0..0xFFFF).for_each(|_| items.extend(item.clone())); - items - }; - fn tvec(s: SignatureToken) -> SignatureToken { - SignatureToken::Vector(Box::new(s)) - } - - let mut module = empty_module(); - module.constant_pool = vec![Constant { - type_: tvec(SignatureToken::Bool), - data: large_vec(vec![0]), - }]; - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::TOO_MANY_VECTOR_ELEMENTS, - ); - - let mut module = empty_module(); - module.constant_pool = vec![Constant { - type_: tvec(SignatureToken::U256), - data: large_vec(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, 0, 0, 0, - 0, 0, 0, - ]), - }]; - let res = LimitsVerifier::verify_module(&config, &module); - assert_eq!( - res.unwrap_err().major_status(), - StatusCode::TOO_MANY_VECTOR_ELEMENTS, - ); - - let config = VerifierConfig { - max_constant_vector_len: Some(0xFFFF), - ..Default::default() - }; - - let mut module = empty_module(); - module.constant_pool = vec![ - // empty - Constant { - type_: tvec(SignatureToken::Bool), - data: vec![0], - }, - Constant { - type_: tvec(tvec(SignatureToken::Bool)), - data: vec![0], - }, - Constant { - type_: tvec(tvec(tvec(tvec(SignatureToken::Bool)))), - data: vec![0], - }, - Constant { - type_: tvec(tvec(tvec(tvec(SignatureToken::Bool)))), - data: double_vec(vec![0]), - }, - // small - Constant { - type_: tvec(SignatureToken::Bool), - data: vec![9, 1, 1, 1, 1, 1, 1, 1, 1, 1], - }, - Constant { - type_: tvec(SignatureToken::U8), - data: vec![9, 1, 1, 1, 1, 1, 1, 1, 1, 1], - }, - // large - Constant { - type_: tvec(SignatureToken::Bool), - data: large_vec(vec![0]), - }, - Constant { - type_: tvec(SignatureToken::U8), - data: large_vec(vec![0]), - }, - Constant { - type_: tvec(SignatureToken::U16), - data: large_vec(vec![0, 0]), - }, - Constant { - type_: tvec(SignatureToken::U32), - data: large_vec(vec![0, 0, 0, 0]), - }, - Constant { - type_: tvec(SignatureToken::U64), - data: large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0]), - }, - Constant { - type_: tvec(SignatureToken::U128), - data: large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - }, - Constant { - type_: tvec(SignatureToken::U256), - data: large_vec(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, 0, 0, - 0, 0, 0, 0, - ]), - }, - Constant { - type_: tvec(SignatureToken::Address), - data: large_vec(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, 0, 0, - 0, 0, 0, 0, - ]), - }, - // double large - Constant { - type_: tvec(tvec(SignatureToken::Bool)), - data: double_vec(large_vec(vec![0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U8)), - data: double_vec(large_vec(vec![0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U16)), - data: double_vec(large_vec(vec![0, 0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U32)), - data: double_vec(large_vec(vec![0, 0, 0, 0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U64)), - data: double_vec(large_vec(vec![0, 0, 0, 0, 0, 0, 0, 0])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U128)), - data: double_vec(large_vec(vec![ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ])), - }, - Constant { - type_: tvec(tvec(SignatureToken::U256)), - data: double_vec(large_vec(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, 0, 0, - 0, 0, 0, 0, - ])), - }, - Constant { - type_: tvec(tvec(SignatureToken::Address)), - data: double_vec(large_vec(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, 0, 0, - 0, 0, 0, 0, - ])), - }, - ]; - let res = LimitsVerifier::verify_module(&config, &module); - - assert!(res.is_ok()); -} - -fn multi_struct(module: &mut CompiledModule, count: usize) { - for i in 0..count { - module - .identifiers - .push(Identifier::new(format!("A_{}", i)).unwrap()); - module.datatype_handles.push(DatatypeHandle { - module: module.self_module_handle_idx, - name: IdentifierIndex((module.identifiers.len() - 1) as u16), - abilities: AbilitySet::EMPTY, - type_parameters: vec![], - }); - module.struct_defs.push(StructDefinition { - struct_handle: DatatypeHandleIndex((module.datatype_handles.len() - 1) as u16), - field_information: StructFieldInformation::Declared(vec![]), - }); - } -} - -fn multi_fields(module: &mut CompiledModule, count: usize) { - for def in &mut module.struct_defs { - let mut fields = vec![]; - for i in 0..count { - module - .identifiers - .push(Identifier::new(format!("f_{}", i)).unwrap()); - fields.push(FieldDefinition { - name: Default::default(), - signature: TypeSignature(SignatureToken::U8), - }); - } - def.field_information = StructFieldInformation::Declared(fields); - } -} - -fn multi_fields_except_one(module: &mut CompiledModule, idx: usize, count: usize, one: usize) { - for (struct_idx, def) in module.struct_defs.iter_mut().enumerate() { - let mut fields = vec![]; - let count = if struct_idx == idx { one } else { count }; - for i in 0..count { - module - .identifiers - .push(Identifier::new(format!("f_{}", i)).unwrap()); - fields.push(FieldDefinition { - name: Default::default(), - signature: TypeSignature(SignatureToken::U8), - }); - } - def.field_information = StructFieldInformation::Declared(fields); - } -} - -fn multi_functions(module: &mut CompiledModule, count: usize) { - module.signatures.push(Signature(vec![])); - for i in 0..count { - module - .identifiers - .push(Identifier::new(format!("func_{}", i)).unwrap()); - module.function_handles.push(FunctionHandle { - module: module.self_module_handle_idx, - name: IdentifierIndex((module.identifiers.len() - 1) as u16), - parameters: SignatureIndex((module.signatures.len() - 1) as u16), - return_: SignatureIndex((module.signatures.len() - 1) as u16), - type_parameters: vec![], - }); - module.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex((module.function_handles.len() - 1) as u16), - visibility: Visibility::Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex((module.signatures.len() - 1) as u16), - code: vec![Bytecode::Ret], - jump_tables: vec![], - }), - }); - } -} - -fn leaf_module(name: &str) -> CompiledModule { - let mut module = empty_module(); - module.identifiers[0] = Identifier::new(name).unwrap(); - module.address_identifiers[0] = AccountAddress::ONE; - module -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/locals.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/locals.rs deleted file mode 100644 index 4789fd9131d..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/locals.rs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::{ - empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, - IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, - Visibility::Public, -}; -use move_bytecode_verifier_meter::bound::BoundMeter; -use move_core_types::{identifier::Identifier, vm_status::StatusCode}; - -use crate::unit_tests::production_config; - -#[test] -fn test_locals() { - // See also: github.com/aptos-labs/aptos-core/security/advisories/ - // GHSA-jjqw-f9pc-525j - let mut m = empty_module(); - - const MAX_BASIC_BLOCKS: u16 = 1024; - const MAX_LOCALS: u8 = 255; - const NUM_FUNCTIONS: u16 = 16; - - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(0), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Public, - is_entry: true, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Ret], - jump_tables: vec![], - }), - }); - - // signature of locals in f1..f - m.signatures.push(Signature( - std::iter::repeat(SignatureToken::U8) - .take(MAX_LOCALS as usize) - .collect(), - )); - - m.identifiers.push(Identifier::new("pwn").unwrap()); - - // create returns_bool_and_u64 - m.signatures - .push(Signature(vec![SignatureToken::Bool, SignatureToken::U8])); - m.identifiers - .push(Identifier::new("returns_bool_and_u64").unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(1), - parameters: SignatureIndex(0), - return_: SignatureIndex(2), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(1), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::LdTrue, Bytecode::LdU8(0), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - // create other functions - for i in 1..(NUM_FUNCTIONS + 1) { - m.identifiers - .push(Identifier::new(format!("f{}", i)).unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(i + 1), // the +1 accounts for returns_bool_and_u64 - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(i + 1), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(1), - code: vec![], - jump_tables: vec![], - }), - }); - - let code = &mut m.function_defs[i as usize + 1].code.as_mut().unwrap().code; - - for _ in 0..(MAX_BASIC_BLOCKS / 2 - MAX_LOCALS as u16 - 3) { - code.push(Bytecode::LdTrue); - code.push(Bytecode::BrTrue((code.len() + 2) as u16)); - code.push(Bytecode::Ret); - code.push(Bytecode::LdTrue); - code.push(Bytecode::BrTrue(0)); - } - for i in 0..MAX_LOCALS { - code.push(Bytecode::Call(FunctionHandleIndex(1))); // calls returns_bool_and_u64 - code.push(Bytecode::StLoc(i)); // i'th local is now available for the first time - code.push(Bytecode::BrTrue(0)); - } - code.push(Bytecode::Ret); - } - - let (verifier_config, meter_config) = production_config(); - let mut meter = BoundMeter::new(meter_config); - let result = move_bytecode_verifier::verify_module_with_config_for_test( - "test_locals", - &verifier_config, - &m, - &mut meter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::CONSTRAINT_NOT_SATISFIED - ); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs deleted file mode 100644 index bae3df1a339..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/loop_summary_tests.rs +++ /dev/null @@ -1,468 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_abstract_interpreter::control_flow_graph::VMControlFlowGraph; -use move_binary_format::file_format::Bytecode; -use move_bytecode_verifier::loop_summary::{LoopPartition, LoopSummary}; - -macro_rules! assert_node { - ( $summary:ident, $node:expr ; $block:expr, $preds:expr, $descs:expr, $backs:expr ) => { - let (s, n) = (&$summary, $node); - assert_eq!(s.block(n), $block, "Block"); - - let descs = $descs; - for d in descs { - assert!(s.is_descendant(n, *d), "{:?} -> {:?}", n, d) - } - - assert_eq!(s.pred_edges(n), $preds, "Predecessor Edges"); - assert_eq!(s.back_edges(n), $backs, "Back Edges"); - }; -} - -#[test] -fn linear_summary() { - let summary = { - use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new( - &[ - // B0, L0 - Nop, - // - Branch(2), - // B2, L1 - Nop, - // - Branch(4), - // B4, L2 - Ret, - ], - &[], - )) - }; - - let n: Vec<_> = summary.preorder().collect(); - - assert_eq!(n.len(), 3); - - assert_node!( - summary, n[0]; - /* block */ 0, - /* preds */ &[], - /* descs */ &[n[1], n[2]], - /* backs */ &[] - ); - - assert_node!( - summary, n[1]; - /* block */ 2, - /* preds */ &[n[0]], - /* descs */ &[n[2]], - /* backs */ &[] - ); - - assert_node!( - summary, n[2]; - /* block */ 4, - /* preds */ &[n[1]], - /* descs */ &[], - /* backs */ &[] - ); -} - -#[test] -fn non_loop_back_branch_summary() { - let summary = { - use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new( - &[ - // B0, L0 - Nop, - // - Branch(3), - // B2, L2 - Ret, - // B3, L1 - Branch(2), - ], - &[], - )) - }; - - let n: Vec<_> = summary.preorder().collect(); - - assert_eq!(n.len(), 3); - - assert_node!( - summary, n[0]; - /* block */ 0, - /* preds */ &[], - /* descs */ &[n[1], n[2]], - /* backs */ &[] - ); - - assert_node!( - summary, n[1]; - /* block */ 3, - /* preds */ &[n[0]], - /* descs */ &[n[2]], - /* backs */ &[] - ); - - assert_node!( - summary, n[2]; - /* block */ 2, - /* preds */ &[n[1]], - /* descs */ &[], - /* backs */ &[] - ); -} - -#[test] -fn branching_summary() { - let summary = { - use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new( - &[ - // B0, L0 - LdTrue, - // - BrTrue(3), - // B2, L2 - Nop, - // B3, L1 - Ret, - ], - &[], - )) - }; - - let n: Vec<_> = summary.preorder().collect(); - - assert_eq!(n.len(), 3); - - assert_node!( - summary, n[0]; - /* block */ 0, - /* preds */ &[], - /* descs */ &[n[1], n[2]], - /* backs */ &[] - ); - - assert_node!( - summary, n[1]; - /* block */ 3, - /* preds */ &[n[0], n[2]], - /* descs */ &[], - /* backs */ &[] - ); - - assert_node!( - summary, n[2]; - /* block */ 2, - /* preds */ &[n[0]], - /* descs */ &[], - /* backs */ &[] - ); - - // Although L2 -> L1 is an edge in the CFG, it's not an edge in the DFST, so L2 - // is said to have no descendants. - assert!(!summary.is_descendant(n[2], n[1])); -} - -#[test] -fn looping_summary() { - let summary = { - use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new( - &[ - // B0, L0 - LdTrue, - // - BrTrue(4), - // B2, L2 - Nop, - // - Branch(0), - // B4, L1 - Ret, - ], - &[], - )) - }; - - let n: Vec<_> = summary.preorder().collect(); - - assert_eq!(n.len(), 3); - - assert_node!( - summary, n[0]; - /* block */ 0, - /* preds */ &[], - /* descs */ &[n[1], n[2]], - /* backs */ &[n[2]] - ); - - assert_node!( - summary, n[1]; - /* block */ 4, - /* preds */ &[n[0]], - /* descs */ &[], - /* backs */ &[] - ); - - assert_node!( - summary, n[2]; - /* block */ 2, - /* preds */ &[n[0]], - /* descs */ &[], - /* backs */ &[] - ); -} - -#[test] -fn branches_in_loops_summary() { - let summary = { - use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new( - &[ - // B0, L0 - LdTrue, - // - BrTrue(3), - // B2, L3 - Nop, - // B3, L1 - LdFalse, - // - BrFalse(0), - // B5, L2 - Ret, - ], - &[], - )) - }; - - let n: Vec<_> = summary.preorder().collect(); - - assert_eq!(n.len(), 4); - - assert_node!( - summary, n[0]; - /* block */ 0, - /* preds */ &[], - /* descs */ &[n[1], n[2], n[3]], - /* backs */ &[n[1]] - ); - - assert_node!( - summary, n[1]; - /* block */ 3, - /* preds */ &[n[0], n[3]], - /* descs */ &[n[2]], - /* backs */ &[] - ); - - assert_node!( - summary, n[2]; - /* block */ 5, - /* preds */ &[n[1]], - /* descs */ &[], - /* backs */ &[] - ); - - assert_node!( - summary, n[3]; - /* block */ 2, - /* preds */ &[n[0]], - /* descs */ &[], - /* backs */ &[] - ); -} - -#[test] -fn loops_in_branches_summary() { - let summary = { - use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new( - &[ - // B0, L0 - LdTrue, - // - BrTrue(8), - // B2, L5 - Nop, - // B3, L6 - LdFalse, - // - BrFalse(3), - // B5, L7 - LdTrue, - // - BrTrue(2), - // B7, L8 - Branch(13), - // B8, L1 - Nop, - // B9, L2 - LdTrue, - // - BrTrue(8), - // B11, L3 - LdFalse, - // - BrFalse(9), - // B13, L4 - Ret, - ], - &[], - )) - }; - - let n: Vec<_> = summary.preorder().collect(); - - assert_eq!(n.len(), 9); - - assert_node!( - summary, n[0]; - /* block */ 0, - /* preds */ &[], - /* descs */ &[n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8]], - /* backs */ &[] - ); - - assert_node!( - summary, n[1]; - /* block */ 8, - /* preds */ &[n[0]], - /* descs */ &[n[2], n[3], n[4]], - /* backs */ &[n[2]] - ); - - assert_node!( - summary, n[2]; - /* block */ 9, - /* preds */ &[n[1]], - /* descs */ &[n[3], n[4]], - /* backs */ &[n[3]] - ); - - assert_node!( - summary, n[3]; - /* block */ 11, - /* preds */ &[n[2]], - /* descs */ &[n[4]], - /* backs */ &[] - ); - - assert_node!( - summary, n[4]; - /* block */ 13, - /* preds */ &[n[3], n[8]], - /* descs */ &[], - /* backs */ &[] - ); - - assert_node!( - summary, n[5]; - /* block */ 2, - /* preds */ &[n[0]], - /* descs */ &[n[6], n[7], n[8]], - /* backs */ &[n[7]] - ); - - assert_node!( - summary, n[6]; - /* block */ 3, - /* preds */ &[n[5]], - /* descs */ &[n[7], n[8]], - /* backs */ &[n[6]] - ); - - assert_node!( - summary, n[7]; - /* block */ 5, - /* preds */ &[n[6]], - /* descs */ &[n[8]], - /* backs */ &[] - ); - - assert_node!( - summary, n[8]; - /* block */ 7, - /* preds */ &[n[7]], - /* descs */ &[], - /* backs */ &[] - ); -} - -#[test] -fn loop_collapsing() { - let summary = { - use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new( - &[ - // B0, L0 - LdTrue, - // - BrTrue(4), - // B2, L2 - Nop, - // - Branch(0), - // B4, L1 - Ret, - ], - &[], - )) - }; - - let mut partition = LoopPartition::new(&summary); - let n: Vec<_> = summary.preorder().collect(); - - for id in &n { - assert_eq!(*id, partition.containing_loop(*id), "Self-parent {:?}", id); - } - - assert_eq!(partition.collapse_loop(n[0], &[n[2]].into()), 1); - assert_eq!(partition.containing_loop(n[0]), n[0]); - assert_eq!(partition.containing_loop(n[1]), n[1]); - assert_eq!(partition.containing_loop(n[2]), n[0]); -} - -#[test] -fn nested_loop_collapsing() { - let summary = { - use Bytecode::*; - LoopSummary::new(&VMControlFlowGraph::new( - &[ - // B0, L0 - Nop, - // B1, L1 - LdTrue, - // - BrTrue(1), - // B3, L2 - LdFalse, - // - BrFalse(0), - // B5, L3 - LdTrue, - // - BrTrue(0), - // B7, L4 - Ret, - ], - &[], - )) - }; - - let mut partition = LoopPartition::new(&summary); - let n: Vec<_> = summary.preorder().collect(); - - // Self-loop is a special case -- its depth should still be bumped. - assert_eq!(partition.collapse_loop(n[1], &[].into()), 1); - assert_eq!(partition.collapse_loop(n[0], &[n[1], n[2]].into()), 2); - assert_eq!(partition.collapse_loop(n[0], &[n[0], n[3]].into()), 3); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs deleted file mode 100644 index b8b488cbafb..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/many_back_edges.rs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::{ - empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, - IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, - Visibility::Public, -}; -use move_bytecode_verifier_meter::bound::BoundMeter; -use move_core_types::{identifier::Identifier, vm_status::StatusCode}; - -use crate::unit_tests::production_config; - -const MAX_BASIC_BLOCKS: u16 = 1024; -const MAX_LOCALS: u8 = 255; - -const NUM_FUNCTIONS: u16 = 16; - -#[test] -fn many_backedges() { - let mut m = empty_module(); - - // signature of locals in f1..f - m.signatures.push(Signature( - std::iter::repeat(SignatureToken::U8) - .take(MAX_LOCALS as usize) - .collect(), - )); - - // create returns_bool_and_u64 - m.signatures - .push(Signature(vec![SignatureToken::Bool, SignatureToken::U8])); - m.identifiers - .push(Identifier::new("returns_bool_and_u64").unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(1), - parameters: SignatureIndex(0), - return_: SignatureIndex(2), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::LdTrue, Bytecode::LdU8(0), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - // create other functions - for i in 1..(NUM_FUNCTIONS + 1) { - m.identifiers - .push(Identifier::new(format!("f{}", i)).unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(i + 1), // the +1 accounts for returns_bool_and_u64 - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(i), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(1), - code: vec![], - jump_tables: vec![], - }), - }); - - let code = &mut m.function_defs[i as usize].code.as_mut().unwrap().code; - - for _ in 0..(MAX_BASIC_BLOCKS - MAX_LOCALS as u16 - 2) { - code.push(Bytecode::LdTrue); - code.push(Bytecode::BrTrue(0)); - } - for i in 0..MAX_LOCALS { - code.push(Bytecode::Call(FunctionHandleIndex(0))); // calls returns_bool_and_u64 - code.push(Bytecode::StLoc(i)); // i'th local is now available for the first time - code.push(Bytecode::BrTrue(0)); - } - code.push(Bytecode::Ret); - } - - let (verifier_config, meter_config) = production_config(); - let mut meter = BoundMeter::new(meter_config); - let result = move_bytecode_verifier::verify_module_with_config_for_test( - "many_backedges", - &verifier_config, - &m, - &mut meter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::CONSTRAINT_NOT_SATISFIED - ); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/mod.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/mod.rs deleted file mode 100644 index 4ed2fb574f7..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/mod.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format_common::VERSION_MAX; -use move_vm_config::verifier::{ - MeterConfig, VerifierConfig, DEFAULT_MAX_CONSTANT_VECTOR_LEN, DEFAULT_MAX_IDENTIFIER_LENGTH, - DEFAULT_MAX_VARIANTS, -}; - -pub mod binary_samples; -pub mod bounds_tests; -pub mod code_unit_tests; -pub mod constants_tests; -pub mod control_flow_tests; -pub mod duplication_tests; -pub mod generic_ops_tests; -pub mod large_type_test; -pub mod limit_tests; -pub mod locals; -pub mod loop_summary_tests; -pub mod many_back_edges; -pub mod negative_stack_size_tests; -pub mod reference_safety_tests; -pub mod signature_tests; -pub mod vec_pack_tests; - -/// Configuration used in production. -pub(crate) fn production_config() -> (VerifierConfig, MeterConfig) { - ( - VerifierConfig { - 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_push_size: Some(10000), - max_dependency_depth: Some(100), - max_data_definitions: Some(200), - max_fields_in_struct: Some(30), - max_function_definitions: Some(1000), - - // Do not use back edge constraints as they are superseded by metering - max_back_edges_per_function: None, - max_back_edges_per_module: None, - - max_constant_vector_len: Some(DEFAULT_MAX_CONSTANT_VECTOR_LEN), - max_identifier_len: Some(DEFAULT_MAX_IDENTIFIER_LENGTH), - bytecode_version: VERSION_MAX, - max_variants_in_enum: Some(DEFAULT_MAX_VARIANTS), - }, - MeterConfig::old_default(), - ) -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/negative_stack_size_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/negative_stack_size_tests.rs deleted file mode 100644 index 56844c517a1..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/negative_stack_size_tests.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::Bytecode; -use move_bytecode_verifier::{ability_cache::AbilityCache, code_unit_verifier}; -use move_bytecode_verifier_meter::dummy::DummyMeter; -use move_core_types::vm_status::StatusCode; - -use crate::support::dummy_procedure_module; - -#[test] -fn one_pop_no_push() { - let module = &dummy_procedure_module(vec![Bytecode::Pop, Bytecode::Ret]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::NEGATIVE_STACK_SIZE_WITHIN_BLOCK - ); -} - -#[test] -fn one_pop_one_push() { - // Height: 0 + (-1 + 1) = 0 would have passed original usage verifier - let module = &dummy_procedure_module(vec![Bytecode::ReadRef, Bytecode::Ret]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::NEGATIVE_STACK_SIZE_WITHIN_BLOCK - ); -} - -#[test] -fn two_pop_one_push() { - // Height: 0 + 1 + (-2 + 1) = 0 would have passed original usage verifier - let module = &dummy_procedure_module(vec![Bytecode::LdU64(0), Bytecode::Add, Bytecode::Ret]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::NEGATIVE_STACK_SIZE_WITHIN_BLOCK - ); -} - -#[test] -fn two_pop_no_push() { - let module = &dummy_procedure_module(vec![Bytecode::WriteRef, Bytecode::Ret]); - let ability_cache = &mut AbilityCache::new(module); - let result = code_unit_verifier::verify_module( - &Default::default(), - module, - ability_cache, - &mut DummyMeter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::NEGATIVE_STACK_SIZE_WITHIN_BLOCK - ); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs deleted file mode 100644 index 8be4f8a621b..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/reference_safety_tests.rs +++ /dev/null @@ -1,454 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::{ - empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, - IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, - Visibility::Public, -}; -use move_bytecode_verifier_meter::bound::BoundMeter; -use move_core_types::{identifier::Identifier, vm_status::StatusCode}; - -use crate::unit_tests::production_config; - -#[test] -fn test_bicliques() { - // See also: github.com/aptos-labs/aptos-core/security/advisories/ - // GHSA-xm6p-ffcq-5p2v - const NUM_LOCALS: u8 = 128; - const NUM_CALLS: u16 = 76; - const NUM_FUNCTIONS: u16 = 1; - - let mut m = empty_module(); - - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(0), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - // create take_and_return_references - m.signatures.push(Signature( - std::iter::repeat(SignatureToken::Reference(Box::new(SignatureToken::U64))) - .take(NUM_LOCALS as usize) - .collect(), - )); - m.identifiers - .push(Identifier::new("take_and_return_references").unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(1), - parameters: SignatureIndex(1), - return_: SignatureIndex(1), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(1), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![], - jump_tables: vec![], - }), - }); - let code = &mut m.function_defs[1].code.as_mut().unwrap().code; - for i in 0..NUM_LOCALS { - code.push(Bytecode::MoveLoc(i)); - } - code.push(Bytecode::Ret); - - // create swallow_references - m.identifiers - .push(Identifier::new("swallow_references").unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(2), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(2), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Ret], - jump_tables: vec![], - }), - }); - - // create other functions - for i in 1..(NUM_FUNCTIONS + 1) { - m.identifiers - .push(Identifier::new(format!("f{}", i)).unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(i + 2), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(i + 2), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![], - jump_tables: vec![], - }), - }); - let code = &mut m.function_defs[i as usize + 2].code.as_mut().unwrap().code; - for j in 0..NUM_LOCALS { - code.push(Bytecode::CopyLoc(j)); - } - for _ in 0..NUM_CALLS { - code.push(Bytecode::Call(FunctionHandleIndex(1))); - } - code.push(Bytecode::Call(FunctionHandleIndex(2))); - code.push(Bytecode::Ret); - } - - let (verifier_config, meter_config) = production_config(); - let mut meter = BoundMeter::new(meter_config); - let result = move_bytecode_verifier::verify_module_with_config_for_test( - "test_bicliques", - &verifier_config, - &m, - &mut meter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::CONSTRAINT_NOT_SATISFIED - ); -} - -#[test] -fn test_merge_state_large_graph() { - // See also: github.com/aptos-labs/aptos-core/security/advisories/ - // GHSA-g8v8-fw4c-8h82 - const N: u8 = 127; - const NUM_NOP_BLOCKS: u16 = 950; - const NUM_FUNCTIONS: u16 = 18; - - let mut m = empty_module(); - - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(0), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - m.signatures.push(Signature( - std::iter::repeat(SignatureToken::Reference(Box::new(SignatureToken::U8))) - .take(N as usize) - .collect(), - )); - - m.identifiers.push(Identifier::new("return_refs").unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(1), - parameters: SignatureIndex(0), - return_: SignatureIndex(1), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(1), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - m.identifiers - .push(Identifier::new("take_and_return_refs").unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(2), - parameters: SignatureIndex(1), - return_: SignatureIndex(1), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(2), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Call(FunctionHandleIndex(1)), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - for i in 0..NUM_FUNCTIONS { - m.identifiers - .push(Identifier::new(format!("f{}", i)).unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(i + 3), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(i + 3), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(1), - code: vec![], - jump_tables: vec![], - }), - }); - let code = &mut m.function_defs[i as usize + 3].code.as_mut().unwrap().code; - for j in 0..N { - code.push(Bytecode::CopyLoc(j)); - } - code.push(Bytecode::Call(FunctionHandleIndex(2))); - for j in 0..N { - code.push(Bytecode::StLoc(N + j)); - } - for _ in 0..NUM_NOP_BLOCKS { - code.push(Bytecode::LdTrue); - code.push(Bytecode::BrTrue(0)); - } - - code.push(Bytecode::Ret); - } - - let (verifier_config, meter_config) = production_config(); - let mut meter = BoundMeter::new(meter_config); - let result = move_bytecode_verifier::verify_module_with_config_for_test( - "test_merge_state_large_graph", - &verifier_config, - &m, - &mut meter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::CONSTRAINT_NOT_SATISFIED - ); -} - -#[test] -fn test_merge_state() { - // See also: github.com/aptos-labs/aptos-core/security/advisories/ - // GHSA-g8v8-fw4c-8h82 - const NUM_NOP_BLOCKS: u16 = 965; - const NUM_LOCALS: u8 = 32; - const NUM_FUNCTIONS: u16 = 21; - - let mut m = empty_module(); - - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(0), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Bytecode::Call(FunctionHandleIndex(0)), Bytecode::Ret], - jump_tables: vec![], - }), - }); - - m.signatures - .push(Signature(vec![SignatureToken::Reference(Box::new( - SignatureToken::U8, - ))])); - m.signatures.push(Signature( - std::iter::repeat(SignatureToken::Reference(Box::new(SignatureToken::U8))) - .take(NUM_LOCALS as usize - 1) - .collect(), - )); - - for i in 0..NUM_FUNCTIONS { - m.identifiers - .push(Identifier::new(format!("f{}", i)).unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(i + 1), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(i + 1), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(2), - code: vec![], - jump_tables: vec![], - }), - }); - let code = &mut m.function_defs[i as usize + 1].code.as_mut().unwrap().code; - // create reference id - code.push(Bytecode::CopyLoc(0)); - code.push(Bytecode::StLoc(1)); - // create a path of length NUM_LOCALS - 1 in the borrow graph - for j in 0..(NUM_LOCALS - 2) { - // create Ref(new_id) and factor in empty-path edge id -> new_id - code.push(Bytecode::CopyLoc(1)); - // can't leave those references on stack since basic blocks need to be - // stack-neutral - code.push(Bytecode::StLoc(j + 2)); - } - for _ in 0..NUM_NOP_BLOCKS { - code.push(Bytecode::LdTrue); - // create back edge to first block - code.push(Bytecode::BrTrue(0)); - } - - code.push(Bytecode::Ret); - } - - let (verifier_config, meter_config) = production_config(); - let mut meter = BoundMeter::new(meter_config); - let result = move_bytecode_verifier::verify_module_with_config_for_test( - "test_merge_state", - &verifier_config, - &m, - &mut meter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::CONSTRAINT_NOT_SATISFIED - ); -} - -#[test] -fn test_copyloc_pop() { - // See also: github.com/aptos-labs/aptos-core/security/advisories/ - // GHSA-2qvr-c9qp-wch7 - const NUM_COPYLOCS: u16 = 1880; - const NUM_CHILDREN: u16 = 1020; - const NUM_FUNCTIONS: u16 = 2; - - let mut m = empty_module(); - - // parameters of f0, f1, ... - m.signatures - .push(Signature(vec![SignatureToken::Reference(Box::new( - SignatureToken::Vector(Box::new(SignatureToken::U8)), - ))])); - // locals of f0, f1, ... - m.signatures.push(Signature(vec![ - SignatureToken::Reference(Box::new(SignatureToken::Vector(Box::new( - SignatureToken::U8, - )))), - SignatureToken::U8, /* ignore this, it's just here because I don't want to fix indices - * and the TypeParameter after removing the collision */ - ])); - // for VecImmBorrow - m.signatures.push(Signature( - std::iter::repeat(SignatureToken::U8).take(1).collect(), - )); - m.signatures - .push(Signature(vec![SignatureToken::TypeParameter(0)])); - - for i in 0..NUM_FUNCTIONS { - m.identifiers - .push(Identifier::new(format!("f{}", i)).unwrap()); - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(i), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(i), - visibility: Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(2), - code: vec![], - jump_tables: vec![], - }), - }); - let code = &mut m.function_defs[i as usize].code.as_mut().unwrap().code; - - // create reference id - code.push(Bytecode::CopyLoc(0)); - code.push(Bytecode::StLoc(1)); - // create NUM_CHLIDREN children of id - for _ in 0..NUM_CHILDREN { - code.push(Bytecode::CopyLoc(1)); - code.push(Bytecode::LdU64(0)); - code.push(Bytecode::VecImmBorrow(SignatureIndex(3))); - } - // then do a whole lot of copylocs on that reference - for _ in 0..NUM_COPYLOCS { - code.push(Bytecode::CopyLoc(1)); - code.push(Bytecode::Pop); - } - for _ in 0..NUM_CHILDREN { - code.push(Bytecode::Pop); - } - - code.push(Bytecode::Ret); - } - - let (verifier_config, meter_config) = production_config(); - let mut meter = BoundMeter::new(meter_config); - let result = move_bytecode_verifier::verify_module_with_config_for_test( - "test_copyloc_pop", - &verifier_config, - &m, - &mut meter, - ); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::CONSTRAINT_NOT_SATISFIED - ); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs deleted file mode 100644 index 5e9ad8923fc..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/signature_tests.rs +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::{ - Bytecode::*, CompiledModule, SignatureToken::*, Visibility::Public, *, -}; -use move_bytecode_verifier::{ - ability_cache::AbilityCache, verify_module_unmetered, verify_module_with_config_for_test, - SignatureChecker, -}; -use move_bytecode_verifier_meter::dummy::DummyMeter; -use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, -}; - -use crate::unit_tests::production_config; - -#[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 ability_cache = &mut AbilityCache::new(&m); - let errors = SignatureChecker::verify_module(&m, ability_cache, &mut DummyMeter); - assert!(errors.is_err()); -} - -#[test] -fn no_verify_locals_good() { - let compiled_module_good = CompiledModule { - version: move_binary_format::file_format_common::VERSION_MAX, - module_handles: vec![ModuleHandle { - address: AddressIdentifierIndex(0), - name: IdentifierIndex(0), - }], - self_module_handle_idx: ModuleHandleIndex(0), - datatype_handles: vec![], - signatures: vec![ - Signature(vec![Address]), - Signature(vec![U64]), - Signature(vec![]), - ], - function_handles: vec![ - FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(1), - return_: SignatureIndex(2), - parameters: SignatureIndex(0), - type_parameters: vec![], - }, - FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(2), - return_: SignatureIndex(2), - parameters: SignatureIndex(1), - type_parameters: vec![], - }, - ], - field_handles: vec![], - friend_decls: vec![], - struct_def_instantiations: vec![], - function_instantiations: vec![], - field_instantiations: vec![], - identifiers: vec![ - Identifier::new("Bad").unwrap(), - Identifier::new("blah").unwrap(), - Identifier::new("foo").unwrap(), - ], - address_identifiers: vec![AccountAddress::new([0; AccountAddress::LENGTH])], - constant_pool: vec![], - metadata: vec![], - struct_defs: vec![], - function_defs: vec![ - FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Visibility::Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![Ret], - jump_tables: vec![], - }), - }, - FunctionDefinition { - function: FunctionHandleIndex(1), - visibility: Visibility::Public, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(1), - code: vec![Ret], - jump_tables: vec![], - }), - }, - ], - enum_defs: vec![], - enum_def_instantiations: vec![], - variant_handles: vec![], - variant_instantiation_handles: vec![], - }; - assert!(verify_module_unmetered(&compiled_module_good).is_ok()); -} - -#[test] -fn big_signature_test() { - const N_TYPE_PARAMS: usize = 5; - const INSTANTIATION_DEPTH: usize = 3; - const VECTOR_DEPTH: usize = 250; - let mut st = SignatureToken::U8; - for _ in 0..VECTOR_DEPTH { - st = SignatureToken::Vector(Box::new(st)); - } - for _ in 0..INSTANTIATION_DEPTH { - let type_params = vec![st; N_TYPE_PARAMS]; - st = SignatureToken::DatatypeInstantiation(Box::new((DatatypeHandleIndex(0), type_params))); - } - - const N_READPOP: u16 = 7500; - - let mut code = vec![]; - // 1. ImmBorrowLoc: ... ref - // 2. ReadRef: ... value - // 3. Pop: ... - for _ in 0..N_READPOP { - code.push(Bytecode::ImmBorrowLoc(0)); - code.push(Bytecode::ReadRef); - code.push(Bytecode::Pop); - } - code.push(Bytecode::Ret); - - let type_param_constraints = DatatypeTyParameter { - constraints: AbilitySet::EMPTY, - is_phantom: false, - }; - - let module = CompiledModule { - version: 5, - self_module_handle_idx: ModuleHandleIndex(0), - module_handles: vec![ModuleHandle { - address: AddressIdentifierIndex(0), - name: IdentifierIndex(0), - }], - datatype_handles: vec![DatatypeHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(1), - abilities: AbilitySet::ALL, - type_parameters: vec![type_param_constraints; N_TYPE_PARAMS], - }], - function_handles: vec![FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(0), - parameters: SignatureIndex(1), - return_: SignatureIndex(0), - type_parameters: vec![], - }], - field_handles: vec![], - friend_decls: vec![], - struct_def_instantiations: vec![], - function_instantiations: vec![], - field_instantiations: vec![], - signatures: vec![Signature(vec![]), Signature(vec![st])], - identifiers: vec![ - Identifier::new("f").unwrap(), - Identifier::new("generic_struct").unwrap(), - ], - address_identifiers: vec![AccountAddress::ONE], - constant_pool: vec![], - metadata: vec![], - struct_defs: vec![StructDefinition { - struct_handle: DatatypeHandleIndex(0), - field_information: StructFieldInformation::Native, - }], - function_defs: vec![FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Public, - is_entry: true, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code, - jump_tables: vec![], - }), - }], - enum_def_instantiations: vec![], - enum_defs: vec![], - variant_handles: vec![], - variant_instantiation_handles: vec![], - }; - - // save module and verify that it can ser/de - let mut mvbytes = vec![]; - module.serialize(&mut mvbytes).unwrap(); - let module = CompiledModule::deserialize_with_defaults(&mvbytes).unwrap(); - - let res = verify_module_with_config_for_test( - "big_signature_test", - &production_config().0, - &module, - &mut DummyMeter, - ) - .unwrap_err(); - assert_eq!(res.major_status(), StatusCode::TOO_MANY_TYPE_NODES); -} diff --git a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs b/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs deleted file mode 100644 index 1f7c54d8991..00000000000 --- a/external-crates/move/move-execution/v0/crates/bytecode-verifier-tests/src/unit_tests/vec_pack_tests.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::file_format::{ - empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, - IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, Visibility, -}; -use move_bytecode_verifier_meter::dummy::DummyMeter; -use move_core_types::{identifier::Identifier, vm_status::StatusCode}; - -use crate::unit_tests::production_config; - -fn vec_sig(len: usize) -> SignatureToken { - if len > 0 { - SignatureToken::Vector(Box::new(vec_sig(len - 1))) - } else { - SignatureToken::U8 - } -} - -#[test] -fn test_vec_pack() { - let mut m = empty_module(); - - let sig = SignatureIndex(m.signatures.len() as u16); - m.signatures.push(Signature(vec![vec_sig(255)])); - - m.function_defs.push(FunctionDefinition { - function: FunctionHandleIndex(0), - visibility: Visibility::Private, - is_entry: false, - acquires_global_resources: vec![], - code: Some(CodeUnit { - locals: SignatureIndex(0), - code: vec![], - jump_tables: vec![], - }), - }); - - m.function_handles.push(FunctionHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(m.identifiers.len() as u16), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), - type_parameters: vec![], - }); - m.identifiers - .push(Identifier::new("foo".to_string()).unwrap()); - - const COUNT: usize = 3000; - - 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::once(&[Bytecode::Pop, Bytecode::Ret][..])) - .flatten() - .cloned() - .collect(); - - let res = move_bytecode_verifier::verify_module_with_config_for_test( - "test_vec_pack", - &production_config().0, - &m, - &mut DummyMeter, - ) - .unwrap_err(); - assert_eq!(res.major_status(), StatusCode::VALUE_STACK_PUSH_OVERFLOW); -} diff --git a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/Cargo.toml b/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/Cargo.toml deleted file mode 100644 index b0dd9fc240b..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "move-abstract-interpreter-v0" -version = "0.1.0" -authors = ["The Move Contributors"] -edition = "2021" -license = "Apache-2.0" -publish = false -description = "Move abstract interpreter" - -[dependencies] -move-binary-format.workspace = true -move-bytecode-verifier-meter.workspace = true - -[dev-dependencies] -itertools.workspace = true - -[features] -default = [] diff --git a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/absint.rs b/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/absint.rs deleted file mode 100644 index 480ff082c60..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/absint.rs +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use std::collections::BTreeMap; - -use move_binary_format::{ - errors::PartialVMResult, - file_format::{ - AbilitySet, Bytecode, CodeOffset, CodeUnit, FunctionDefinitionIndex, FunctionHandle, - Signature, - }, - CompiledModule, -}; -use move_bytecode_verifier_meter::{Meter, Scope}; - -use crate::control_flow_graph::{BlockId, ControlFlowGraph, VMControlFlowGraph}; - -/// A `FunctionContext` holds all the information needed by the verifier for -/// `FunctionDefinition`.` A control flow graph is built for a function when the -/// `FunctionContext` is created. -pub struct FunctionContext<'a> { - index: Option, - code: &'a CodeUnit, - parameters: &'a Signature, - return_: &'a Signature, - locals: &'a Signature, - type_parameters: &'a [AbilitySet], - cfg: VMControlFlowGraph, -} - -/// Trait for finite-height abstract domains. Infinite height domains would -/// require a more complex trait with widening and a partial order. -pub trait AbstractDomain: Clone + Sized { - fn join( - &mut self, - other: &Self, - meter: &mut (impl Meter + ?Sized), - ) -> PartialVMResult; -} - -#[derive(Debug)] -pub enum JoinResult { - Changed, - Unchanged, -} - -#[allow(dead_code)] -#[derive(Clone)] -pub struct BlockInvariant { - /// Precondition of the block - pre: State, -} - -/// A map from block id's to the pre/post of each block after a fixed point is -/// reached. -#[allow(dead_code)] -pub type InvariantMap = BTreeMap>; - -/// Costs for metered verification -const ANALYZE_FUNCTION_BASE_COST: u128 = 10; -const EXECUTE_BLOCK_BASE_COST: u128 = 10; -const PER_BACKEDGE_COST: u128 = 10; -const PER_SUCCESSOR_COST: u128 = 10; - -/// Take a pre-state + instruction and mutate it to produce a post-state -/// Auxiliary data can be stored in self. -pub trait TransferFunctions { - type State: AbstractDomain; - type Error; - - /// Execute local@instr found at index local@index in the current basic - /// block from pre-state local@pre. - /// Should return an AnalysisError if executing the instruction is - /// unsuccessful, and () if the effects of successfully executing - /// local@instr have been reflected by mutatating local@pre. - /// Auxiliary data from the analysis that is not part of the abstract state - /// can be collected by mutating local@self. - /// The last instruction index in the current block is local@last_index. - /// Knowing this information allows clients to detect the end of a basic - /// block and special-case appropriately (e.g., normalizing the abstract - /// state before a join). - fn execute( - &mut self, - pre: &mut Self::State, - instr: &Bytecode, - index: CodeOffset, - last_index: CodeOffset, - meter: &mut (impl Meter + ?Sized), - ) -> PartialVMResult<()>; -} - -pub trait AbstractInterpreter: TransferFunctions { - /// Analyze procedure local@function_context starting from pre-state - /// local@initial_state. - fn analyze_function( - &mut self, - initial_state: Self::State, - function_context: &FunctionContext, - meter: &mut (impl Meter + ?Sized), - ) -> PartialVMResult<()> { - meter.add(Scope::Function, ANALYZE_FUNCTION_BASE_COST)?; - let mut inv_map = InvariantMap::new(); - let entry_block_id = function_context.cfg().entry_block_id(); - let mut next_block = Some(entry_block_id); - inv_map.insert(entry_block_id, BlockInvariant { pre: initial_state }); - - while let Some(block_id) = next_block { - let block_invariant = match inv_map.get_mut(&block_id) { - Some(invariant) => invariant, - None => { - // This can only happen when all predecessors have errors, - // so skip the block and move on to the next one - next_block = function_context.cfg().next_block(block_id); - continue; - } - }; - - let pre_state = &block_invariant.pre; - // Note: this will stop analysis after the first error occurs, to avoid the risk - // of subsequent crashes - let post_state = self.execute_block(block_id, pre_state, function_context, meter)?; - - let mut next_block_candidate = function_context.cfg().next_block(block_id); - // propagate postcondition of this block to successor blocks - for successor_block_id in function_context.cfg().successors(block_id) { - meter.add(Scope::Function, PER_SUCCESSOR_COST)?; - match inv_map.get_mut(successor_block_id) { - Some(next_block_invariant) => { - let join_result = { - let old_pre = &mut next_block_invariant.pre; - old_pre.join(&post_state, meter) - }?; - match join_result { - JoinResult::Unchanged => { - // Pre is the same after join. Reanalyzing this - // block would produce - // the same post - } - JoinResult::Changed => { - // If the cur->successor is a back edge, jump back to the beginning - // of the loop, instead of the normal next block - if function_context - .cfg() - .is_back_edge(block_id, *successor_block_id) - { - meter.add(Scope::Function, PER_BACKEDGE_COST)?; - next_block_candidate = Some(*successor_block_id); - break; - } - } - } - } - None => { - // Haven't visited the next block yet. Use the post of the current block as - // its pre - inv_map.insert( - *successor_block_id, - BlockInvariant { - pre: post_state.clone(), - }, - ); - } - } - } - next_block = next_block_candidate; - } - Ok(()) - } - - fn execute_block( - &mut self, - block_id: BlockId, - pre_state: &Self::State, - function_context: &FunctionContext, - meter: &mut (impl Meter + ?Sized), - ) -> PartialVMResult { - meter.add(Scope::Function, EXECUTE_BLOCK_BASE_COST)?; - let mut state_acc = pre_state.clone(); - let block_end = function_context.cfg().block_end(block_id); - for offset in function_context.cfg().instr_indexes(block_id) { - let instr = &function_context.code().code[offset as usize]; - self.execute(&mut state_acc, instr, offset, block_end, meter)? - } - Ok(state_acc) - } -} - -impl<'a> FunctionContext<'a> { - // Creates a `FunctionContext` for a module function. - pub fn new( - module: &'a CompiledModule, - index: FunctionDefinitionIndex, - code: &'a CodeUnit, - function_handle: &'a FunctionHandle, - ) -> Self { - Self { - index: Some(index), - code, - parameters: module.signature_at(function_handle.parameters), - return_: module.signature_at(function_handle.return_), - locals: module.signature_at(code.locals), - type_parameters: &function_handle.type_parameters, - cfg: VMControlFlowGraph::new(&code.code, &code.jump_tables), - } - } - - pub fn index(&self) -> Option { - self.index - } - - pub fn code(&self) -> &'a CodeUnit { - self.code - } - - pub fn parameters(&self) -> &'a Signature { - self.parameters - } - - pub fn return_(&self) -> &'a Signature { - self.return_ - } - - pub fn locals(&self) -> &'a Signature { - self.locals - } - - pub fn type_parameters(&self) -> &'a [AbilitySet] { - self.type_parameters - } - - pub fn cfg(&self) -> &VMControlFlowGraph { - &self.cfg - } -} diff --git a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/control_flow_graph.rs b/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/control_flow_graph.rs deleted file mode 100644 index 1ee2a267829..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/control_flow_graph.rs +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -//! This module defines the control-flow graph uses for bytecode verification. -use move_binary_format::file_format::{Bytecode, CodeOffset, VariantJumpTable}; -use std::collections::{btree_map::Entry, BTreeMap, BTreeSet}; - -// BTree/Hash agnostic type wrappers -type Map = BTreeMap; -type Set = BTreeSet; - -pub type BlockId = CodeOffset; - -/// A trait that specifies the basic requirements for a CFG -pub trait ControlFlowGraph { - /// Start index of the block ID in the bytecode vector - fn block_start(&self, block_id: BlockId) -> CodeOffset; - - /// End index of the block ID in the bytecode vector - fn block_end(&self, block_id: BlockId) -> CodeOffset; - - /// Successors of the block ID in the bytecode vector - fn successors(&self, block_id: BlockId) -> &Vec; - - /// Return the next block in traversal order - fn next_block(&self, block_id: BlockId) -> Option; - - /// Iterator over the indexes of instructions in this block - fn instr_indexes(&self, block_id: BlockId) -> Box>; - - /// Return an iterator over the blocks of the CFG - fn blocks(&self) -> Vec; - - /// Return the number of blocks (vertices) in the control flow graph - fn num_blocks(&self) -> u16; - - /// Return the id of the entry block for this control-flow graph - /// Note: even a CFG with no instructions has an (empty) entry block. - fn entry_block_id(&self) -> BlockId; - - /// Checks if the block ID is a loop head - fn is_loop_head(&self, block_id: BlockId) -> bool; - - /// Checks if the edge from cur->next is a back edge - /// returns false if the edge is not in the cfg - fn is_back_edge(&self, cur: BlockId, next: BlockId) -> bool; - - /// Return the number of back edges in the cfg - fn num_back_edges(&self) -> usize; -} - -struct BasicBlock { - exit: CodeOffset, - successors: Vec, -} - -/// The control flow graph that we build from the bytecode. -pub struct VMControlFlowGraph { - /// The basic blocks - blocks: Map, - /// Basic block ordering for traversal - traversal_successors: Map, - /// Map of loop heads with all of their back edges - loop_heads: Map>, -} - -impl BasicBlock { - pub fn display(&self, entry: BlockId) { - println!("+=======================+"); - println!("| Enter: {} |", entry); - println!("+-----------------------+"); - println!("==> Children: {:?}", self.successors); - println!("+-----------------------+"); - println!("| Exit: {} |", self.exit); - println!("+=======================+"); - } -} - -const ENTRY_BLOCK_ID: BlockId = 0; - -impl VMControlFlowGraph { - pub fn new(code: &[Bytecode], jump_tables: &[VariantJumpTable]) -> Self { - let code_len = code.len() as CodeOffset; - // First go through and collect block ids, i.e., offsets that begin basic - // blocks. Need to do this first in order to handle backwards edges. - let mut block_ids = Set::new(); - block_ids.insert(ENTRY_BLOCK_ID); - for pc in 0..code.len() { - VMControlFlowGraph::record_block_ids( - pc as CodeOffset, - code, - jump_tables, - &mut block_ids, - ); - } - - // Create basic blocks - let mut blocks = Map::new(); - let mut entry = 0; - let mut exit_to_entry = Map::new(); - for pc in 0..code.len() { - let co_pc = pc as CodeOffset; - - // Create a basic block - if Self::is_end_of_block(co_pc, code, &block_ids) { - let exit = co_pc; - exit_to_entry.insert(exit, entry); - let successors = Bytecode::get_successors(co_pc, code, jump_tables); - let bb = BasicBlock { exit, successors }; - blocks.insert(entry, bb); - entry = co_pc + 1; - } - } - let blocks = blocks; - assert_eq!(entry, code_len); - - // # Loop analysis - // - // This section identifies loops in the control-flow graph, picks a back edge - // and loop head (the basic block the back edge returns to), and decides - // the order that blocks are traversed during abstract interpretation - // (reverse post-order). - // - // The implementation is based on the algorithm for finding widening points in - // Section 4.1, "Depth-first numbering" of Bourdoncle [1993], "Efficient - // chaotic iteration strategies with widenings." - // - // NB. The comments below refer to a block's sub-graph -- the reflexive - // transitive closure of its successor edges, modulo cycles. - - #[derive(Copy, Clone)] - enum Exploration { - InProgress, - Done, - } - - let mut exploration: Map = Map::new(); - let mut stack = vec![ENTRY_BLOCK_ID]; - - // For every loop in the CFG that is reachable from the entry block, there is an - // entry in `loop_heads` mapping to all the back edges pointing to it, - // and vice versa. - // - // Entry in `loop_heads` implies loop in the CFG is justified by the comments in - // the loop below. Loop in the CFG implies entry in `loop_heads` is - // justified by considering the point at which the first node in that - // loop, `F` is added to the `exploration` map: - // - // - By definition `F` is part of a loop, meaning there is a block `L` such - // that: - // - // F - ... -> L -> F - // - // - `F` will not transition to `Done` until all the nodes reachable from it - // (including `L`) have been visited. - // - Because `F` is the first node seen in the loop, all the other nodes in the - // loop (including `L`) will be visited while `F` is `InProgress`. - // - Therefore, we will process the `L -> F` edge while `F` is `InProgress`. - // - Therefore, we will record a back edge to it. - let mut loop_heads: Map> = Map::new(); - - // Blocks appear in `post_order` after all the blocks in their (non-reflexive) - // sub-graph. - let mut post_order = Vec::with_capacity(blocks.len()); - - while let Some(block) = stack.pop() { - match exploration.entry(block) { - Entry::Vacant(entry) => { - // Record the fact that exploration of this block and its sub-graph has started. - entry.insert(Exploration::InProgress); - - // Push the block back on the stack to finish processing it, and mark it as done - // once its sub-graph has been traversed. - stack.push(block); - - for succ in &blocks[&block].successors { - match exploration.get(succ) { - // This successor has never been visited before, add it to the stack to - // be explored before `block` gets marked `Done`. - None => stack.push(*succ), - - // This block's sub-graph was being explored, meaning it is a (reflexive - // transitive) predecessor of `block` as well as being a successor, - // implying a loop has been detected -- greedily choose the successor - // block as the loop head. - Some(Exploration::InProgress) => { - loop_heads.entry(*succ).or_default().insert(block); - } - - // Cross-edge detected, this block and its entire sub-graph (modulo - // cycles) has already been explored via a different path, and is - // already present in `post_order`. - Some(Exploration::Done) => { /* skip */ } - }; - } - } - - Entry::Occupied(mut entry) => match entry.get() { - // Already traversed the sub-graph reachable from this block, so skip it. - Exploration::Done => continue, - - // Finish up the traversal by adding this block to the post-order traversal - // after its sub-graph (modulo cycles). - Exploration::InProgress => { - post_order.push(block); - entry.insert(Exploration::Done); - } - }, - } - } - - let traversal_order = { - // This reverse post order is akin to a topological sort (ignoring cycles) and - // is different from a pre-order in the presence of diamond patterns - // in the graph. - post_order.reverse(); - post_order - }; - - // build a mapping from a block id to the next block id in the traversal order - let traversal_successors = traversal_order - .windows(2) - .map(|window| { - debug_assert!(window.len() == 2); - (window[0], window[1]) - }) - .collect(); - - VMControlFlowGraph { - blocks, - traversal_successors, - loop_heads, - } - } - - pub fn display(&self) { - for (entry, block) in &self.blocks { - block.display(*entry); - } - println!("Traversal: {:#?}", self.traversal_successors); - } - - fn is_end_of_block(pc: CodeOffset, code: &[Bytecode], block_ids: &Set) -> bool { - pc + 1 == (code.len() as CodeOffset) || block_ids.contains(&(pc + 1)) - } - - fn record_block_ids( - pc: CodeOffset, - code: &[Bytecode], - jump_tables: &[VariantJumpTable], - block_ids: &mut Set, - ) { - let bytecode = &code[pc as usize]; - - block_ids.extend(bytecode.offsets(jump_tables)); - - if bytecode.is_branch() && pc + 1 < (code.len() as CodeOffset) { - block_ids.insert(pc + 1); - } - } - - /// A utility function that implements BFS-reachability from block_id with - /// respect to get_targets function - fn traverse_by(&self, block_id: BlockId) -> Vec { - let mut ret = Vec::new(); - // We use this index to keep track of our frontier. - let mut index = 0; - // Guard against cycles - let mut seen = Set::new(); - - ret.push(block_id); - seen.insert(&block_id); - - while index < ret.len() { - let block_id = ret[index]; - index += 1; - let successors = self.successors(block_id); - for block_id in successors.iter() { - if !seen.contains(&block_id) { - ret.push(*block_id); - seen.insert(block_id); - } - } - } - - ret - } - - pub fn reachable_from(&self, block_id: BlockId) -> Vec { - self.traverse_by(block_id) - } -} - -impl ControlFlowGraph for VMControlFlowGraph { - // Note: in the following procedures, it's safe not to check bounds because: - // - Every CFG (even one with no instructions) has a block at ENTRY_BLOCK_ID - // - The only way to acquire new BlockId's is via block_successors() - // - block_successors only() returns valid BlockId's - // Note: it is still possible to get a BlockId from one CFG and use it in - // another CFG where it is not valid. The design does not attempt to prevent - // this abuse of the API. - - fn block_start(&self, block_id: BlockId) -> CodeOffset { - block_id - } - - fn block_end(&self, block_id: BlockId) -> CodeOffset { - self.blocks[&block_id].exit - } - - fn successors(&self, block_id: BlockId) -> &Vec { - &self.blocks[&block_id].successors - } - - fn next_block(&self, block_id: BlockId) -> Option { - debug_assert!(self.blocks.contains_key(&block_id)); - self.traversal_successors.get(&block_id).copied() - } - - fn instr_indexes(&self, block_id: BlockId) -> Box> { - Box::new(self.block_start(block_id)..=self.block_end(block_id)) - } - - fn blocks(&self) -> Vec { - self.blocks.keys().cloned().collect() - } - - fn num_blocks(&self) -> u16 { - self.blocks.len() as u16 - } - - fn entry_block_id(&self) -> BlockId { - ENTRY_BLOCK_ID - } - - fn is_loop_head(&self, block_id: BlockId) -> bool { - self.loop_heads.contains_key(&block_id) - } - - fn is_back_edge(&self, cur: BlockId, next: BlockId) -> bool { - self.loop_heads - .get(&next) - .map_or(false, |back_edges| back_edges.contains(&cur)) - } - - fn num_back_edges(&self) -> usize { - self.loop_heads - .iter() - .fold(0, |acc, (_, edges)| acc + edges.len()) - } -} diff --git a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/lib.rs b/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/lib.rs deleted file mode 100644 index e103979117e..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -pub mod absint; -pub mod control_flow_graph; - -#[cfg(test)] -mod unit_tests; diff --git a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/unit_tests/control_flow_graph_tests.rs b/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/unit_tests/control_flow_graph_tests.rs deleted file mode 100644 index 83cb0ca6fe3..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/unit_tests/control_flow_graph_tests.rs +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use itertools::Itertools; - -use crate::control_flow_graph::{BlockId, ControlFlowGraph, VMControlFlowGraph}; - -use move_binary_format::file_format::{ - Bytecode, EnumDefinitionIndex, JumpTableInner, VariantJumpTable, VariantJumpTableIndex, -}; - -#[test] -fn traversal_no_loops() { - let cfg = { - use Bytecode::*; - VMControlFlowGraph::new( - &[ - /* L0 */ LdTrue, - /* */ BrTrue(3), - /* L2 */ Branch(3), - /* L3 */ Ret, - ], - &[], - ) - }; - - cfg.display(); - assert_eq!(cfg.num_blocks(), 3); - assert_eq!(traversal(&cfg), vec![0, 2, 3]); -} - -#[test] -fn traversal_no_loops_with_switch() { - let cfg = { - use Bytecode::*; - VMControlFlowGraph::new( - &[ - /* L0 */ VariantSwitch(VariantJumpTableIndex::new(0)), - /* */ Nop, - /* */ Nop, - /* */ Nop, - /* */ Nop, - /* */ Nop, - /* */ BrTrue(8), - /* L2 */ Branch(8), - /* L3 */ Ret, - ], - &[VariantJumpTable { - // Doesn't matter - head_enum: EnumDefinitionIndex::new(0), - jump_table: JumpTableInner::Full(vec![1, 8, 2, 4]), - }], - ) - }; - - cfg.display(); - assert_eq!(cfg.num_blocks(), 6); - assert_eq!(dbg!(traversal(&cfg)), vec![0, 1, 2, 4, 7, 8]); -} - -#[test] -fn traversal_loops() { - let cfg = { - use Bytecode::*; - VMControlFlowGraph::new( - &[ - /* L0: Outer head */ LdTrue, - /* Outer break */ BrTrue(6), - /* L2: Inner head */ LdTrue, - /* Inner break */ BrTrue(5), - /* L4: Inner continue */ Branch(2), - /* Outer continue */ Branch(0), - /* L6: */ Ret, - ], - &[], - ) - }; - - cfg.display(); - assert_eq!(cfg.num_blocks(), 5); - assert_eq!(traversal(&cfg), vec![0, 2, 4, 5, 6]); -} - -#[test] -fn traversal_loops_with_switch() { - let cfg = { - use Bytecode::*; - VMControlFlowGraph::new( - &[ - /* L0: Outer head */ LdTrue, - /* Outer break */ BrTrue(4), - /* L2: Inner head */ VariantSwitch(VariantJumpTableIndex::new(0)), - /* Outer continue */ Branch(0), - /* L6: */ Ret, - ], - &[VariantJumpTable { - // Doesn't matter - head_enum: EnumDefinitionIndex::new(0), - jump_table: JumpTableInner::Full(vec![ - /* Inner break */ 3, /* Inner continue */ 2, - ]), - }], - ) - }; - - cfg.display(); - assert_eq!(cfg.num_blocks(), 4); - assert_eq!(traversal(&cfg), vec![0, 2, 3, 4]); -} - -#[test] -fn traversal_non_loop_back_branch() { - let cfg = { - use Bytecode::*; - VMControlFlowGraph::new( - &[ - /* L0 */ Branch(2), - /* L1 */ Ret, - /* L2 */ Branch(1), - ], - &[], - ) - }; - - cfg.display(); - assert_eq!(cfg.num_blocks(), 3); - assert_eq!(traversal(&cfg), vec![0, 2, 1]); -} - -#[test] -fn traversal_non_loop_back_branch_variant_switch() { - let cfg = { - use Bytecode::*; - VMControlFlowGraph::new( - &[ - /* L0 */ VariantSwitch(VariantJumpTableIndex::new(0)), - /* L1 */ Ret, - /* L2 */ Branch(1), - ], - &[VariantJumpTable { - // Doesn't matter - head_enum: EnumDefinitionIndex::new(0), - jump_table: JumpTableInner::Full(vec![2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]), - }], - ) - }; - - cfg.display(); - assert_eq!(cfg.num_blocks(), 3); - assert_eq!(traversal(&cfg), vec![0, 2, 1]); -} - -#[test] -fn out_of_order_blocks_variant_switch() { - const PERMUTATION_BOUND: usize = 2000; - - let blocks = (0..=127) - .map(|i| { - ( - i, - vec![ - Bytecode::Pop, // Pop the value from the variant switch - Bytecode::LdU16(i), // Ld the number so we can track what block this is canonically - Bytecode::Pop, // Then pop it - Bytecode::Ret, // Then ret - ], - ) - }) - .collect::>(); - - let block_len = blocks.last().unwrap().1.len() as u16; - - let (canonical_blocks, canonical_traversal) = { - let jump_table = - JumpTableInner::Full(blocks.iter().map(|(i, _)| 1 + *i * block_len).collect()); - let mut start_block = vec![Bytecode::VariantSwitch(VariantJumpTableIndex::new(0))]; - start_block.extend(blocks.clone().into_iter().flat_map(|(_, block)| block)); - - let cfg = VMControlFlowGraph::new( - &start_block, - &[VariantJumpTable { - // Doesn't matter - head_enum: EnumDefinitionIndex::new(0), - jump_table, - }], - ); - - cfg.display(); - (cfg.num_blocks(), traversal(&cfg)) - }; - - assert_eq!(canonical_blocks, 129); - assert_eq!(canonical_traversal.len(), 129); - - for permutation in blocks.into_iter().permutations(128).take(PERMUTATION_BOUND) { - // orig index => new_index - // identity permutation == perm[i] == i; - let mut perm = vec![]; - let mut blocks = vec![Bytecode::VariantSwitch(VariantJumpTableIndex::new(0))]; - for (index, mut block) in permutation.into_iter() { - perm.push(index); - blocks.append(&mut block); - } - - let jump_table = JumpTableInner::Full(perm.iter().map(|i| 1 + *i * block_len).collect()); - - let cfg = VMControlFlowGraph::new( - &blocks, - &[VariantJumpTable { - // Doesn't matter - head_enum: EnumDefinitionIndex::new(0), - jump_table, - }], - ); - assert_eq!( - cfg.num_blocks(), - canonical_blocks, - "num blocks differ: Permutation: {:?}", - perm - ); - assert_eq!( - traversal(&cfg), - canonical_traversal, - "traversal differs: Permutation: {:?}", - perm - ); - } -} - -/// Return a vector containing the `BlockId`s from `cfg` in the order suggested by successively -/// calling `ControlFlowGraph::next_block` starting from the entry block. -fn traversal(cfg: &dyn ControlFlowGraph) -> Vec { - let mut order = Vec::with_capacity(cfg.num_blocks() as usize); - let mut next = Some(cfg.entry_block_id()); - - while let Some(block) = next { - order.push(block); - next = cfg.next_block(block); - } - - order -} diff --git a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/unit_tests/mod.rs b/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/unit_tests/mod.rs deleted file mode 100644 index 46e078986ad..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-abstract-interpreter/src/unit_tests/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -mod control_flow_graph_tests; diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/Cargo.toml b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/Cargo.toml deleted file mode 100644 index 66e4d921646..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "move-bytecode-verifier-v0" -version = "0.1.0" -authors = ["IOTA Foundation "] -edition = "2021" -license = "Apache-2.0" -publish = false -description = "Move bytecode verifier" - -[dependencies] -petgraph.workspace = true - -move-abstract-interpreter.workspace = true -move-abstract-stack.workspace = true -move-binary-format.workspace = true -move-borrow-graph.workspace = true -move-bytecode-verifier-meter.workspace = true -move-core-types.workspace = true -move-vm-config.workspace = true - -[features] -default = [] diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/README.md b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/README.md deleted file mode 100644 index f062b48a66f..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/README.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -id: bytecode-verifier -title: Bytecode Verifier -custom_edit_url: https://github.com/move-language/move/edit/main/language/move-bytecode-verifier/README.md ---- - -## Overview - -The bytecode verifier contains a static analysis tool for rejecting invalid Move bytecode. It checks the safety of stack usage, types, resources, and references. - -The body of each function in a compiled module is verified separately while trusting the correctness of function signatures in the module. Checking that each function signature matches its definition is a separate responsibility. The body of a function is a sequence of bytecode instructions. This instruction sequence is checked in several phases described below. - -## CFG Construction - -A control-flow graph is constructed by decomposing the instruction sequence into a collection of basic blocks. Each basic block contains a contiguous sequence of instructions; the set of all instructions is partitioned among the blocks. Each block ends with a branch or return instruction. The decomposition into blocks guarantees that branch targets land only at the beginning of some block. The decomposition also attempts to ensure that the generated blocks are maximal. However, the soundness of the analysis does not depend on maximality. - -## Stack Safety - -The execution of a block happens in the context of a stack and an array of local variables. The parameters of the function are a prefix of the array of local variables. Arguments and return values are passed across function calls via the stack. When a function starts executing, its arguments are already loaded into its parameters. Suppose the stack height is _n_ when a function starts executing; then valid bytecode must enforce the invariant that when execution lands at the beginning of a basic block, the stack height is _n_. Furthermore, at a return instruction, the stack height must be _n_+_k_ where _k_, s.t. _k_>=0 is the number of return values. The first phase of the analysis checks that this invariant is maintained by analyzing each block separately, calculating the effect of each instruction in the block on the stack height, checking that the height does not go below _n_, and that is left either at _n_ or _n_+_k_ (depending on the final instruction of the block and the return type of the function) at the end of the block. - -## Type Safety - -The second phase of the analysis checks that each operation, primitive or defined function, is invoked with arguments of appropriate types. The operands of an operation are values located either in a local variable or on the stack. The types of local variables of a function are already provided in the bytecode. However, the types of stack values are inferred. This inference and the type checking of each operation can be done separately for each block. Since the stack height at the beginning of each block is _n_ and does not go below _n_ during the execution of the block, we only need to model the suffix of the stack starting at _n_ for type checking the block instructions. We model this suffix using a stack of types on which types are pushed and popped as the instruction stream in a block is processed. Only the type stack and the statically-known types of local variables are needed to type check each instruction. - -## Resource Safety - -Resources represent the assets of the blockchain. As such, there are certain restrictions on these types that do not apply to normal values. Intuitively, resource values cannot be copied and must be used by the end of the transaction (this means that they are moved to global storage or destroyed). Concretely, the following restrictions apply: - -- `CopyLoc` and `StLoc` require that the type of local is not of resource kind. -- `WriteRef`, `Eq`, and `Neq` require that the type of the reference is not of resource kind. -- At the end of a function (when `Ret` is reached), no local whose type is of resource kind must be empty, i.e., the value must have been moved out of the local. - -As mentioned above, this last rule around `Ret` implies that the resource _must_ have been either: - -- Moved to global storage via `MoveTo`. -- Destroyed via `Unpack`. - -Both `MoveTo` and `Unpack` are internal to the module in which the resource is declared. - -## Reference Safety - -References are first-class in the bytecode language. Fresh references become available to a function in several ways: - -- Inputting parameters. -- Taking the address of the value in a local variable. -- Taking the address of the globally published value in an address. -- Taking the address of a field from a reference to the containing struct. -- Returning value from a function. - -The goal of reference safety checking is to ensure that there are no dangling references. Here are some examples of dangling references: - -- Local variable `y` contains a reference to the value in a local variable `x`; `x` is then moved. -- Local variable `y` contains a reference to the value in a local variable `x`; `x` is then bound to a new value. -- Reference is taken to a local variable that has not been initialized. -- Reference to a value in a local variable is returned from a function. -- Reference `r` is taken to a globally published value `v`; `v` is then unpublished. - -References can be either exclusive or shared; the latter allow read-only access. A secondary goal of reference safety checking is to ensure that in the execution context of the bytecode program, including the entire evaluation stack and all function frames, if there are two distinct storage locations containing references `r1` and `r2` such that `r2` extends `r1`, then both of the following conditions hold: - -- If `r1` is tagged as exclusive, then it must be inactive, i.e. it is impossible to reach a control location where `r1` is dereferenced or mutated. -- If `r1` is shared, then `r2` is shared. - -The two conditions above establish the property of referential transparency, important for scalable program verification, which looks roughly as follows: consider the piece of code `v1 = *r; S; v2 = *r`, where `S` is an arbitrary computation that does not perform any write through the syntactic reference `r` (and no writes to any `r'` that extends `r`). Then `v1 == v2`. - -### Analysis Setup - -The reference safety analysis is set up as a flow analysis (or abstract interpretation). An abstract state is defined for abstractly executing the code of a basic block. A map is maintained from basic blocks to abstract states. Given an abstract state _S_ at the beginning of a basic block _B_, the abstract execution of _B_ results in state _S'_. This state _S'_ is propagated to all successors of _B_ and recorded in the map. If a state already existed for a block, the freshly propagated state is “joined” with the existing state. If the join fails an error is reported. If the join succeeds but the abstract state remains unchanged, no further propagation is done. Otherwise, the state is updated and propagated again through the block. An error may also be reported when an instruction is processed during the propagation of abstract state through a block. - -**Errors.** As mentioned earlier, an error is reported by the checker in one of the following situations: - -- An instruction cannot be proven to be safe during the propagation of the abstract state through a block. -- Join of abstract states propagated via different incoming edges into a block fails. - -## How is this module organized? - -```text -* -├── invalid-mutations # Library used by proptests -├── src # Core bytecode verifier files -├── tests # Proptests -``` diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/ability_cache.rs b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/ability_cache.rs deleted file mode 100644 index 9f9a61b9329..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/ability_cache.rs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::{ - errors::PartialVMResult, - file_format::{AbilitySet, DatatypeHandleIndex, SignatureToken}, - safe_unwrap, CompiledModule, -}; -use move_bytecode_verifier_meter::{Meter, Scope}; -use std::{ - cmp::max, - collections::{btree_map::Entry, BTreeMap}, -}; - -const TYPE_ARG_COST: u128 = 1; - -pub struct AbilityCache<'a> { - module: &'a CompiledModule, - vector_results: BTreeMap, - datatype_results: BTreeMap, AbilitySet>>, -} - -impl<'a> AbilityCache<'a> { - pub fn new(module: &'a CompiledModule) -> Self { - Self { - module, - vector_results: BTreeMap::new(), - datatype_results: BTreeMap::new(), - } - } - - pub fn abilities( - &mut self, - scope: Scope, - meter: &mut (impl Meter + ?Sized), - type_parameter_abilities: &[AbilitySet], - ty: &SignatureToken, - ) -> PartialVMResult { - use SignatureToken as S; - - Ok(match ty { - S::Bool | S::U8 | S::U16 | S::U32 | S::U64 | S::U128 | S::U256 | S::Address => { - AbilitySet::PRIMITIVES - } - - S::Reference(_) | S::MutableReference(_) => AbilitySet::REFERENCES, - S::Signer => AbilitySet::SIGNER, - S::TypeParameter(idx) => *safe_unwrap!(type_parameter_abilities.get(*idx as usize)), - S::Datatype(idx) => { - let sh = self.module.datatype_handle_at(*idx); - sh.abilities - } - S::Vector(inner) => { - let inner_abilities = - self.abilities(scope, meter, type_parameter_abilities, inner)?; - let entry = self.vector_results.entry(inner_abilities); - match entry { - Entry::Occupied(entry) => *entry.get(), - Entry::Vacant(entry) => { - meter.add(scope, TYPE_ARG_COST)?; - let abilities = AbilitySet::polymorphic_abilities( - AbilitySet::VECTOR, - vec![false], - vec![inner_abilities], - )?; - entry.insert(abilities); - abilities - } - } - } - S::DatatypeInstantiation(inst) => { - let (idx, type_args) = &**inst; - let type_arg_abilities = type_args - .iter() - .map(|arg| self.abilities(scope, meter, type_parameter_abilities, arg)) - .collect::>>()?; - let entry = self - .datatype_results - .entry(*idx) - .or_default() - .entry(type_arg_abilities.clone()); - match entry { - Entry::Occupied(entry) => *entry.get(), - Entry::Vacant(entry) => { - meter.add_items(scope, TYPE_ARG_COST, max(type_args.len(), 1))?; - let sh = self.module.datatype_handle_at(*idx); - let declared_abilities = sh.abilities; - let abilities = AbilitySet::polymorphic_abilities( - declared_abilities, - sh.type_parameters.iter().map(|param| param.is_phantom), - type_arg_abilities, - )?; - entry.insert(abilities); - abilities - } - } - } - }) - } -} diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/ability_field_requirements.rs b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/ability_field_requirements.rs deleted file mode 100644 index a7dd938c6eb..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/ability_field_requirements.rs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// 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::{ - errors::{verification_error, Location, PartialVMResult, VMResult}, - file_format::{AbilitySet, CompiledModule, StructFieldInformation, TableIndex}, - IndexKind, -}; -use move_bytecode_verifier_meter::{Meter, Scope}; -use move_core_types::vm_status::StatusCode; - -use crate::ability_cache::AbilityCache; - -pub fn verify_module<'env>( - module: &'env CompiledModule, - ability_cache: &mut AbilityCache<'env>, - meter: &mut (impl Meter + ?Sized), -) -> VMResult<()> { - verify_module_impl(module, ability_cache, meter) - .map_err(|e| e.finish(Location::Module(module.self_id()))) -} - -fn verify_module_impl<'env>( - module: &'env CompiledModule, - ability_cache: &mut AbilityCache<'env>, - meter: &mut (impl Meter + ?Sized), -) -> PartialVMResult<()> { - for (idx, struct_def) in module.struct_defs().iter().enumerate() { - let sh = module.datatype_handle_at(struct_def.struct_handle); - let fields = match &struct_def.field_information { - StructFieldInformation::Native => continue, - StructFieldInformation::Declared(fields) => fields, - }; - 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::>(); - for field in fields { - let field_abilities = ability_cache.abilities( - Scope::Module, - meter, - &type_parameter_abilities, - &field.signature.0, - )?; - if !required_abilities.is_subset(field_abilities) { - return Err(verification_error( - StatusCode::FIELD_MISSING_TYPE_ABILITY, - IndexKind::StructDefinition, - idx as TableIndex, - )); - } - } - } - - for (idx, enum_def) in module.enum_defs().iter().enumerate() { - let sh = module.datatype_handle_at(enum_def.enum_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 enum's abilities will be - // dependent on them - let type_parameter_abilities = sh - .type_parameters - .iter() - .map(|_| AbilitySet::ALL) - .collect::>(); - for (i, variant) in enum_def.variants.iter().enumerate() { - for (fi, field) in variant.fields.iter().enumerate() { - let field_abilities = ability_cache.abilities( - Scope::Module, - meter, - &type_parameter_abilities, - &field.signature.0, - )?; - if !required_abilities.is_subset(field_abilities) { - return Err(verification_error( - StatusCode::FIELD_MISSING_TYPE_ABILITY, - IndexKind::EnumDefinition, - idx as TableIndex, - ) - .at_index(IndexKind::VariantTag, i as TableIndex) - .at_index(IndexKind::FieldDefinition, fi as TableIndex)); - } - } - } - } - Ok(()) -} diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/acquires_list_verifier.rs b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/acquires_list_verifier.rs deleted file mode 100644 index 9c94d58cd8a..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/acquires_list_verifier.rs +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -//! This module implements a checker for verifying properties about the acquires list on function -//! definitions. Function definitions must annotate the global resources (declared in that module) -//! accesssed by `BorrowGlobal`, `MoveFrom`, and any transitive function calls -//! The list of acquired resources (stored in `FunctionDefinition`'s `acquires_global_resources` -//! field) must have: -//! - No duplicate resources (checked by `check_duplication`) -//! - No missing resources (any resource acquired must be present) -//! - No additional resources (no extraneous resources not actually acquired) - -use std::collections::{BTreeSet, HashMap}; - -use move_binary_format::{ - errors::{PartialVMError, PartialVMResult}, - file_format::{ - Bytecode, CodeOffset, CompiledModule, FunctionDefinition, FunctionDefinitionIndex, - FunctionHandle, FunctionHandleIndex, StructDefinitionIndex, - }, - safe_unwrap, -}; -use move_bytecode_verifier_meter::Meter; -use move_core_types::vm_status::StatusCode; - -pub(crate) struct AcquiresVerifier<'a> { - module: &'a CompiledModule, - current_function: FunctionDefinitionIndex, - annotated_acquires: BTreeSet, - actual_acquires: BTreeSet, - handle_to_def: HashMap, -} - -impl<'a> AcquiresVerifier<'a> { - pub(crate) fn verify( - module: &'a CompiledModule, - index: FunctionDefinitionIndex, - function_definition: &'a FunctionDefinition, - _meter: &mut (impl Meter + ?Sized), // currently unused - ) -> PartialVMResult<()> { - let annotated_acquires: BTreeSet<_> = function_definition - .acquires_global_resources - .iter() - .cloned() - .collect(); - let mut handle_to_def = HashMap::new(); - for func_def in module.function_defs() { - handle_to_def.insert(func_def.function, func_def); - } - let mut verifier = Self { - module, - current_function: index, - annotated_acquires, - actual_acquires: BTreeSet::new(), - handle_to_def, - }; - - for (offset, instruction) in safe_unwrap!(function_definition.code.as_ref()) - .code - .iter() - .enumerate() - { - verifier.verify_instruction(instruction, offset as CodeOffset)? - } - - for annotation in verifier.annotated_acquires { - if !verifier.actual_acquires.contains(&annotation) { - return Err(PartialVMError::new( - StatusCode::EXTRANEOUS_ACQUIRES_ANNOTATION, - )); - } - - let struct_def = safe_unwrap!(module.struct_defs().get(annotation.0 as usize)); - let struct_handle = module.datatype_handle_at(struct_def.struct_handle); - if !struct_handle.abilities.has_key() { - return Err(PartialVMError::new(StatusCode::INVALID_ACQUIRES_ANNOTATION)); - } - } - - Ok(()) - } - - fn verify_instruction( - &mut self, - instruction: &Bytecode, - offset: CodeOffset, - ) -> PartialVMResult<()> { - match instruction { - Bytecode::Call(idx) => self.call_acquire(*idx, offset), - Bytecode::CallGeneric(idx) => { - let fi = self.module.function_instantiation_at(*idx); - self.call_acquire(fi.handle, offset) - } - Bytecode::MoveFromDeprecated(idx) - | Bytecode::MutBorrowGlobalDeprecated(idx) - | Bytecode::ImmBorrowGlobalDeprecated(idx) => self.struct_acquire(*idx, offset), - Bytecode::MoveFromGenericDeprecated(idx) - | Bytecode::MutBorrowGlobalGenericDeprecated(idx) - | Bytecode::ImmBorrowGlobalGenericDeprecated(idx) => { - let si = self.module.struct_instantiation_at(*idx); - self.struct_acquire(si.def, offset) - } - - Bytecode::Pop - | Bytecode::BrTrue(_) - | Bytecode::BrFalse(_) - | Bytecode::Abort - | Bytecode::Branch(_) - | Bytecode::Nop - | Bytecode::Ret - | Bytecode::StLoc(_) - | Bytecode::MoveLoc(_) - | Bytecode::CopyLoc(_) - | Bytecode::ImmBorrowLoc(_) - | Bytecode::MutBorrowLoc(_) - | Bytecode::FreezeRef - | Bytecode::MutBorrowField(_) - | Bytecode::MutBorrowFieldGeneric(_) - | Bytecode::ImmBorrowField(_) - | Bytecode::ImmBorrowFieldGeneric(_) - | Bytecode::LdU8(_) - | Bytecode::LdU16(_) - | Bytecode::LdU32(_) - | Bytecode::LdU64(_) - | Bytecode::LdU128(_) - | Bytecode::LdU256(_) - | Bytecode::LdConst(_) - | Bytecode::LdTrue - | Bytecode::LdFalse - | 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::Shl - | Bytecode::Shr - | Bytecode::Or - | Bytecode::And - | Bytecode::Not - | Bytecode::Eq - | Bytecode::Neq - | Bytecode::Lt - | Bytecode::Gt - | Bytecode::Le - | Bytecode::Ge - | Bytecode::ExistsDeprecated(_) - | Bytecode::ExistsGenericDeprecated(_) - | Bytecode::MoveToDeprecated(_) - | Bytecode::MoveToGenericDeprecated(_) - | Bytecode::VecPack(..) - | Bytecode::VecLen(_) - | Bytecode::VecImmBorrow(_) - | Bytecode::VecMutBorrow(_) - | Bytecode::VecPushBack(_) - | Bytecode::VecPopBack(_) - | Bytecode::VecUnpack(..) - | Bytecode::VecSwap(_) - | Bytecode::PackVariant(_) - | Bytecode::PackVariantGeneric(_) - | Bytecode::UnpackVariant(_) - | Bytecode::UnpackVariantImmRef(_) - | Bytecode::UnpackVariantMutRef(_) - | Bytecode::UnpackVariantGeneric(_) - | Bytecode::UnpackVariantGenericImmRef(_) - | Bytecode::UnpackVariantGenericMutRef(_) - | Bytecode::VariantSwitch(_) => Ok(()), - } - } - - fn call_acquire( - &mut self, - fh_idx: FunctionHandleIndex, - offset: CodeOffset, - ) -> PartialVMResult<()> { - let function_handle = self.module.function_handle_at(fh_idx); - let mut function_acquired_resources = - self.function_acquired_resources(function_handle, fh_idx); - for acquired_resource in &function_acquired_resources { - if !self.annotated_acquires.contains(acquired_resource) { - return Err(self.error(StatusCode::MISSING_ACQUIRES_ANNOTATION, offset)); - } - } - self.actual_acquires - .append(&mut function_acquired_resources); - Ok(()) - } - - fn struct_acquire( - &mut self, - sd_idx: StructDefinitionIndex, - offset: CodeOffset, - ) -> PartialVMResult<()> { - if self.annotated_acquires.contains(&sd_idx) { - self.actual_acquires.insert(sd_idx); - Ok(()) - } else { - Err(self.error(StatusCode::MISSING_ACQUIRES_ANNOTATION, offset)) - } - } - - fn function_acquired_resources( - &self, - function_handle: &FunctionHandle, - fh_idx: FunctionHandleIndex, - ) -> BTreeSet { - if function_handle.module != self.module.self_handle_idx() { - return BTreeSet::new(); - } - match self.handle_to_def.get(&fh_idx) { - Some(func_def) => func_def.acquires_global_resources.iter().cloned().collect(), - None => BTreeSet::new(), - } - } - - fn error(&self, status: StatusCode, offset: CodeOffset) -> PartialVMError { - PartialVMError::new(status).at_code_offset(self.current_function, offset) - } -} diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/check_duplication.rs b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/check_duplication.rs deleted file mode 100644 index cf320d91782..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/check_duplication.rs +++ /dev/null @@ -1,417 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -//! This module implements a checker for verifying that each vector in a -//! CompiledModule contains distinct values. Successful verification implies -//! that an index in vector can be used to uniquely name the entry at that -//! index. Additionally, the checker also verifies the following: -//! - struct and field definitions are consistent -//! - the handles in struct and function definitions point to the self module -//! index -//! - all struct and function handles pointing to the self module index have a -//! definition -use std::{collections::HashSet, hash::Hash}; - -use move_binary_format::{ - errors::{verification_error, Location, PartialVMResult, VMResult}, - file_format::{ - CompiledModule, Constant, DatatypeHandle, DatatypeHandleIndex, FunctionHandle, - FunctionHandleIndex, FunctionInstantiation, ModuleHandle, Signature, - StructFieldInformation, TableIndex, VariantHandle, - }, - IndexKind, -}; -use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, -}; - -pub struct DuplicationChecker<'a> { - module: &'a CompiledModule, -} - -impl<'a> DuplicationChecker<'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<()> { - Self::check_identifiers(module.identifiers())?; - Self::check_address_identifiers(module.address_identifiers())?; - Self::check_constants(module.constant_pool())?; - Self::check_signatures(module.signatures())?; - Self::check_module_handles(module.module_handles())?; - Self::check_module_handles(module.friend_decls())?; - Self::check_datatype_handles(module.datatype_handles())?; - Self::check_function_handles(module.function_handles())?; - Self::check_function_instantiations(module.function_instantiations())?; - Self::check_variant_handles(module.variant_handles())?; - - let checker = Self { module }; - checker.check_field_handles()?; - checker.check_field_instantiations()?; - checker.check_function_definitions()?; - checker.check_struct_definitions()?; - checker.check_struct_instantiations()?; - checker.check_enum_definitions()?; - checker.check_enum_instantiations()?; - checker.check_datatype_handles_implemented() - } - - fn check_identifiers(identifiers: &[Identifier]) -> PartialVMResult<()> { - match Self::first_duplicate_element(identifiers) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::Identifier, - idx, - )), - None => Ok(()), - } - } - - fn check_address_identifiers(address_identifiers: &[AccountAddress]) -> PartialVMResult<()> { - match Self::first_duplicate_element(address_identifiers) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::AddressIdentifier, - idx, - )), - None => Ok(()), - } - } - - fn check_constants(constant_pool: &[Constant]) -> PartialVMResult<()> { - match Self::first_duplicate_element(constant_pool) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::ConstantPool, - idx, - )), - None => Ok(()), - } - } - - fn check_signatures(signatures: &[Signature]) -> PartialVMResult<()> { - match Self::first_duplicate_element(signatures) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::Signature, - idx, - )), - None => Ok(()), - } - } - - fn check_module_handles(module_handles: &[ModuleHandle]) -> PartialVMResult<()> { - match Self::first_duplicate_element(module_handles) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::ModuleHandle, - idx, - )), - None => Ok(()), - } - } - - // DatatypeHandles - module and name define uniqueness - fn check_datatype_handles(datatype_handles: &[DatatypeHandle]) -> PartialVMResult<()> { - match Self::first_duplicate_element(datatype_handles.iter().map(|x| (x.module, x.name))) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::DatatypeHandle, - idx, - )), - None => Ok(()), - } - } - - fn check_variant_handles(variant_handles: &[VariantHandle]) -> PartialVMResult<()> { - match Self::first_duplicate_element(variant_handles.iter().map(|x| (x.enum_def, x.variant))) - { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::VariantHandle, - idx, - )), - None => Ok(()), - } - } - - fn check_function_instantiations( - function_instantiations: &[FunctionInstantiation], - ) -> PartialVMResult<()> { - match Self::first_duplicate_element(function_instantiations) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::FunctionInstantiation, - idx, - )), - None => Ok(()), - } - } - - // FunctionHandles - module and name define uniqueness - fn check_function_handles(function_handles: &[FunctionHandle]) -> PartialVMResult<()> { - match Self::first_duplicate_element(function_handles.iter().map(|x| (x.module, x.name))) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::FunctionHandle, - idx, - )), - None => Ok(()), - } - } - - // Module only code - // - - fn check_field_handles(&self) -> PartialVMResult<()> { - match Self::first_duplicate_element(self.module.field_handles()) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::FieldHandle, - idx, - )), - None => Ok(()), - } - } - - fn check_struct_instantiations(&self) -> PartialVMResult<()> { - match Self::first_duplicate_element(self.module.struct_instantiations()) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::StructDefInstantiation, - idx, - )), - None => Ok(()), - } - } - - fn check_enum_instantiations(&self) -> PartialVMResult<()> { - match Self::first_duplicate_element(self.module.enum_instantiations()) { - Some(idx) => Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::EnumDefInstantiation, - idx, - )), - None => Ok(()), - } - } - - fn check_field_instantiations(&self) -> PartialVMResult<()> { - if let Some(idx) = Self::first_duplicate_element(self.module.field_instantiations()) { - return Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::FieldInstantiation, - idx, - )); - } - Ok(()) - } - - fn check_struct_definitions(&self) -> PartialVMResult<()> { - // StructDefinition - contained DatatypeHandle defines uniqueness - if let Some(idx) = - Self::first_duplicate_element(self.module.struct_defs().iter().map(|x| x.struct_handle)) - { - return Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::StructDefinition, - idx, - )); - } - // Field names in structs must be unique - for (struct_idx, struct_def) in self.module.struct_defs().iter().enumerate() { - let fields = match &struct_def.field_information { - StructFieldInformation::Native => continue, - StructFieldInformation::Declared(fields) => fields, - }; - if fields.is_empty() { - return Err(verification_error( - StatusCode::ZERO_SIZED_STRUCT, - IndexKind::StructDefinition, - struct_idx as TableIndex, - )); - } - if let Some(idx) = Self::first_duplicate_element(fields.iter().map(|x| x.name)) { - return Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::FieldDefinition, - idx, - )); - } - } - // Check that each struct definition is pointing to the self module - if let Some(idx) = self.module.struct_defs().iter().position(|x| { - self.module.datatype_handle_at(x.struct_handle).module != self.module.self_handle_idx() - }) { - return Err(verification_error( - StatusCode::INVALID_MODULE_HANDLE, - IndexKind::StructDefinition, - idx as TableIndex, - )); - } - Ok(()) - } - - fn check_datatype_handles_implemented(&self) -> PartialVMResult<()> { - let implemented_datatype_handles: HashSet = self - .module - .struct_defs() - .iter() - .map(|x| x.struct_handle) - .chain(self.module.enum_defs().iter().map(|x| x.enum_handle)) - .collect(); - if let Some(idx) = (0..self.module.datatype_handles().len()).position(|x| { - let y = DatatypeHandleIndex::new(x as u16); - self.module.datatype_handle_at(y).module == self.module.self_handle_idx() - && !implemented_datatype_handles.contains(&y) - }) { - return Err(verification_error( - StatusCode::UNIMPLEMENTED_HANDLE, - IndexKind::DatatypeHandle, - idx as TableIndex, - )); - } - Ok(()) - } - - fn check_enum_definitions(&self) -> PartialVMResult<()> { - // EnumDefinition - contained DatatypeHandle defines uniqueness - // NB: We check uniqueness across both enum and struct handles at this point to - // make sure data definitions are not duplicated across struct and - // enums. - if let Some(idx) = Self::first_duplicate_element( - self.module - .struct_defs() - .iter() - .map(|x| x.struct_handle) - .chain(self.module.enum_defs().iter().map(|x| x.enum_handle)), - ) { - return Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::EnumDefinition, - idx, - )); - } - // Variant names in enums must be unique - // Field names in each variant must be unique - for (enum_idx, enum_def) in self.module.enum_defs().iter().enumerate() { - let variants = &enum_def.variants; - if variants.is_empty() { - return Err(verification_error( - StatusCode::ZERO_SIZED_ENUM, - IndexKind::EnumDefinition, - enum_idx as TableIndex, - )); - } - if let Some(idx) = - Self::first_duplicate_element(variants.iter().map(|x| x.variant_name)) - { - return Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::EnumDefinition, - enum_idx as TableIndex, - ) - .at_index(IndexKind::VariantTag, idx as TableIndex)); - } - - // NB: we allow zero-sized variants: since we require non-empty enums we always - // have a tag and therefore a variant with no fields is still - // non-zero sized whereas a struct with zero fields is zero-sized. - for (tag, variant) in variants.iter().enumerate() { - if let Some(idx) = - Self::first_duplicate_element(variant.fields.iter().map(|x| x.name)) - { - return Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::FieldDefinition, - idx, - ) - .at_index(IndexKind::VariantTag, tag as TableIndex) - .at_index(IndexKind::EnumDefinition, enum_idx as TableIndex)); - } - } - } - // Check that each enum definition is pointing to the self module - if let Some(idx) = self.module.enum_defs().iter().position(|x| { - self.module.datatype_handle_at(x.enum_handle).module != self.module.self_handle_idx() - }) { - return Err(verification_error( - StatusCode::INVALID_MODULE_HANDLE, - IndexKind::EnumDefinition, - idx as TableIndex, - )); - } - Ok(()) - } - - fn check_function_definitions(&self) -> PartialVMResult<()> { - // FunctionDefinition - contained FunctionHandle defines uniqueness - if let Some(idx) = - Self::first_duplicate_element(self.module.function_defs().iter().map(|x| x.function)) - { - return Err(verification_error( - StatusCode::DUPLICATE_ELEMENT, - IndexKind::FunctionDefinition, - idx, - )); - } - // Acquires in function declarations contain unique struct definitions - for (idx, function_def) in self.module.function_defs().iter().enumerate() { - let acquires = function_def.acquires_global_resources.iter(); - if Self::first_duplicate_element(acquires).is_some() { - return Err(verification_error( - StatusCode::DUPLICATE_ACQUIRES_ANNOTATION, - IndexKind::FunctionDefinition, - idx as TableIndex, - )); - } - } - // Check that each function definition is pointing to the self module - if let Some(idx) = self.module.function_defs().iter().position(|x| { - self.module.function_handle_at(x.function).module != self.module.self_handle_idx() - }) { - return Err(verification_error( - StatusCode::INVALID_MODULE_HANDLE, - IndexKind::FunctionDefinition, - idx as TableIndex, - )); - } - // Check that each function handle in self module is implemented (has a - // declaration) - let implemented_function_handles: HashSet = self - .module - .function_defs() - .iter() - .map(|x| x.function) - .collect(); - if let Some(idx) = (0..self.module.function_handles().len()).position(|x| { - let y = FunctionHandleIndex::new(x as u16); - self.module.function_handle_at(y).module == self.module.self_handle_idx() - && !implemented_function_handles.contains(&y) - }) { - return Err(verification_error( - StatusCode::UNIMPLEMENTED_HANDLE, - IndexKind::FunctionHandle, - idx as TableIndex, - )); - } - Ok(()) - } - - fn first_duplicate_element(iter: T) -> Option - where - T: IntoIterator, - T::Item: Eq + Hash, - { - let mut uniq = HashSet::new(); - for (i, x) in iter.into_iter().enumerate() { - if !uniq.insert(x) { - return Some(i as TableIndex); - } - } - None - } -} diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/code_unit_verifier.rs b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/code_unit_verifier.rs deleted file mode 100644 index 8e4a1eebe54..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/code_unit_verifier.rs +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -//! This module implements the checker for verifying correctness of function bodies. -//! The overall verification is split between stack_usage_verifier.rs and -//! abstract_interpreter.rs. CodeUnitVerifier simply orchestrates calls into these two files. -use crate::{ - ability_cache::AbilityCache, acquires_list_verifier::AcquiresVerifier, control_flow, - locals_safety, reference_safety, stack_usage_verifier::StackUsageVerifier, type_safety, -}; -use move_abstract_interpreter::{absint::FunctionContext, control_flow_graph::ControlFlowGraph}; -use move_binary_format::{ - errors::{Location, PartialVMError, PartialVMResult, VMResult}, - file_format::{ - CompiledModule, FunctionDefinition, FunctionDefinitionIndex, IdentifierIndex, TableIndex, - }, - IndexKind, -}; -use move_bytecode_verifier_meter::{Meter, Scope}; -use move_core_types::vm_status::StatusCode; -use move_vm_config::verifier::VerifierConfig; -use std::collections::HashMap; - -pub struct CodeUnitVerifier<'env, 'a> { - module: &'env CompiledModule, - function_context: FunctionContext<'env>, - name_def_map: &'a HashMap, -} - -pub fn verify_module<'env>( - verifier_config: &VerifierConfig, - module: &'env CompiledModule, - ability_cache: &mut AbilityCache<'env>, - meter: &mut (impl Meter + ?Sized), -) -> VMResult<()> { - verify_module_impl(verifier_config, module, ability_cache, meter) - .map_err(|e| e.finish(Location::Module(module.self_id()))) -} - -fn verify_module_impl<'env>( - verifier_config: &VerifierConfig, - module: &'env CompiledModule, - ability_cache: &mut AbilityCache<'env>, - meter: &mut (impl Meter + ?Sized), -) -> PartialVMResult<()> { - let mut name_def_map = HashMap::new(); - for (idx, func_def) in module.function_defs().iter().enumerate() { - let fh = module.function_handle_at(func_def.function); - name_def_map.insert(fh.name, FunctionDefinitionIndex(idx as u16)); - } - let mut total_back_edges = 0; - for (idx, function_definition) in module.function_defs().iter().enumerate() { - let index = FunctionDefinitionIndex(idx as TableIndex); - let num_back_edges = verify_function( - verifier_config, - index, - function_definition, - module, - ability_cache, - &name_def_map, - meter, - ) - .map_err(|err| err.at_index(IndexKind::FunctionDefinition, index.0))?; - total_back_edges += num_back_edges; - } - if let Some(limit) = verifier_config.max_back_edges_per_module { - if total_back_edges > limit { - return Err(PartialVMError::new(StatusCode::TOO_MANY_BACK_EDGES)); - } - } - Ok(()) -} - -fn verify_function<'env>( - verifier_config: &VerifierConfig, - index: FunctionDefinitionIndex, - function_definition: &'env FunctionDefinition, - module: &'env CompiledModule, - ability_cache: &mut AbilityCache<'env>, - name_def_map: &HashMap, - meter: &mut (impl Meter + ?Sized), -) -> PartialVMResult { - meter.enter_scope( - module - .identifier_at(module.function_handle_at(function_definition.function).name) - .as_str(), - Scope::Function, - ); - // nothing to verify for native function - let code = match &function_definition.code { - Some(code) => code, - None => return Ok(0), - }; - - // create `FunctionContext` and `BinaryIndexedView` - let function_context = control_flow::verify_function( - verifier_config, - module, - index, - function_definition, - code, - meter, - )?; - - if let Some(limit) = verifier_config.max_basic_blocks { - if function_context.cfg().blocks().len() > limit { - return Err( - PartialVMError::new(StatusCode::TOO_MANY_BASIC_BLOCKS).at_code_offset(index, 0) - ); - } - } - - let num_back_edges = function_context.cfg().num_back_edges(); - if let Some(limit) = verifier_config.max_back_edges_per_function { - if num_back_edges > limit { - return Err( - PartialVMError::new(StatusCode::TOO_MANY_BACK_EDGES).at_code_offset(index, 0) - ); - } - } - - // verify - let code_unit_verifier = CodeUnitVerifier { - module, - function_context, - name_def_map, - }; - code_unit_verifier.verify_common(verifier_config, ability_cache, meter)?; - AcquiresVerifier::verify(module, index, function_definition, meter)?; - - meter.transfer(Scope::Function, Scope::Module, 1.0)?; - - Ok(num_back_edges) -} - -impl<'env, 'a> CodeUnitVerifier<'env, 'a> { - fn verify_common( - &self, - verifier_config: &VerifierConfig, - ability_cache: &mut AbilityCache<'env>, - meter: &mut (impl Meter + ?Sized), - ) -> PartialVMResult<()> { - StackUsageVerifier::verify(verifier_config, self.module, &self.function_context, meter)?; - type_safety::verify(self.module, &self.function_context, ability_cache, meter)?; - locals_safety::verify(self.module, &self.function_context, ability_cache, meter)?; - reference_safety::verify( - self.module, - &self.function_context, - self.name_def_map, - meter, - ) - } -} diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/constants.rs b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/constants.rs deleted file mode 100644 index fe14ea9eb3f..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/constants.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -//! This module implements a checker for verifying that -//! - a constant's type only refers to primitive types -//! - a constant's data serializes correctly for that type -use move_binary_format::{ - errors::{verification_error, Location, PartialVMResult, VMResult}, - file_format::{CompiledModule, Constant, SignatureToken, TableIndex}, - IndexKind, -}; -use move_core_types::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<()> { - for (idx, constant) in module.constant_pool().iter().enumerate() { - verify_constant(idx, constant)? - } - Ok(()) -} - -fn verify_constant(idx: usize, constant: &Constant) -> PartialVMResult<()> { - verify_constant_type(idx, &constant.type_)?; - verify_constant_data(idx, constant) -} - -fn verify_constant_type(idx: usize, type_: &SignatureToken) -> PartialVMResult<()> { - if type_.is_valid_for_constant() { - Ok(()) - } else { - Err(verification_error( - StatusCode::INVALID_CONSTANT_TYPE, - IndexKind::ConstantPool, - idx as TableIndex, - )) - } -} - -fn verify_constant_data(idx: usize, constant: &Constant) -> PartialVMResult<()> { - match constant.deserialize_constant() { - Some(_) => Ok(()), - None => Err(verification_error( - StatusCode::MALFORMED_CONSTANT_DATA, - IndexKind::ConstantPool, - idx as TableIndex, - )), - } -} diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/control_flow.rs b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/control_flow.rs deleted file mode 100644 index e66039afd94..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/control_flow.rs +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -//! This module implements control flow checks. -//! -//! For bytecode versions 6 and up, the following properties are ensured: -//! - The CFG is not empty and the last block ends in an unconditional jump, so -//! it's not possible to fall off the end of a function. -//! - The CFG is reducible (and optionally max loop depth is bounded), to limit -//! the potential for pathologically long abstract interpretation runtimes -//! (through poor choice of loop heads and back edges). -//! -//! For bytecode versions 5 and below, delegates to `control_flow_v5`. -use crate::{ - control_flow_v5, - loop_summary::{LoopPartition, LoopSummary}, -}; -use move_abstract_interpreter::absint::FunctionContext; -use move_binary_format::{ - errors::{PartialVMError, PartialVMResult}, - file_format::{CodeOffset, CodeUnit, FunctionDefinition, FunctionDefinitionIndex}, - CompiledModule, -}; -use move_bytecode_verifier_meter::Meter; -use move_core_types::vm_status::StatusCode; -use move_vm_config::verifier::VerifierConfig; -use std::collections::BTreeSet; - -/// Perform control flow verification on the compiled function, returning its -/// `FunctionContext` if verification was successful. -pub fn verify_function<'env>( - verifier_config: &VerifierConfig, - module: &'env CompiledModule, - index: FunctionDefinitionIndex, - function_definition: &'env FunctionDefinition, - code: &'env CodeUnit, - _meter: &mut (impl Meter + ?Sized), // TODO: metering -) -> PartialVMResult> { - let function_handle = module.function_handle_at(function_definition.function); - - if module.version() <= 5 { - control_flow_v5::verify(verifier_config, Some(index), code)?; - Ok(FunctionContext::new(module, index, code, function_handle)) - } else { - verify_fallthrough(Some(index), code)?; - let function_context = FunctionContext::new(module, index, code, function_handle); - verify_reducibility(verifier_config, &function_context)?; - Ok(function_context) - } -} - -/// Check to make sure that the bytecode vector is non-empty and ends with a -/// branching instruction. -fn verify_fallthrough( - current_function_opt: Option, - code: &CodeUnit, -) -> PartialVMResult<()> { - let current_function = current_function_opt.unwrap_or(FunctionDefinitionIndex(0)); - match code.code.last() { - None => Err(PartialVMError::new(StatusCode::EMPTY_CODE_UNIT)), - Some(last) if !last.is_unconditional_branch() => { - Err(PartialVMError::new(StatusCode::INVALID_FALL_THROUGH) - .at_code_offset(current_function, (code.code.len() - 1) as CodeOffset)) - } - Some(_) => Ok(()), - } -} - -/// Test that `function_context`'s control-flow graph is reducible using -/// Tarjan's algorithm [1]. Optionally test loop depth bounded by -/// `verifier_config.max_loop_depth`. -/// -/// A CFG, `G`, with starting block `s` is reducible if and only if [2] any of -/// the following equivalent properties hold: -/// -/// 1. G has a unique set of back-edges `u -> v` where `v` dominates `u`, that -/// corresponds to the set of back-edges for any depth-first spanning tree -/// of G. -/// -/// 2. Every loop in G contains a unique node `h` (the "head") which dominates -/// all other nodes in the loop. -/// -/// 3. G has a unique maximal (in terms of number of edges) acyclic sub-graph. -/// -/// 4. G can be reduced to a CFG containing just `s` through a sequence of the -/// following two operations: a. Delete a cyclic edge `v -> v` b. For an -/// edge `e: u -> v` where `e` is the only incident edge to `v`, collapse -/// `v` into `u` by deleting `e` and `v` and replacing all `v -> w` edges -/// with `u -> w` edges. -/// -/// Reducibility means that a control-flow graph can be decomposed into a series -/// of nested loops (strongly connected subgraphs), which leads to more -/// predictable abstract interpretation performance. -/// -/// ## References -/// -/// 1. Tarjan, R. 1974. Testing Flow Graph Reducibility. -/// 2. Hecht, M. S., Ullman J. D. 1974. Characterizations of Reducible Flow -/// Graphs. -fn verify_reducibility<'a>( - verifier_config: &VerifierConfig, - function_context: &'a FunctionContext<'a>, -) -> PartialVMResult<()> { - let current_function = function_context - .index() - .unwrap_or(FunctionDefinitionIndex(0)); - let err = move |code: StatusCode, offset: CodeOffset| { - Err(PartialVMError::new(code).at_code_offset(current_function, offset)) - }; - - let summary = LoopSummary::new(function_context.cfg()); - let mut partition = LoopPartition::new(&summary); - - // Iterate through nodes in reverse pre-order so more deeply nested loops (which - // would appear later in the pre-order) are processed first. - for head in summary.preorder().rev() { - // If a node has no back edges, it is not a loop head, so doesn't need to be - // processed. - let back = summary.back_edges(head); - if back.is_empty() { - continue; - } - - // Collect the rest of the nodes in `head`'s loop, in `body`. Start with the - // nodes that jump back to the head, and grow `body` by repeatedly - // following predecessor edges until `head` is found again. - - let mut body = BTreeSet::new(); - for node in back { - let node = partition.containing_loop(*node); - - if node != head { - body.insert(node); - } - } - - let mut frontier: Vec<_> = body.iter().copied().collect(); - while let Some(node) = frontier.pop() { - for pred in summary.pred_edges(node) { - let pred = partition.containing_loop(*pred); - - // `pred` can eventually jump back to `head`, so is part of its body. If it is - // not a descendant of `head`, it implies that `head` does not - // dominate a node in its loop, therefore the CFG is not - // reducible, according to Property 1 (see doc comment). - if !summary.is_descendant(/* ancestor */ head, /* descendant */ pred) { - return err(StatusCode::INVALID_LOOP_SPLIT, summary.block(pred)); - } - - let body_extended = pred != head && body.insert(pred); - if body_extended { - frontier.push(pred); - } - } - } - - // Collapse all the nodes in `body` into `head`, so it appears as one node when - // processing outer loops (this performs a sequence of Operation 4(b), - // followed by a 4(a)). - let depth = partition.collapse_loop(head, &body); - if let Some(max_depth) = verifier_config.max_loop_depth { - if depth as usize > max_depth { - return err(StatusCode::LOOP_MAX_DEPTH_REACHED, summary.block(head)); - } - } - } - - Ok(()) -} diff --git a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/control_flow_v5.rs b/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/control_flow_v5.rs deleted file mode 100644 index ce1a55b3a14..00000000000 --- a/external-crates/move/move-execution/v0/crates/move-bytecode-verifier/src/control_flow_v5.rs +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// Copyright (c) The Move Contributors -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -//! This module implements a checker to verify control flow in bytecode version -//! 5 and below. The following properties are ensured: -//! - All forward jumps do not enter into the middle of a loop -//! - All "breaks" (forward, loop-exiting jumps) go to the "end" of the loop -//! - All "continues" (back jumps in a loop) are only to the current loop -use std::{collections::HashSet, convert::TryInto}; - -use move_binary_format::{ - errors::{PartialVMError, PartialVMResult}, - file_format::{Bytecode, CodeOffset, CodeUnit, FunctionDefinitionIndex}, - safe_unwrap, -}; -use move_core_types::vm_status::StatusCode; -use move_vm_config::verifier::VerifierConfig; - -pub fn verify( - verifier_config: &VerifierConfig, - current_function_opt: Option, - code: &CodeUnit, -) -> PartialVMResult<()> { - let current_function = current_function_opt.unwrap_or(FunctionDefinitionIndex(0)); - - // check fallthrough - verify_fallthrough(current_function, &code.code)?; - - // check jumps - let context = &ControlFlowVerifier { - current_function, - code: &code.code, - }; - let labels = instruction_labels(context); - check_jumps(verifier_config, context, labels) -} - -fn verify_fallthrough( - current_function: FunctionDefinitionIndex, - code: &[Bytecode], -) -> PartialVMResult<()> { - // Check to make sure that the bytecode vector ends with a branching - // instruction. - match code.last() { - None => Err(PartialVMError::new(StatusCode::EMPTY_CODE_UNIT)), - Some(last) if !last.is_unconditional_branch() => { - Err(PartialVMError::new(StatusCode::INVALID_FALL_THROUGH) - .at_code_offset(current_function, (code.len() - 1) as CodeOffset)) - } - Some(_) => Ok(()), - } -} - -#[derive(Clone, Copy)] -enum Label { - Loop { last_continue: u16 }, - Code, -} - -struct ControlFlowVerifier<'a> { - current_function: FunctionDefinitionIndex, - code: &'a Vec, -} - -impl<'a> ControlFlowVerifier<'a> { - fn code(&self) -> impl Iterator { - self.code - .iter() - .enumerate() - .map(|(idx, instr)| (idx.try_into().unwrap(), instr)) - } - - fn labeled_code<'b: 'a>( - &self, - labels: &'b [Label], - ) -> impl Iterator { - self.code() - .zip(labels) - .map(|((i, instr), lbl)| (i, instr, lbl)) - } - - fn error(&self, status: StatusCode, offset: CodeOffset) -> PartialVMError { - PartialVMError::new(status).at_code_offset(self.current_function, offset) - } -} - -fn instruction_labels(context: &ControlFlowVerifier) -> Vec