diff --git a/.github/actions/install_rust/action.yml b/.github/actions/install_rust/action.yml index f22be34106..d40e4baa8a 100644 --- a/.github/actions/install_rust/action.yml +++ b/.github/actions/install_rust/action.yml @@ -1,9 +1,10 @@ # Installs rust toolchain with the version defined in .github/actions/install_rust/rust_version.txt. inputs: components: - description: "An optional parameter that will be sent to dtolnay/rust-toolchain." + description: "Optional: which additional components to install." required: false type: string + default: '' runs: using: "composite" @@ -11,6 +12,7 @@ runs: - name: Define toolchain run: echo "DEFAULT_TOOLCHAIN=$(cat .github/actions/install_rust/rust_version.txt)" >> $GITHUB_ENV shell: bash + - name: install rust toolchain with given components if: "${{ inputs.components != '' }}" uses: dtolnay/rust-toolchain@master diff --git a/.github/actions/setup-native-deps/action.yml b/.github/actions/setup-native-deps/action.yml index 7930558f4c..4b9e1f4d0a 100644 --- a/.github/actions/setup-native-deps/action.yml +++ b/.github/actions/setup-native-deps/action.yml @@ -5,37 +5,24 @@ outputs: cairo-native-runtime-library: description: "The path to the cairo native runtime library" value: ${{ steps.set-env-vars.outputs.cairo-native-runtime-library }} + runs: using: "composite" steps: - - name: Add llvm deb repository - uses: myci-actions/add-deb-repo@11 - with: - repo: deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main - repo-name: llvm-repo - keys-asc: https://apt.llvm.org/llvm-snapshot.gpg.key - - name: Install LLVM and gmplib + - name: Make script executable shell: bash - run: | - sudo apt-get update - sudo apt-get install llvm-18 llvm-18-dev llvm-18-runtime clang-18 clang-tools-18 lld-18 libpolly-18-dev libmlir-18-dev mlir-18-tools - sudo apt-get install -y libgmp3-dev + run: chmod +x ./scripts/setup_native_deps.sh - - name: Fetch Cairo Native Repository - uses: actions/checkout@v3 - with: - repository: "lambdaclass/cairo_native" - ref: "cairo-lang2.7.0-rc.3" - path: "cairo_native" - name: Install Cairo Native Runtime Dependencies + id: set-runtime-deps + shell: bash + run: | + sudo ./scripts/setup_native_deps.sh + + - name: Set Environment Variables id: set-env-vars shell: bash run: | - cd ./cairo_native && - echo "cairo-native-runtime-library=$(pwd)/target/release/libcairo_native_runtime.a" >> $GITHUB_OUTPUT && - echo "CAIRO_NATIVE_RUNTIME_LIBRARY=$(pwd)/target/release/libcairo_native_runtime.a" >> $GITHUB_ENV && echo "MLIR_SYS_180_PREFIX=/usr/lib/llvm-18/" >> $GITHUB_ENV && echo "LLVM_SYS_181_PREFIX=/usr/lib/llvm-18/" >> $GITHUB_ENV && - echo "TABLEGEN_180_PREFIX=/usr/lib/llvm-18/" >> $GITHUB_ENV && - cd ./runtime && - cargo build --release \ No newline at end of file + echo "TABLEGEN_180_PREFIX=/usr/lib/llvm-18/" >> $GITHUB_ENV \ No newline at end of file diff --git a/.github/workflows/blockifier_ci.yml b/.github/workflows/blockifier_ci.yml index 9b653a44dd..a18ff977e0 100644 --- a/.github/workflows/blockifier_ci.yml +++ b/.github/workflows/blockifier_ci.yml @@ -39,77 +39,15 @@ concurrency: jobs: featureless-build: - runs-on: starkware-ubuntu-20-04-medium + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/install_rust + - uses: Swatinem/rust-cache@v2 + with: + prefix-key: "v0-rust-ubuntu-latest" - name: Set up Native Dependencies uses: ./.github/actions/setup-native-deps id: native-deps - - uses: Swatinem/rust-cache@v2 - with: - prefix-key: "v0-rust-ubuntu-20.04" - run: cargo build -p blockifier - run: cargo test -p blockifier - - native-blockifier-artifacts-push: - runs-on: starkware-ubuntu-20-04-medium - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - - uses: Swatinem/rust-cache@v2 - with: - prefix-key: "v1-rust-ubuntu-20.04" - - - name: Build native blockifier - run: ./build_native_in_docker.sh scripts/build_native_blockifier.sh - - # Commit hash on pull request event would be the head commit of the branch. - - name: Get commit hash prefix for PR update - if: ${{ github.event_name == 'pull_request' }} - env: - COMMIT_SHA: ${{ github.event.pull_request.head.sha }} - run: echo "SHORT_HASH=${COMMIT_SHA:0:7}" >> $GITHUB_ENV - - # On push event (to main, for example) we should take the commit post-push. - - name: Get commit hash prefix for merge - if: ${{ github.event_name != 'pull_request' }} - env: - COMMIT_SHA: ${{ github.event.after }} - run: echo "SHORT_HASH=${COMMIT_SHA:0:7}" >> $GITHUB_ENV - - # Rename is required; see https://pyo3.rs/v0.19.2/building_and_distribution#manual-builds. - - name: Rename shared object - run: | - mv \ - target/release/libnative_blockifier.so \ - target/release/native_blockifier.pypy39-pp73-x86_64-linux-gnu.so - - # Check if the user has the required permission to upload the artifact. - - name: Get User Permission - id: checkAccess - uses: actions-cool/check-user-permission@v2 - with: - require: write - username: ${{ github.triggering_actor }} - - - name: Check User Permission - if: steps.checkAccess.outputs.require-result == 'false' - run: | - echo "${{ github.triggering_actor }} does not have permissions on this repo." - echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}" - echo "Job originally triggered by ${{ github.actor }}" - exit 1 - - - name: Authenticate with GCS - uses: "google-github-actions/auth@v2" - with: - credentials_json: ${{ secrets.SA_NATIVE_BLOCKIFIER_ARTIFACTS_BUCKET_WRITER_ACCESS_KEY }} - - - name: Upload binary to GCP - id: upload_file - uses: "google-github-actions/upload-cloud-storage@v2" - with: - path: "target/release/native_blockifier.pypy39-pp73-x86_64-linux-gnu.so" - destination: "native_blockifier_artifacts/${{ env.SHORT_HASH }}/release/" diff --git a/.github/workflows/blockifier_compiled_cairo.yml b/.github/workflows/blockifier_compiled_cairo.yml index 619764481f..295f8e8fb4 100644 --- a/.github/workflows/blockifier_compiled_cairo.yml +++ b/.github/workflows/blockifier_compiled_cairo.yml @@ -32,13 +32,17 @@ concurrency: jobs: verify_cairo_file_dependencies: - runs-on: starkware-ubuntu-20-04-medium + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/install_rust - uses: Swatinem/rust-cache@v2 with: - prefix-key: "v0-rust-ubuntu-20.04" + prefix-key: "v0-rust-ubuntu-latest" + + - name: Set up Native Dependencies + uses: ./.github/actions/setup-native-deps + id: native-deps # Setup pypy and link to the location expected by .cargo/config.toml. - uses: actions/setup-python@v5 @@ -70,10 +74,6 @@ jobs: with: toolchain: nightly-2023-07-05 - - name: set up native dependencies - uses: ./.github/actions/setup-native-deps - id: native-deps - - name: Verify cairo contract recompilation (both cairo versions). run: cd sequencer && diff --git a/.github/workflows/blockifier_post-merge.yml b/.github/workflows/blockifier_post-merge.yml index 9d5c285677..6e27e4525e 100644 --- a/.github/workflows/blockifier_post-merge.yml +++ b/.github/workflows/blockifier_post-merge.yml @@ -12,15 +12,15 @@ on: jobs: if_merged: if: github.event.pull_request.merged == true - runs-on: starkware-ubuntu-20-04-medium + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/install_rust - uses: Noelware/setup-protoc@1.1.0 - uses: Swatinem/rust-cache@v2 with: - prefix-key: "v0-rust-ubuntu-20.04" - + prefix-key: "v0-rust-ubuntu-latest" + - name: Set up Native Dependencies uses: ./.github/actions/setup-native-deps id: native-deps diff --git a/.github/workflows/clean_stale_prs.yml b/.github/workflows/clean_stale_prs.yml deleted file mode 100644 index 1ccbe73ac8..0000000000 --- a/.github/workflows/clean_stale_prs.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- -name: Clean-Stale-PRs - -on: - schedule: - - cron: "0 8 * * *" - workflow_dispatch: - -jobs: - stale: - name: ๐Ÿงน Clean up stale issues and PRs - runs-on: starkware-ubuntu-latest-small - steps: - - name: ๐Ÿš€ Run stale - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - days-before-stale: 30 - days-before-close: 7 - remove-stale-when-updated: true - stale-issue-label: "stale" - exempt-issue-labels: "no-stale,help-wanted" - stale-issue-message: > - There hasn't been any activity on this issue recently, and in order - to prioritize active issues, it will be marked as stale. - - Please make sure to update to the latest version and - check if that solves the issue. Let us know if that works for you - by leaving a ๐Ÿ‘ - - Because this issue is marked as stale, it will be closed and locked - in 7 days if no further activity occurs. - - Thank you for your contributions! - stale-pr-label: "stale" - exempt-pr-labels: "no-stale" - stale-pr-message: > - There hasn't been any activity on this pull request recently, and in - order to prioritize active work, it has been marked as stale. - - This PR will be closed and locked in 7 days if no further activity - occurs. - - Thank you for your contributions! diff --git a/.github/workflows/committer_ci.yml b/.github/workflows/committer_ci.yml index d7ce4d16f6..5427a6d148 100644 --- a/.github/workflows/committer_ci.yml +++ b/.github/workflows/committer_ci.yml @@ -12,6 +12,7 @@ on: - 'Cargo.toml' - 'Cargo.lock' - 'crates/committer_cli/**' + - 'crates/starknet_api/**' - 'crates/starknet_committer/**' - 'crates/starknet_patricia/**' @@ -27,6 +28,7 @@ on: - 'Cargo.toml' - 'Cargo.lock' - 'crates/committer_cli/**' + - 'crates/starknet_api/**' - 'crates/starknet_committer/**' - 'crates/starknet_patricia/**' diff --git a/.github/workflows/lock_closed_prs.yml b/.github/workflows/lock_closed_prs.yml deleted file mode 100644 index 91b0175ffd..0000000000 --- a/.github/workflows/lock_closed_prs.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Lock-Closed-Issues - -on: - schedule: - - cron: "0 9 * * *" - workflow_dispatch: - -jobs: - lock: - name: ๐Ÿ”’ Lock closed issues and PRs - runs-on: starkware-ubuntu-latest-small - steps: - - uses: dessant/lock-threads@v2.0.3 - with: - github-token: ${{ github.token }} - issue-lock-inactive-days: "30" - issue-lock-reason: "" - issue-comment: > - Issue closed and locked due to lack of activity. - - If you encounter this same issue, please open a new issue and refer - to this closed one. - pr-lock-inactive-days: "1" - pr-lock-reason: "" - pr-comment: > - Pull Request closed and locked due to lack of activity. - - If you'd like to build on this closed PR, you can clone it using - this method: https://stackoverflow.com/a/14969986 - - Then open a new PR, referencing this closed PR in your message. diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1bcd2564cb..c6f216a24c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,7 +23,7 @@ concurrency: jobs: commitlint: - runs-on: starkware-ubuntu-latest-small + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: @@ -46,7 +46,7 @@ jobs: run: echo "$TITLE" | commitlint --verbose format: - runs-on: starkware-ubuntu-20-04-medium + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master # TODO(Nimrod, 15/8/2024): Use stable toolchain. @@ -55,29 +55,32 @@ jobs: toolchain: nightly-2024-04-29 - uses: Swatinem/rust-cache@v2 with: - prefix-key: "v0-rust-ubuntu-20.04" + prefix-key: "v0-rust-ubuntu-latest" - run: scripts/rust_fmt.sh --check clippy: - runs-on: starkware-ubuntu-20-04-medium + runs-on: ubuntu-latest steps: + # Enviorment setup. - uses: actions/checkout@v4 - uses: Noelware/setup-protoc@1.1.0 - - uses: ./.github/actions/install_rust + - uses: baptiste0928/cargo-install@v3 with: components: clippy + - name: Set up Native Dependencies uses: ./.github/actions/setup-native-deps id: native-deps + - uses: Swatinem/rust-cache@v2 with: - prefix-key: "v0-rust-ubuntu-20.04" + prefix-key: "v0-rust-ubuntu-latest" # Setup pypy and link to the location expected by .cargo/config.toml. - uses: actions/setup-python@v5 id: setup-pypy with: - python-version: 'pypy3.9' + python-version: "pypy3.9" - run: ln -s '${{ steps.setup-pypy.outputs.python-path }}' /usr/local/bin/pypy3.9 - env: LD_LIBRARY_PATH: ${{ steps.setup-pypy.outputs.pythonLocation }}/bin @@ -86,7 +89,7 @@ jobs: - run: scripts/clippy.sh doc: - runs-on: starkware-ubuntu-latest-small + runs-on: ubuntu-latest env: RUSTDOCFLAGS: "-D warnings" steps: @@ -99,18 +102,10 @@ jobs: - uses: Noelware/setup-protoc@1.1.0 with: version: ${{env.PROTOC_VERSION}} - - run: cargo doc --workspace -r --document-private-items --no-deps - - run-workspace-tests: - runs-on: starkware-ubuntu-latest-small - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - run: cargo test -p workspace_tests + - run: cargo doc -p blockifier -r --document-private-items --no-deps run-tests: - runs-on: starkware-ubuntu-20-04-medium + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: @@ -123,13 +118,13 @@ jobs: - uses: Noelware/setup-protoc@1.1.0 - uses: Swatinem/rust-cache@v2 with: - prefix-key: "v0-rust-ubuntu-20.04" + prefix-key: "v0-rust-ubuntu-latest" # Setup pypy and link to the location expected by .cargo/config.toml. - uses: actions/setup-python@v5 id: setup-pypy with: - python-version: 'pypy3.9' + python-version: "pypy3.9" - run: ln -s '${{ steps.setup-pypy.outputs.python-path }}' /usr/local/bin/pypy3.9 - env: LD_LIBRARY_PATH: ${{ env.Python3_ROOT_DIR }}/bin @@ -154,7 +149,7 @@ jobs: SEED: 0 taplo: - runs-on: starkware-ubuntu-latest-small + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/install_rust @@ -162,85 +157,29 @@ jobs: - uses: baptiste0928/cargo-install@v3 with: crate: taplo-cli - version: '0.9.0' + version: "0.9.0" locked: true - run: scripts/taplo.sh machete: - runs-on: starkware-ubuntu-latest-small + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Machete (detect unused dependencies) uses: bnjbvr/cargo-machete@main check: - runs-on: starkware-ubuntu-latest-small + runs-on: ubuntu-latest env: RUSTDOCFLAGS: "-D warnings" steps: - uses: actions/checkout@v4 - uses: ./.github/actions/install_rust - - name: Set up Native Dependencies - uses: ./.github/actions/setup-native-deps - id: native-deps - uses: Swatinem/rust-cache@v2 - uses: Noelware/setup-protoc@1.1.0 with: version: ${{env.PROTOC_VERSION}} - - run: cargo check --workspace -r --all-features - - merge-gatekeeper: - runs-on: starkware-ubuntu-latest-small - # Restrict permissions of the GITHUB_TOKEN. - # Docs: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs - permissions: - checks: read - statuses: read - steps: - - name: Run Merge Gatekeeper on pull request - if: github.event_name == 'pull_request' - uses: upsidr/merge-gatekeeper@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - timeout: 1200 - interval: 30 - ignored: "code-review/reviewable" - - - name: Run Merge Gatekeeper on Merge Queue || push - if: github.event_name == 'merge_group' || github.event_name == 'push' - uses: upsidr/merge-gatekeeper@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - ref: ${{github.ref}} - timeout: 1200 - interval: 30 - ignored: "code-review/reviewable" - - codecov: - runs-on: starkware-ubuntu-latest-medium - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - name: Set-Up - run: | - sudo apt-get update - sudo apt-get install -y clang llvm libudev-dev - - uses: Noelware/setup-protoc@1.1.0 - with: - version: ${{env.PROTOC_VERSION}} - - - name: Install cargo-llvm-cov - uses: taiki-e/install-action@cargo-llvm-cov - - uses: Swatinem/rust-cache@v2 - - run: npm install -g ganache@7.4.3 - - name: Coverage - run: cargo llvm-cov --codecov -r --output-path codecov.json - env: - SEED: 0 - - name: Codecov - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - fail_ci_if_error: true - version: "v0.1.15" + - name: Set up Native Dependencies + uses: ./.github/actions/setup-native-deps + id: native-deps + - run: cargo check -p blockifier -r --all-features diff --git a/.github/workflows/merge_paths_ci.yml b/.github/workflows/merge_paths_ci.yml deleted file mode 100644 index 65e11b51f2..0000000000 --- a/.github/workflows/merge_paths_ci.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Merge-paths test - -on: - push: - branches: - - main - - main-v[0-9].** - tags: - - v[0-9].** - paths: - - '.github/workflows/merge_paths_ci.yml' - - 'scripts/merge_branches.py' - - 'scripts/merge_paths.json' - - 'scripts/merge_paths_test.py' - - 'scripts/merge_status.py' - - pull_request: - types: - - opened - - reopened - - synchronize - - auto_merge_enabled - - edited - paths: - - '.github/workflows/merge_paths_ci.yml' - - 'scripts/merge_branches.py' - - 'scripts/merge_paths.json' - - 'scripts/merge_paths_test.py' - - 'scripts/merge_status.py' - -# On PR events, cancel existing CI runs on this same PR for this workflow. -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - merge-paths-test: - runs-on: starkware-ubuntu-latest-small - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.9' - - run: | - python -m pip install --upgrade pip - pip install pytest - - run: pytest scripts/merge_paths_test.py diff --git a/.github/workflows/papyrus/helm-install.yml b/.github/workflows/papyrus/helm-install.yml index 886f307f09..e06b2ca832 100644 --- a/.github/workflows/papyrus/helm-install.yml +++ b/.github/workflows/papyrus/helm-install.yml @@ -14,7 +14,7 @@ on: jobs: deploy-teardown: - runs-on: starkware-ubuntu-latest-small + runs-on: ubuntu-latest permissions: contents: "read" id-token: "write" diff --git a/.github/workflows/papyrus_benchmark.yaml b/.github/workflows/papyrus_benchmark.yaml deleted file mode 100644 index b7912e4957..0000000000 --- a/.github/workflows/papyrus_benchmark.yaml +++ /dev/null @@ -1,57 +0,0 @@ -name: Papyrus-Benchmarks - -on: - workflow_dispatch: - # TODO: Uncomment and run this automatically when the storage benchmark is fixed. - # push: - # branches: [main] - -jobs: - storage-benchmark: - runs-on: ubuntu-latest - permissions: - contents: "write" - id-token: "write" - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - id: "auth" - name: "Authenticate to Google Cloud" - uses: "google-github-actions/auth@v1" - with: - credentials_json: "${{ secrets.GOOGLE_CI_SA_CREDENTIALS }}" - - - id: "get-credentials" - name: Get GKE credentials - uses: "google-github-actions/get-gke-credentials@v1" - with: - cluster_name: "${{ secrets.GKE_CI_CLUSTER_NAME }}" - location: "${{ secrets.GKE_CI_CLUSTER_REGION }}" - - - name: Run benchmark test - run: sh -c "deployments/storage-benchmark/run_benchmark.bash 5m" - - - name: Download previous benchmark data - uses: actions/cache@v4 - with: - path: ./cache - key: ${{ runner.os }}-benchmark - - # Run `github-action-benchmark` action - - name: Store benchmark result - uses: benchmark-action/github-action-benchmark@v1 - with: - name: "Papyrus storage benchmark" - # What benchmark tool the output.txt came from - tool: 'customSmallerIsBetter' - # Where the output from the benchmark tool is stored - output-file-path: output.txt - - # Push to gh-pages branch - - name: Push benchmark result - run: | - git switch gh-pages - git push https://github.com/starkware-libs/papyrus.git gh-pages:gh-pages --no-verify - git checkout - diff --git a/.github/workflows/papyrus_ci.yml b/.github/workflows/papyrus_ci.yml deleted file mode 100644 index 875c556c68..0000000000 --- a/.github/workflows/papyrus_ci.yml +++ /dev/null @@ -1,203 +0,0 @@ -name: Papyrus-CI - -on: - push: - branches: [main] - paths: - - '.github/workflows/papyrus_ci.yml' - - 'Dockerfile' - - 'papyrus_utilities.Dockerfile' - - 'Cargo.toml' - - 'Cargo.lock' - - 'crates/papyrus**/**' - - 'crates/sequencing/**' - - 'crates/starknet_client/**' - - pull_request: - types: - - opened - - reopened - - synchronize - - auto_merge_enabled - - edited # for when the PR title is edited - paths: - - '.github/workflows/papyrus_ci.yml' - - 'Dockerfile' - - 'papyrus_utilities.Dockerfile' - - 'Cargo.toml' - - 'Cargo.lock' - - 'crates/papyrus**/**' - - 'crates/sequencing/**' - - 'crates/starknet_client/**' - - merge_group: - types: [checks_requested] - -# On PR events, cancel existing CI runs on this same PR for this workflow. -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -env: - PROTOC_VERSION: v25.1 - -jobs: - executable-run: - runs-on: starkware-ubuntu-latest-medium - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - uses: Noelware/setup-protoc@1.1.0 - with: - version: ${{env.PROTOC_VERSION}} - - name: Build node - run: | - mkdir data - cargo build -r -p papyrus_node - - - name: Run executable - run: > - target/release/papyrus_node --base_layer.node_url ${{ secrets.CI_BASE_LAYER_NODE_URL }} - & sleep 30 ; kill $! - - executable-run-no-rpc: - runs-on: starkware-ubuntu-latest-medium - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - uses: Noelware/setup-protoc@1.1.0 - with: - version: ${{env.PROTOC_VERSION}} - - name: Build node - run: | - mkdir data - cargo build -r -p papyrus_node --no-default-features - - - name: Run executable - run: > - target/release/papyrus_node --base_layer.node_url ${{ secrets.CI_BASE_LAYER_NODE_URL }} - & sleep 30 ; kill $! - - p2p-sync-e2e-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - uses: Noelware/setup-protoc@1.1.0 - with: - version: ${{env.PROTOC_VERSION}} - - - name: Build node - run: | - cargo build -r -p papyrus_node - - - name: Run p2p sync end-to-end test - run: | - scripts/papyrus/p2p_sync_e2e_test/main.sh ${{ secrets.CI_BASE_LAYER_NODE_URL }} - - integration-test: - runs-on: starkware-ubuntu-latest-medium - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - uses: Noelware/setup-protoc@1.1.0 - with: - version: ${{env.PROTOC_VERSION}} - - run: > - cargo test -r - --test latency_histogram - --test gateway_integration_test - --test feeder_gateway_integration_test - -- --include-ignored --skip test_gw_integration_testnet; - cargo run -r -p papyrus_node --bin central_source_integration_test --features="futures-util tokio-stream" - - test-no-rpc: - runs-on: starkware-ubuntu-latest-medium - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - uses: Noelware/setup-protoc@1.1.0 - - - run: | - cargo test -p papyrus_node --no-default-features - env: - SEED: 0 - - codecov: - runs-on: starkware-ubuntu-latest-medium - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - name: Set-Up - run: | - sudo apt-get update - sudo apt-get install -y clang llvm libudev-dev - - uses: Noelware/setup-protoc@1.1.0 - with: - version: ${{env.PROTOC_VERSION}} - - - name: Install cargo-llvm-cov - uses: taiki-e/install-action@cargo-llvm-cov - - uses: Swatinem/rust-cache@v2 - - run: npm install -g ganache - - name: Coverage - run: cargo llvm-cov --codecov -r --output-path codecov.json - env: - SEED: 0 - - name: Codecov - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - fail_ci_if_error: true - version: "v0.1.15" - - check-starknet_api-dependency: - runs-on: starkware-ubuntu-latest-small - if: github.base_ref == 'main' # this step is only run if the pr is to the main branch - steps: - - uses: actions/checkout@v4 - - run: sudo apt-get install jq - - run: ./check_starknet_api_version_dependency.sh # this script checks that if the starknet_api dependency is by git rev then this rev (commit) is on main - - build-papyrus-utilities-image: - runs-on: starkware-ubuntu-latest-medium - steps: - - uses: actions/checkout@v4 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Build Papyrus utilites docker image - uses: docker/build-push-action@v3.2.0 - continue-on-error: true # ignore the failure of a step and avoid terminating the job. - with: - push: false - context: . - file: papyrus_utilities.Dockerfile - cache-from: type=gha,scope=buildkit-ci - cache-to: type=gha,mode=max,scope=buildkit-ci - - random-table-test: - runs-on: starkware-ubuntu-latest-medium - steps: - - uses: actions/checkout@v4 - # run this job only if the path 'crates/papyrus_storage/src/db/**' is changed, because it takes around 2 minutes. - - uses: dorny/paths-filter@v3 - id: changes - with: - # The 'base' and 'ref' parameters are set to be able to run the job in a 'merge_group' event. in a 'pull_request' event - # those parameters are ignored. - base: ${{ github.event.merge_group.base_ref}} - ref: ${{ github.event.merge_group.head_ref }} - filters: | - target_directory: - - 'crates/papyrus_storage/src/db/**' - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - # repeat this job 32 times. this is a random test for part of the code that may cause a corrupted database. - - run: for run in {1..32}; do cargo test -r -p papyrus_storage -- --include-ignored common_prefix_compare_with_simple_table_random; done - if: steps.changes.outputs.target_directory == 'true' diff --git a/.github/workflows/papyrus_docker-publish.yml b/.github/workflows/papyrus_docker-publish.yml deleted file mode 100644 index 2035a801d0..0000000000 --- a/.github/workflows/papyrus_docker-publish.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: Papyrus-Docker-Publish - -on: - workflow_dispatch: - push: - branches: [main] - tags: ["v*.*.*"] - paths: - - '.github/workflows/papyrus_docker-publish.yml' - - 'crates/papyrus**/**' - - pull_request: - paths: - - '.github/workflows/papyrus_docker-publish.yml' - - 'crates/papyrus**/**' - -# On PR events, cancel existing CI runs on this same PR for this workflow. -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -env: - REGISTRY: ghcr.io - REPO_NAME: ${{ github.repository }} - -jobs: - docker-build-push: - runs-on: starkware-ubuntu-latest-medium - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Not required but recommended - enables build multi-platform images, export cache, etc - # Also workaround for: https://github.com/docker/build-push-action/issues/461 - # https://github.com/docker/setup-buildx-action - - name: Setup Docker buildx - uses: docker/setup-buildx-action@v2.2.1 - - # Login to a Docker registry except on PR - # https://github.com/docker/login-action - - name: Login to registry ${{ env.REGISTRY }} - if: github.event_name != 'pull_request' - uses: docker/login-action@v2.1.0 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - logout: true - - # Extract metadata (tags, labels) for Docker - # https://github.com/docker/metadata-action - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v4.1.1 - with: - images: ${{ env.REGISTRY }}/${{ env.REPO_NAME }}/papyrus - tags: | - type=semver,pattern={{raw}} - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=ref,event=pr - # set `dev` tag for the default branch (`main`). - type=raw,value=dev,enable={{is_default_branch}} - type=raw,value={{branch}}{{tag}}-{{sha}},enable=${{ github.event_name == 'workflow_dispatch' }} - - # Build and push Docker image with Buildx - # https://github.com/docker/build-push-action - - name: Build and push Docker image - uses: docker/build-push-action@v3.2.0 - with: - context: . - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/.github/workflows/papyrus_nightly-tests-call.yml b/.github/workflows/papyrus_nightly-tests-call.yml deleted file mode 100644 index 64980b6ab5..0000000000 --- a/.github/workflows/papyrus_nightly-tests-call.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Papyrus-Nightly-Tests-Call - -on: - workflow_call: - inputs: - os: - required: true - type: string - secrets: - INTEGRATION_TESTNET_NODE_URL: - required: true - INTEGRATION_TESTNET_SENDER_PRIVATE_KEY: - required: true - SLACK_BOT_TOKEN: - required: true - SLACK_ALERT_CHANNEL: - required: true - -jobs: - GW-integration-test-call: - runs-on: ${{ inputs.os }} - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - run: sudo apt update; sudo apt -y install libclang-dev - # Install libclang-dev that is not a part of the ubuntu vm in github actions. - if: runner.os == 'Linux' - - name: Run gateway_integration_test. - id: run_test - # Workflow steps exit upon failure of a subcommand (running `set -e` implicitly before the - # run). As we want to keep running this step after a test failure we can either start with - # `set +e` to suppress all errors, or, as done below, append `|| retVal=$?` to the command - # which makes it successful while storing the potential erroneous code. - run: > - retVal=0; - INTEGRATION_TESTNET_NODE_URL=${{ secrets.INTEGRATION_TESTNET_NODE_URL }} - SENDER_PRIVATE_KEY=${{ secrets.INTEGRATION_TESTNET_SENDER_PRIVATE_KEY }} - cargo test --test gateway_integration_test -p papyrus_rpc test_gw_integration_testnet - -- --ignored || retVal=$?; - echo "retVal=$retVal" >> $GITHUB_OUTPUT; - if [ $retVal -ne 0 ]; then - echo "Integration test failed with exit code $retVal"; - fi; - - name: In case of a failure - post to a Slack channel. - id: slack - if: ${{ steps.run_test.outputs.retVal != 0 }} - uses: slackapi/slack-github-action@v1.24.0 - with: - channel-id: ${{ secrets.SLACK_ALERT_CHANNEL }} - slack-message: > - gateway_integration_test failed with exit code: ${{ steps.run_test.outputs.retVal }}, - see - <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}| - logs>. - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - - name: Fail job in case of test failure. - if: ${{ steps.run_test.outputs.retVal != 0 }} - run: exit 1 diff --git a/.github/workflows/papyrus_nightly-tests.yml b/.github/workflows/papyrus_nightly-tests.yml deleted file mode 100644 index a7a91d5687..0000000000 --- a/.github/workflows/papyrus_nightly-tests.yml +++ /dev/null @@ -1,103 +0,0 @@ -name: Papyrus-Nightly-Tests -# We run gateway_integration_test at different times, to avoid a nonce race between parallel runs. -on: - schedule: - - cron: '30 22 * * *' # Uses ubuntu runner. - - cron: '30 0 * * *' # Uses macos runner. - workflow_dispatch: # Uses ubuntu runner. - -env: - PROTOC_VERSION: 25 # homebrew doesn't support minor versions - -jobs: - GW-integration-test-ubuntu: - uses: ./.github/workflows/papyrus_nightly-tests-call.yml - with: - os: starkware-ubuntu-latest-small - secrets: - INTEGRATION_TESTNET_NODE_URL: ${{ secrets.INTEGRATION_TESTNET_NODE_URL }} - INTEGRATION_TESTNET_SENDER_PRIVATE_KEY: ${{ secrets.INTEGRATION_TESTNET_SENDER_PRIVATE_KEY }} - SLACK_ALERT_CHANNEL: ${{ secrets.SLACK_ALERT_CHANNEL }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - if: github.event.schedule != '30 0 * * *' - - GW-integration-test-macos: - uses: ./.github/workflows/papyrus_nightly-tests-call.yml - with: - os: macos-latest - secrets: - INTEGRATION_TESTNET_NODE_URL: ${{ secrets.INTEGRATION_TESTNET_NODE_URL }} - INTEGRATION_TESTNET_SENDER_PRIVATE_KEY: ${{ secrets.INTEGRATION_TESTNET_SENDER_PRIVATE_KEY }} - SLACK_ALERT_CHANNEL: ${{ secrets.SLACK_ALERT_CHANNEL }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - if: github.event.schedule == '30 0 * * *' - - executable-run: - runs-on: macos-latest - if: github.event.schedule == '30 0 * * *' - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - - run: mkdir data - - - run: brew install protobuf@$PROTOC_VERSION - - - name: Build node - run: cargo build -r -p papyrus_node - - - name: Run executable - run: > - target/release/papyrus_node --base_layer.node_url ${{ secrets.CI_BASE_LAYER_NODE_URL }} - & sleep 30 ; kill $! - - test: - runs-on: macos-latest - if: github.event.schedule == '30 0 * * *' - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - run: npm install -g ganache@7.4.3 - - - run: brew install protobuf@$PROTOC_VERSION - - - run: | - cargo test -r -p papyrus_node - env: - SEED: 0 - - build-load-test: - runs-on: macos-latest - if: github.event.schedule == '30 0 * * *' - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - run: cargo build -r -p papyrus_load_test - - integration-test: - runs-on: macos-latest - if: github.event.schedule == '30 0 * * *' - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - run: > - cargo test -r - --test latency_histogram - --test gateway_integration_test - --test feeder_gateway_integration_test - -- --include-ignored --skip test_gw_integration_testnet; - cargo run -r -p papyrus_node --bin central_source_integration_test --features="futures-util tokio-stream" - - # TODO(dvir): make this run only if the path 'crates/papyrus_storage/src/db/**' (same path as in the CI) was changed on the - # last day and increase the number of repetitions. - random-table-test: - runs-on: starkware-ubuntu-latest-small - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/install_rust - - uses: Swatinem/rust-cache@v2 - - run: for run in {1..100}; do cargo test -r -p papyrus_storage -- --include-ignored common_prefix_compare_with_simple_table_random; done diff --git a/.github/workflows/verify-deps.yml b/.github/workflows/verify-deps.yml index e23ac29496..dc7f0f9640 100644 --- a/.github/workflows/verify-deps.yml +++ b/.github/workflows/verify-deps.yml @@ -7,11 +7,14 @@ on: jobs: latest_deps: name: Latest Dependencies - runs-on: starkware-ubuntu-latest-medium + runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v4 - uses: ./.github/actions/install_rust + - name: Set up Native Dependencies + uses: ./.github/actions/setup-native-deps + id: native-deps - name: Update Dependencies run: cargo update --verbose - name: Build diff --git a/.gitignore b/.gitignore index 77f8b26aae..cab3c61de7 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,7 @@ scripts/__pycache__ # Papyrus p2p sync test artifacts. scripts/papyrus/p2p_sync_e2e_test/data_client/ scripts/papyrus/p2p_sync_e2e_test/data_server/ + +# Papyrus helm chart +deployments/papyrus/helm/config/* +!deployments/papyrus/helm/config/example.json diff --git a/Cargo.lock b/Cargo.lock index 0c9f9b8a37..0e2e75a517 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,19 +14,13 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "adler2" version = "2.0.0" @@ -169,9 +163,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "aquamarine" @@ -184,7 +178,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -323,9 +317,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -366,7 +360,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "synstructure", ] @@ -378,7 +372,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -435,9 +429,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ "async-task", "concurrent-queue", @@ -506,7 +500,7 @@ dependencies = [ "futures-lite 2.3.0", "parking", "polling 3.7.3", - "rustix 0.38.34", + "rustix 0.38.37", "slab", "tracing", "windows-sys 0.59.0", @@ -556,7 +550,7 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.34", + "rustix 0.38.37", "windows-sys 0.48.0", ] @@ -568,7 +562,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -583,7 +577,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.34", + "rustix 0.38.37", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -591,20 +585,20 @@ dependencies = [ [[package]] name = "async-std" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" dependencies = [ "async-channel 1.9.0", "async-global-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io 2.3.4", + "async-lock 3.4.0", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 1.13.0", - "gloo-timers", + "futures-lite 2.3.0", + "gloo-timers 0.3.0", "kv-log-macro", "log", "memchr", @@ -634,7 +628,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -645,13 +639,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -716,7 +710,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -785,17 +779,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", - "miniz_oxide 0.7.4", + "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -896,7 +890,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -918,7 +912,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.76", + "syn 2.0.77", "which", ] @@ -1009,9 +1003,10 @@ dependencies = [ "criterion", "derive_more", "glob", - "indexmap 2.4.0", - "itertools 0.10.5", + "indexmap 2.5.0", + "itertools 0.12.1", "keccak", + "lazy_static", "log", "num-bigint 0.4.6", "num-integer", @@ -1086,6 +1081,16 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +[[package]] +name = "byte-unit" +version = "4.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" +dependencies = [ + "serde", + "utf8-width", +] + [[package]] name = "bytecount" version = "0.6.8" @@ -1100,9 +1105,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" dependencies = [ "serde", ] @@ -1360,7 +1365,7 @@ checksum = "c33b5f4502b7efde6ac07fd5468f6dae15d88760aeece3d57a7bc4c224ba693e" dependencies = [ "cairo-lang-debug", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1674,7 +1679,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73104609a7d865e4cd1de9cbf4e750683d076b6d0233bf81be511df274a26916" dependencies = [ "hashbrown 0.14.5", - "indexmap 2.4.0", + "indexmap 2.5.0", "itertools 0.12.1", "num-bigint 0.4.6", "num-traits 0.2.19", @@ -1686,7 +1691,7 @@ dependencies = [ [[package]] name = "cairo-native" version = "0.2.0" -source = "git+https://github.com/lambdaclass/cairo_native#2be717cba74c63628cb68b619ff2022c70d0cdd2" +source = "git+https://github.com/lambdaclass/cairo_native#8faf10fb65fbb9ace5fc45ca5f72000470c09bac" dependencies = [ "anyhow", "aquamarine", @@ -1732,19 +1737,19 @@ dependencies = [ "thiserror", "tracing", "tracing-subscriber", + "utf8_iter", ] [[package]] name = "cairo-native-runtime" version = "0.2.0" -source = "git+https://github.com/lambdaclass/cairo_native#2be717cba74c63628cb68b619ff2022c70d0cdd2" +source = "git+https://github.com/lambdaclass/cairo_native#8faf10fb65fbb9ace5fc45ca5f72000470c09bac" dependencies = [ "cairo-lang-sierra-gas", "lazy_static", "libc", "rand 0.8.5", - "starknet-crypto 0.7.1", - "starknet-curve 0.5.0", + "starknet-curve 0.5.1", "starknet-types-core", ] @@ -1835,9 +1840,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.15" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "jobserver", "libc", @@ -1955,9 +1960,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -1965,9 +1970,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -1984,7 +1989,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2079,7 +2084,7 @@ dependencies = [ "derive_more", "ethnum", "futures", - "indexmap 2.4.0", + "indexmap 2.5.0", "pretty_assertions", "rand 0.8.5", "rand_distr", @@ -2164,18 +2169,18 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" dependencies = [ "proc-macro2", "quote", @@ -2258,9 +2263,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -2416,7 +2421,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2464,7 +2469,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2486,14 +2491,14 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] name = "dashmap" -version = "6.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", "crossbeam-utils", @@ -2592,33 +2597,33 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" +checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" +checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] name = "derive_builder_macro" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" +checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" dependencies = [ "derive_builder_core", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2631,7 +2636,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2726,7 +2731,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2807,7 +2812,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2886,14 +2891,14 @@ checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" [[package]] name = "enum-as-inner" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2924,7 +2929,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2944,7 +2949,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3120,7 +3125,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.76", + "syn 2.0.77", "toml", "walkdir", ] @@ -3138,7 +3143,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3164,7 +3169,7 @@ dependencies = [ "serde", "serde_json", "strum 0.26.3", - "syn 2.0.76", + "syn 2.0.77", "tempfile", "thiserror", "tiny-keccak", @@ -3299,7 +3304,7 @@ dependencies = [ "tokio", "tracing", "walkdir", - "yansi", + "yansi 0.5.1", ] [[package]] @@ -3399,9 +3404,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -3434,7 +3439,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", - "miniz_oxide 0.8.0", + "miniz_oxide", ] [[package]] @@ -3622,7 +3627,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3632,7 +3637,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.12", + "rustls 0.23.13", "rustls-pki-types", ] @@ -3665,7 +3670,7 @@ version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ - "gloo-timers", + "gloo-timers 0.2.6", "send_wrapper 0.4.0", ] @@ -3715,7 +3720,7 @@ checksum = "553630feadf7b76442b0849fd25fdf89b860d933623aec9693fed19af0400c78" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3754,9 +3759,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" @@ -3766,9 +3771,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick", "bstr", @@ -3810,6 +3815,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "gloo-utils" version = "0.2.0" @@ -3908,7 +3925,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -3927,7 +3944,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -4258,9 +4275,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" dependencies = [ "bytes", "futures-util", @@ -4273,9 +4290,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -4404,9 +4421,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ "crossbeam-deque", "globset", @@ -4500,9 +4517,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -4532,9 +4549,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.39.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5" +checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" dependencies = [ "console", "lazy_static", @@ -4583,9 +4600,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "is-terminal" @@ -4711,7 +4728,7 @@ dependencies = [ "tokio-util", "tracing", "url", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] @@ -5322,7 +5339,7 @@ dependencies = [ "quinn", "rand 0.8.5", "ring 0.17.8", - "rustls 0.23.12", + "rustls 0.23.13", "socket2 0.5.7", "thiserror", "tokio", @@ -5363,7 +5380,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5415,7 +5432,7 @@ dependencies = [ "libp2p-identity", "rcgen", "ring 0.17.8", - "rustls 0.23.12", + "rustls 0.23.13", "rustls-webpki 0.101.7", "thiserror", "x509-parser", @@ -5504,9 +5521,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "llvm-sys" -version = "181.1.1" +version = "181.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d255b36907416971229095a8465c0b69f5f1c6fb8421b6dcdbb64eb47e1be90" +checksum = "d320f9d2723c97d4b78f9190a61ed25cc7cfbe456668c08e6e7dd8e50ceb8500" dependencies = [ "anyhow", "cc", @@ -5643,7 +5660,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.76", + "syn 2.0.77", "tblgen-alt", "unindent 0.2.3", ] @@ -5729,7 +5746,7 @@ checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5784,15 +5801,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.8.0" @@ -5847,7 +5855,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5987,7 +5995,7 @@ dependencies = [ "cached", "cairo-lang-starknet-classes", "cairo-vm", - "indexmap 2.4.0", + "indexmap 2.5.0", "log", "num-bigint 0.4.6", "papyrus_storage", @@ -6127,6 +6135,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -6347,7 +6364,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6361,9 +6378,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -6443,7 +6460,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6531,18 +6548,6 @@ dependencies = [ "url", ] -[[package]] -name = "papyrus_block_builder" -version = "0.0.0" -dependencies = [ - "papyrus_storage", - "papyrus_test_utils", - "pretty_assertions", - "starknet_api", - "thiserror", - "tracing", -] - [[package]] name = "papyrus_common" version = "0.0.0" @@ -6550,8 +6555,7 @@ dependencies = [ "assert_matches", "cairo-lang-starknet-classes", "hex", - "indexmap 2.4.0", - "itertools 0.10.5", + "indexmap 2.5.0", "lazy_static", "papyrus_test_utils", "pretty_assertions", @@ -6561,7 +6565,6 @@ dependencies = [ "sha3", "starknet-types-core", "starknet_api", - "thiserror", ] [[package]] @@ -6570,7 +6573,7 @@ version = "0.0.0" dependencies = [ "assert_matches", "clap", - "itertools 0.10.5", + "itertools 0.12.1", "lazy_static", "papyrus_test_utils", "serde", @@ -6586,6 +6589,8 @@ name = "papyrus_consensus" version = "0.0.0" dependencies = [ "async-trait", + "clap", + "fs2", "futures", "lazy_static", "lru", @@ -6606,6 +6611,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "papyrus_consensus_orchestrator" +version = "0.0.0" +dependencies = [ + "async-trait", + "futures", + "mockall", + "papyrus_consensus", + "papyrus_network", + "papyrus_protobuf", + "papyrus_storage", + "papyrus_test_utils", + "starknet_api", + "test-case", + "tokio", + "tracing", +] + [[package]] name = "papyrus_execution" version = "0.0.0" @@ -6617,8 +6640,8 @@ dependencies = [ "cairo-lang-starknet-classes", "cairo-lang-utils", "cairo-vm", - "indexmap 2.4.0", - "itertools 0.10.5", + "indexmap 2.5.0", + "itertools 0.12.1", "lazy_static", "papyrus_common", "papyrus_config", @@ -6682,6 +6705,7 @@ version = "0.0.0" dependencies = [ "assert_matches", "async-stream", + "async-trait", "bytes", "deadqueue", "defaultmap", @@ -6720,7 +6744,7 @@ dependencies = [ "futures", "futures-util", "insta", - "itertools 0.10.5", + "itertools 0.12.1", "lazy_static", "metrics-exporter-prometheus", "once_cell", @@ -6728,6 +6752,7 @@ dependencies = [ "papyrus_common", "papyrus_config", "papyrus_consensus", + "papyrus_consensus_orchestrator", "papyrus_monitoring_gateway", "papyrus_network", "papyrus_p2p_sync", @@ -6759,7 +6784,7 @@ dependencies = [ "chrono", "enum-iterator", "futures", - "indexmap 2.4.0", + "indexmap 2.5.0", "lazy_static", "metrics 0.21.1", "papyrus_common", @@ -6791,7 +6816,7 @@ dependencies = [ "papyrus_test_utils", "prometheus-parse", "quote", - "syn 2.0.76", + "syn 2.0.77", "tracing", ] @@ -6799,13 +6824,15 @@ dependencies = [ name = "papyrus_protobuf" version = "0.0.0" dependencies = [ - "indexmap 2.4.0", + "futures", + "indexmap 2.5.0", "lazy_static", "papyrus_common", "papyrus_test_utils", "primitive-types", "prost", "prost-build", + "protoc-prebuilt", "rand 0.8.5", "rand_chacha 0.3.1", "starknet-types-core", @@ -6831,9 +6858,9 @@ dependencies = [ "futures-util", "hex", "hyper 0.14.30", - "indexmap 2.4.0", + "indexmap 2.5.0", "insta", - "itertools 0.10.5", + "itertools 0.12.1", "jsonrpsee", "jsonschema", "lazy_static", @@ -6878,7 +6905,7 @@ dependencies = [ "camelpaste", "clap", "human_bytes", - "indexmap 2.4.0", + "indexmap 2.5.0", "insta", "integer-encoding", "lazy_static", @@ -6928,8 +6955,8 @@ dependencies = [ "chrono", "futures", "futures-util", - "indexmap 2.4.0", - "itertools 0.10.5", + "indexmap 2.5.0", + "itertools 0.12.1", "lru", "metrics 0.21.1", "mockall", @@ -6959,7 +6986,7 @@ dependencies = [ "cairo-lang-casm", "cairo-lang-starknet-classes", "cairo-lang-utils", - "indexmap 2.4.0", + "indexmap 2.5.0", "num-bigint 0.4.6", "pretty_assertions", "primitive-types", @@ -7001,9 +7028,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -7126,7 +7153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.4.0", + "indexmap 2.5.0", ] [[package]] @@ -7169,7 +7196,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7213,7 +7240,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7228,6 +7255,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "ping" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6370a87a1a5bacec2eb80fa24ff3b7f47a1d47404a96611230d3b0d2e0f51141" +dependencies = [ + "rand 0.8.5", + "socket2 0.4.10", + "thiserror", +] + [[package]] name = "piper" version = "0.2.4" @@ -7257,9 +7295,9 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits 0.2.19", "plotters-backend", @@ -7270,15 +7308,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] @@ -7309,7 +7347,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.34", + "rustix 0.38.37", "tracing", "windows-sys 0.59.0", ] @@ -7392,12 +7430,12 @@ dependencies = [ [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", - "yansi", + "yansi 1.0.1", ] [[package]] @@ -7407,7 +7445,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7449,7 +7487,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.22.20", + "toml_edit 0.22.21", ] [[package]] @@ -7495,7 +7533,7 @@ dependencies = [ "hex", "lazy_static", "procfs-core", - "rustix 0.38.34", + "rustix 0.38.37", ] [[package]] @@ -7528,7 +7566,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7586,7 +7624,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.76", + "syn 2.0.77", "tempfile", ] @@ -7600,7 +7638,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7612,6 +7650,16 @@ dependencies = [ "prost", ] +[[package]] +name = "protoc-prebuilt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d85d4641fe3b8c6e853dfd09fe35379bc6b6e66bd692ac29ed4f7087de69ed5" +dependencies = [ + "ureq", + "zip", +] + [[package]] name = "psl-types" version = "2.0.11" @@ -7760,9 +7808,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" dependencies = [ "bytes", "futures-io", @@ -7770,7 +7818,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.0.0", - "rustls 0.23.12", + "rustls 0.23.13", "socket2 0.5.7", "thiserror", "tokio", @@ -7779,15 +7827,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" dependencies = [ "bytes", "rand 0.8.5", "ring 0.17.8", "rustc-hash 2.0.0", - "rustls 0.23.12", + "rustls 0.23.13", "slab", "thiserror", "tinyvec", @@ -7796,15 +7844,15 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" dependencies = [ "libc", "once_cell", "socket2 0.5.7", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -8035,9 +8083,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ "bitflags 2.6.0", ] @@ -8159,7 +8207,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.25.4", "winreg", ] @@ -8224,9 +8272,9 @@ dependencies = [ [[package]] name = "rlimit" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3560f70f30a0f16d11d01ed078a07740fe6b489667abc7c7b029155d9f21c3d8" +checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" dependencies = [ "libc", ] @@ -8307,7 +8355,7 @@ version = "0.17.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719825638c59fd26a55412a24561c7c5bcf54364c88b9a7a04ba08a6eafaba8d" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "lock_api", "oorandom", "parking_lot", @@ -8327,7 +8375,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8366,9 +8414,9 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -8398,9 +8446,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -8423,14 +8471,15 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ + "log", "once_cell", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.6", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] @@ -8474,9 +8523,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -8550,11 +8599,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -8579,7 +8628,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8670,22 +8719,22 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8696,14 +8745,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -8740,7 +8789,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8788,7 +8837,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -8872,8 +8921,8 @@ dependencies = [ "serde_json", "sha2", "smallvec", - "starknet-crypto 0.7.1", - "starknet-curve 0.5.0", + "starknet-crypto 0.7.2", + "starknet-curve 0.5.1", "starknet-types-core", "thiserror", "tracing", @@ -9130,26 +9179,6 @@ dependencies = [ "starknet-ff", ] -[[package]] -name = "starknet-crypto" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f2175b0b3fc24ff2ec6dc07f5a720498994effca7e78b11a6e1c1bd02cad52" -dependencies = [ - "crypto-bigint", - "hex", - "hmac", - "num-bigint 0.4.6", - "num-integer", - "num-traits 0.2.19", - "rfc6979", - "sha2", - "starknet-crypto-codegen 0.3.3", - "starknet-curve 0.3.0", - "starknet-ff", - "zeroize", -] - [[package]] name = "starknet-crypto" version = "0.6.2" @@ -9164,7 +9193,7 @@ dependencies = [ "num-traits 0.2.19", "rfc6979", "sha2", - "starknet-crypto-codegen 0.3.3", + "starknet-crypto-codegen", "starknet-curve 0.4.2", "starknet-ff", "zeroize", @@ -9172,9 +9201,9 @@ dependencies = [ [[package]] name = "starknet-crypto" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2a821ad8d98c6c3e4d0e5097f3fe6e2ed120ada9d32be87cd1330c7923a2f0" +checksum = "60a5064173a8e8d2675e67744fd07f310de44573924b6b7af225a6bdd8102913" dependencies = [ "crypto-bigint", "hex", @@ -9184,8 +9213,7 @@ dependencies = [ "num-traits 0.2.19", "rfc6979", "sha2", - "starknet-crypto-codegen 0.4.0", - "starknet-curve 0.5.0", + "starknet-curve 0.5.1", "starknet-types-core", "zeroize", ] @@ -9198,27 +9226,7 @@ checksum = "bbc159a1934c7be9761c237333a57febe060ace2bc9e3b337a59a37af206d19f" dependencies = [ "starknet-curve 0.4.2", "starknet-ff", - "syn 2.0.76", -] - -[[package]] -name = "starknet-crypto-codegen" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e179dedc3fa6da064e56811d3e05d446aa2f7459e4eb0e3e49378a337235437" -dependencies = [ - "starknet-curve 0.5.0", - "starknet-types-core", - "syn 2.0.76", -] - -[[package]] -name = "starknet-curve" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252610baff59e4c4332ce3569f7469c5d3f9b415a2240d698fb238b2b4fc0942" -dependencies = [ - "starknet-ff", + "syn 2.0.77", ] [[package]] @@ -9232,9 +9240,9 @@ dependencies = [ [[package]] name = "starknet-curve" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56935b306dcf0b8f14bb2a1257164b8478bb8be4801dfae0923f5b266d1b457c" +checksum = "bcde6bd74269b8161948190ace6cf069ef20ac6e79cd2ba09b320efa7500b6de" dependencies = [ "starknet-types-core", ] @@ -9277,17 +9285,17 @@ dependencies = [ "cairo-lang-starknet-classes", "derive_more", "hex", - "indexmap 2.4.0", + "indexmap 2.5.0", "itertools 0.12.1", "primitive-types", "rstest", "serde", "serde_json", "sha3", - "starknet-crypto 0.5.2", + "starknet-crypto 0.7.2", "starknet-types-core", - "strum 0.24.1", - "strum_macros 0.24.3", + "strum 0.25.0", + "strum_macros 0.25.3", "thiserror", ] @@ -9306,6 +9314,7 @@ dependencies = [ "starknet_mempool_types", "thiserror", "tokio", + "tokio-stream", "tracing", "validator", ] @@ -9331,7 +9340,7 @@ dependencies = [ "cairo-lang-starknet-classes", "enum-iterator", "http 0.2.12", - "indexmap 2.4.0", + "indexmap 2.5.0", "mockall", "mockito 0.31.1", "os_info", @@ -9434,6 +9443,14 @@ dependencies = [ "validator", ] +[[package]] +name = "starknet_gateway_types" +version = "0.0.0" + +[[package]] +name = "starknet_http_server" +version = "0.0.0" + [[package]] name = "starknet_mempool" version = "0.0.0" @@ -9441,7 +9458,7 @@ dependencies = [ "assert_matches", "async-trait", "derive_more", - "itertools 0.10.5", + "itertools 0.12.1", "mempool_test_utils", "pretty_assertions", "rstest", @@ -9478,8 +9495,8 @@ dependencies = [ "axum", "blockifier", "cairo-lang-starknet-classes", - "indexmap 2.4.0", - "itertools 0.10.5", + "indexmap 2.5.0", + "itertools 0.12.1", "mempool_test_utils", "papyrus_common", "papyrus_rpc", @@ -9532,6 +9549,19 @@ dependencies = [ "validator", ] +[[package]] +name = "starknet_mempool_p2p" +version = "0.0.0" +dependencies = [ + "async-trait", + "papyrus_network", + "papyrus_proc_macros", + "serde", + "starknet_api", + "starknet_mempool_infra", + "thiserror", +] + [[package]] name = "starknet_mempool_types" version = "0.0.0" @@ -9581,6 +9611,7 @@ dependencies = [ "serde_json", "starknet-types-core", "starknet_api", + "tempfile", "thiserror", "validator", ] @@ -9642,12 +9673,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" - [[package]] name = "strum" version = "0.25.0" @@ -9663,19 +9688,6 @@ dependencies = [ "strum_macros 0.26.4", ] -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", -] - [[package]] name = "strum_macros" version = "0.25.3" @@ -9686,7 +9698,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -9699,7 +9711,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -9741,9 +9753,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.76" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -9764,7 +9776,22 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", +] + +[[package]] +name = "sysinfo" +version = "0.29.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "winapi", ] [[package]] @@ -9832,7 +9859,7 @@ dependencies = [ "cfg-if", "fastrand 2.1.1", "once_cell", - "rustix 0.38.34", + "rustix 0.38.37", "windows-sys 0.59.0", ] @@ -9880,7 +9907,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -9891,7 +9918,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "test-case-core", ] @@ -9914,7 +9941,7 @@ checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -9923,11 +9950,17 @@ version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3e3e1275a1442b99772321d4a35e0622f7abc04f6af49bd801c7119645bc9e" dependencies = [ + "byte-unit", + "num_cpus", + "ping", "proc-macro-error", "proc-macro2", "quote", "regex", - "syn 2.0.76", + "reqwest", + "syn 2.0.77", + "sysinfo", + "users", "which", ] @@ -9948,7 +9981,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -10070,9 +10103,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -10094,7 +10127,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -10130,9 +10163,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -10164,14 +10197,14 @@ dependencies = [ "tokio", "tokio-rustls", "tungstenite", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -10190,7 +10223,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.20", + "toml_edit 0.22.21", ] [[package]] @@ -10208,18 +10241,18 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "toml_datetime", "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", @@ -10279,7 +10312,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -10362,7 +10395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -10448,24 +10481,24 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-xid" @@ -10529,6 +10562,21 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" +dependencies = [ + "base64 0.22.1", + "log", + "once_cell", + "rustls 0.23.13", + "rustls-pki-types", + "url", + "webpki-roots 0.26.6", +] + [[package]] name = "url" version = "2.5.2" @@ -10540,12 +10588,34 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "users" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" +dependencies = [ + "libc", + "log", +] + [[package]] name = "utf-8" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -10690,7 +10760,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -10724,7 +10794,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -10761,6 +10831,15 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "webpki-roots" +version = "0.26.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "which" version = "4.4.2" @@ -10770,7 +10849,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.34", + "rustix 0.38.37", ] [[package]] @@ -11116,14 +11195,14 @@ checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", "linux-raw-sys 0.4.14", - "rustix 0.38.34", + "rustix 0.38.37", ] [[package]] name = "xml-rs" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" +checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" [[package]] name = "xmltree" @@ -11186,6 +11265,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yasna" version = "0.5.2" @@ -11213,7 +11298,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -11233,7 +11318,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fbbf60b7fd..d8d96e51ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,12 @@ members = [ "crates/consensus_manager", "crates/consensus_manager_types", "crates/gateway", + "crates/gateway_types", + "crates/http_server", "crates/mempool", "crates/mempool_infra", "crates/mempool_node", + "crates/mempool_p2p", "crates/mempool_test_utils", "crates/mempool_types", "crates/native_blockifier", @@ -32,8 +35,8 @@ members = [ "crates/papyrus_storage", "crates/papyrus_sync", "crates/papyrus_test_utils", - "crates/sequencing/papyrus_block_builder", "crates/sequencing/papyrus_consensus", + "crates/sequencing/papyrus_consensus_orchestrator", "crates/starknet_api", "crates/starknet_client", "crates/starknet_committer", @@ -96,20 +99,23 @@ derive_more = "0.99.17" enum-assoc = "1.1.0" enum-iterator = "1.4.1" ethers = "2.0.3" +ethers-core = "2.0.3" ethnum = "1.5.0" flate2 = "1.0.24" futures = "0.3.21" futures-channel = "0.3.21" futures-util = "0.3.21" glob = "0.3.1" +goose = "0.17.0" hex = "0.4.3" http = "0.2.8" +http-body = "0.4.5" human_bytes = "0.4.3" hyper = "0.14" indexmap = "2.1.0" insta = "1.29.0" integer-encoding = "3.0.4" -itertools = "0.10.5" +itertools = "0.12.1" jsonrpsee = "0.20.3" jsonschema = "0.17.0" keccak = "0.1.3" @@ -123,10 +129,12 @@ memmap2 = "0.8.0" mempool_test_utils = { path = "crates/mempool_test_utils", version = "0.0.0" } metrics = "0.21.0" metrics-exporter-prometheus = "0.12.1" +metrics-process = "1.0.11" mockall = "0.12.1" +mockito = "1.4.0" num-bigint = "0.4" num-integer = "0.1.45" -num-rational = { version = "0.4", features = ["serde"] } +num-rational = "0.4" num-traits = "0.2.15" once_cell = "1.19.0" os_info = "3.6.0" @@ -135,6 +143,7 @@ papyrus_base_layer = { path = "crates/papyrus_base_layer", version = "0.0.0" } papyrus_common = { path = "crates/papyrus_common", version = "0.0.0" } papyrus_config = { path = "crates/papyrus_config", version = "0.0.0" } papyrus_consensus = { path = "crates/sequencing/papyrus_consensus", version = "0.0.0" } +papyrus_consensus_orchestrator = { path = "crates/sequencing/papyrus_consensus_orchestrator", version = "0.0.0" } papyrus_execution = { path = "crates/papyrus_execution", version = "0.0.0" } papyrus_monitoring_gateway = { path = "crates/papyrus_monitoring_gateway", version = "0.0.0" } papyrus_network = { path = "crates/papyrus_network", version = "0.0.0" } @@ -148,21 +157,23 @@ papyrus_test_utils = { path = "crates/papyrus_test_utils", version = "0.0.0" } parity-scale-codec = "=3.6.9" parity-scale-codec-derive = "=3.6.9" paste = "1.0.15" -phf = { version = "0.11", features = ["macros"] } +phf = "0.11" pretty_assertions = "1.4.0" primitive-types = "0.12.1" prometheus-parse = "0.2.4" prost = "0.12.1" prost-build = "0.12.1" prost-types = "0.12.1" +protoc-prebuilt = "0.3.0" pyo3 = "0.19.1" pyo3-log = "0.8.1" +quote = "1.0.26" rand = "0.8.5" rand_chacha = "0.3.1" rand_distr = "0.4.3" regex = "1.10.4" replace_with = "0.1.7" -reqwest = { version = "0.11", features = ["blocking", "json"] } +reqwest = "0.11" rstest = "0.17.0" rustc-hex = "2.1.0" schemars = "0.8.12" @@ -174,8 +185,8 @@ sha2 = "0.10.8" sha3 = "0.10.8" simple_logger = "4.0.0" starknet-core = "0.6.0" -starknet-crypto = "0.5.1" -starknet-types-core = { version = "0.1.5", features = ["hash", "prime-bigint", "std"] } +starknet-crypto = "0.7.1" +starknet-types-core = "0.1.5" starknet_api = { path = "crates/starknet_api", version = "0.0.0" } starknet_batcher = { path = "crates/batcher", version = "0.0.0" } starknet_batcher_types = { path = "crates/batcher_types", version = "0.0.0" } @@ -195,12 +206,15 @@ static_assertions = "1.1.0" statistical = "1.0.0" strum = "0.25.0" strum_macros = "0.25.2" +syn = "2.0.39" +tar = "0.4.38" tempfile = "3.7.0" test-case = "3.2.1" test-log = "0.2.14" +test-with = "0.9.3" thiserror = "1.0.37" tikv-jemallocator = "0.5.4" -tokio = { version = "1.37.0", features = ["full"] } +tokio = "1.37.0" tokio-retry = "0.3" tokio-stream = "0.1.8" tokio-test = "0.4.4" diff --git a/Dockerfile b/Dockerfile index c362597fc2..9e82860e0a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,22 +7,51 @@ # More info on Cargo Chef: https://github.com/LukeMathWalker/cargo-chef # We start by creating a base image using 'clux/muslrust' with additional required tools. -FROM clux/muslrust:1.80.0-stable AS chef +FROM ubuntu:22.04 AS base WORKDIR /app -RUN apt update && apt install -y clang unzip + +RUN apt update -y && apt install -y lsb-release \ + wget \ + curl \ + git \ + build-essential \ + libclang-dev \ + libz-dev \ + libzstd-dev \ + libssl-dev \ + pkg-config \ + gnupg \ + unzip + +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain stable -y +ENV PATH="/root/.cargo/bin:${PATH}" + RUN cargo install cargo-chef + ENV PROTOC_VERSION=25.1 RUN curl -L "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOC_VERSION/protoc-$PROTOC_VERSION-linux-x86_64.zip" -o protoc.zip && unzip ./protoc.zip -d $HOME/.local && rm ./protoc.zip ENV PROTOC=/root/.local/bin/protoc -# Add the x86_64-unknown-linux-musl target to rustup for compiling statically linked binaries. -# This enables the creation of fully self-contained binaries that do not depend on the system's dynamic libraries, -# resulting in more portable executables that can run on any Linux distribution. -RUN rustup target add x86_64-unknown-linux-musl + +# Install LLVM 18 +RUN echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" > /etc/apt/sources.list.d/llvm-18.list +RUN echo "deb-src http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" >> /etc/apt/sources.list.d/llvm-18.list +RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - + +RUN apt update -y && apt install -y --ignore-missing --allow-downgrades \ + libmlir-18-dev \ + libpolly-18-dev \ + llvm-18-dev \ + mlir-18-tools \ + clang-18 + +ENV MLIR_SYS_180_PREFIX=/usr/lib/llvm-18/ +ENV LLVM_SYS_181_PREFIX=/usr/lib/llvm-18/ +ENV TABLEGEN_180_PREFIX=/usr/lib/llvm-18/ ##################### # Stage 1 (planer): # ##################### -FROM chef AS planner +FROM base AS planner COPY . . # * Running Cargo Chef prepare that will generate recipe.json which will be used in the next stage. RUN cargo chef prepare @@ -31,43 +60,39 @@ RUN cargo chef prepare # Stage 2 (cacher): # ##################### # Compile all the dependecies using Cargo Chef cook. -FROM chef AS cacher +FROM base AS cacher # Copy recipe.json from planner stage COPY --from=planner /app/recipe.json recipe.json # Build dependencies - this is the caching Docker layer! -RUN cargo chef cook --target x86_64-unknown-linux-musl --release --package papyrus_node +RUN cargo chef cook --release --package papyrus_node ###################### # Stage 3 (builder): # ###################### -FROM chef AS builder +FROM base AS builder COPY . . COPY --from=cacher /app/target target # Disable incremental compilation for a cleaner build. ENV CARGO_INCREMENTAL=0 # Compile the papyrus_node crate for the x86_64-unknown-linux-musl target in release mode, ensuring dependencies are locked. -RUN cargo build --target x86_64-unknown-linux-musl --release --package papyrus_node --locked +RUN cargo build --release --package papyrus_node --locked ########################### # Stage 4 (papyrus_node): # ########################### -# Uses Alpine Linux to run a lightweight and secure container. -FROM alpine:3.17.0 AS papyrus_node +FROM base AS papyrus_node ENV ID=1000 WORKDIR /app # Copy the node executable and its configuration. -COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/papyrus_node /app/target/release/papyrus_node +COPY --from=builder /app/target/release/papyrus_node /app/target/release/papyrus_node COPY config config # Install tini, a lightweight init system, to call our executable. -RUN set -ex; \ - apk update; \ - apk add --no-cache tini; \ - mkdir data +RUN apt install tini # Create a new user "papyrus". RUN set -ex; \ @@ -82,4 +107,4 @@ EXPOSE 8080 8081 USER ${ID} # Set the entrypoint to use tini to manage the process. -ENTRYPOINT ["/sbin/tini", "--", "/app/target/release/papyrus_node"] +ENTRYPOINT ["tini", "--", "/app/target/release/papyrus_node"] \ No newline at end of file diff --git a/commitlint.config.js b/commitlint.config.js index 21ea8d63b7..d590eb9651 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -21,7 +21,6 @@ const Configuration = { 'scope-enum': [2, 'always', [ 'base_layer', 'batcher', - 'block_builder', 'block_hash', 'blockifier', 'ci', diff --git a/config/papyrus/default_config.json b/config/papyrus/default_config.json index 947af95b60..7d1b69f099 100644 --- a/config/papyrus/default_config.json +++ b/config/papyrus/default_config.json @@ -179,6 +179,16 @@ "privacy": "TemporaryValue", "value": true }, + "network.advertised_multiaddr": { + "description": "The external address other peers see this node. If this is set, the node will not try to find out which addresses it has and will write this address as external instead", + "privacy": "Public", + "value": "" + }, + "network.advertised_multiaddr.#is_none": { + "description": "Flag for an optional field.", + "privacy": "TemporaryValue", + "value": true + }, "network.bootstrap_peer_multiaddr": { "description": "The multiaddress of the peer node. It should include the peer's id. For more info: https://docs.libp2p.io/concepts/fundamentals/peers/", "privacy": "Public", @@ -194,16 +204,6 @@ "pointer_target": "chain_id", "privacy": "Public" }, - "network.hardcoded_external_multiaddr": { - "description": "The external address other peers see this node. If this is set, the node will not try to find out which addresses it has and will write this address as external instead", - "privacy": "Public", - "value": "" - }, - "network.hardcoded_external_multiaddr.#is_none": { - "description": "Flag for an optional field.", - "privacy": "TemporaryValue", - "value": true - }, "network.idle_connection_timeout": { "description": "Amount of time in seconds that a connection with no active sessions will stay alive.", "privacy": "Public", diff --git a/crates/batcher/Cargo.toml b/crates/batcher/Cargo.toml index a735b2908d..933ebc7eb4 100644 --- a/crates/batcher/Cargo.toml +++ b/crates/batcher/Cargo.toml @@ -18,6 +18,7 @@ starknet_mempool_infra.workspace = true starknet_mempool_types.workspace = true thiserror.workspace = true tokio.workspace = true +tokio-stream.workspace = true tracing.workspace = true validator.workspace = true diff --git a/crates/batcher/src/fee_market.rs b/crates/batcher/src/fee_market.rs new file mode 100644 index 0000000000..71cba26a49 --- /dev/null +++ b/crates/batcher/src/fee_market.rs @@ -0,0 +1,74 @@ +use std::cmp::max; + +#[cfg(test)] +#[path = "fee_market_test.rs"] +pub mod fee_market_test; + +// This constant is used to calculate the base gas price for the next block according to EIP-1559 +// and serves as a sensitivity parameter that limits the maximum rate of change of the gas price +// between consecutive blocks. +const GAS_PRICE_MAX_CHANGE_DENOMINATOR: u128 = 48; +const MIN_GAS_PRICE: u64 = 100000; // In fri. +// TODO(Mohammad): Check the exact value for maximum block size in StarkNet. +const MAX_BLOCK_SIZE: u64 = 4000000000; // In gas units. It's equivalent to 40M gas steps, with 100 gas units per step. + +/// Calculate the base gas price for the next block according to EIP-1559. +/// +/// # Parameters +/// - `price`: The base fee of the current block. +/// - `gas_used`: The total gas used in the current block. +/// - `gas_target`: The target gas usage per block (usually half of the gas limit). +pub fn calculate_next_base_gas_price(price: u64, gas_used: u64, gas_target: u64) -> u64 { + // Setting the target at 50% of the max block size balances the rate of gas price changes, + // helping to prevent sudden spikes, particularly during increases, for a better user + // experience. + assert_eq!( + gas_target, + MAX_BLOCK_SIZE / 2, + "Gas target must be 50% of max block size to balance price changes." + ); + // To prevent precision loss during multiplication and division, we set a minimum gas price. + // Additionally, a minimum gas price is established to prevent prolonged periods before the + // price reaches a higher value. + assert!( + price >= MIN_GAS_PRICE, + "The gas price must be at least the minimum to prevent precision loss during \ + multiplication and division." + ); + + // We use unsigned integers (u64 and u128) to avoid overflow issues, as the input values are + // naturally unsigned and i256 is unstable in Rust. This approach allows safe handling of + // all inputs using u128 for intermediate calculations. + + // The absolute difference between gas_used and gas_target is always u64. + let gas_delta = gas_used.abs_diff(gas_target); + // Convert to u128 to prevent overflow, as a product of two u64 fits inside a u128. + let price_u128 = u128::from(price); + let gas_delta_u128 = u128::from(gas_delta); + let gas_target_u128 = u128::from(gas_target); + + // Calculate the gas change as u128 to handle potential overflow during multiplication. + let gas_delta_cost = + price_u128.checked_mul(gas_delta_u128).expect("Both variables originate from u64"); + // Calculate the price change, maintaining precision by dividing after scaling up. + // This avoids significant precision loss that would occur if dividing before + // multiplication. + let price_change_u128 = gas_delta_cost / gas_target_u128 / GAS_PRICE_MAX_CHANGE_DENOMINATOR; + + // Convert back to u64, as the price change should fit within the u64 range. + // Since the target is half the maximum block size (which fits within a u64), the gas delta + // is bounded by half the maximum block size. Therefore, after dividing by the gas target + // (which is half the maximum block size), the result is guaranteed to fit within a u64. + let price_change = u64::try_from(price_change_u128) + .expect("Result fits u64 after division of a bounded gas delta"); + + let adjusted_price = + if gas_used > gas_target { price + price_change } else { price - price_change }; + + assert!( + gas_used > gas_target && adjusted_price >= price + || gas_used <= gas_target && adjusted_price <= price + ); + + max(adjusted_price, MIN_GAS_PRICE) +} diff --git a/crates/batcher/src/fee_market_test.rs b/crates/batcher/src/fee_market_test.rs new file mode 100644 index 0000000000..88e4ecebe9 --- /dev/null +++ b/crates/batcher/src/fee_market_test.rs @@ -0,0 +1,62 @@ +use crate::fee_market::{ + calculate_next_base_gas_price, + GAS_PRICE_MAX_CHANGE_DENOMINATOR, + MAX_BLOCK_SIZE, + MIN_GAS_PRICE, +}; + +#[test] +fn test_price_calculation_snapshot() { + // Setup: using realistic arbitrary values. + const INIT_PRICE: u64 = 1_000_000; + const GAS_TARGET: u64 = MAX_BLOCK_SIZE / 2; + const HIGH_CONGESTION_GAS_USED: u64 = MAX_BLOCK_SIZE * 3 / 4; + const LOW_CONGESTION_GAS_USED: u64 = MAX_BLOCK_SIZE / 4; + const STABLE_CONGESTION_GAS_USED: u64 = GAS_TARGET; + + // Fixed expected output values. + let increased_price = 1000000 + 10416; // 1000000 + (1000000 * 1 / 4 * MAX_BLOCK_SIZE) / (0.5 * MAX_BLOCK_SIZE * 48); + let decreased_price = 1000000 - 10416; // 1000000 - (1000000 * 1 / 4 * MAX_BLOCK_SIZE) / (0.5 * MAX_BLOCK_SIZE * 48); + + // Assert. + assert_eq!( + calculate_next_base_gas_price(INIT_PRICE, HIGH_CONGESTION_GAS_USED, GAS_TARGET), + increased_price + ); + assert_eq!( + calculate_next_base_gas_price(INIT_PRICE, LOW_CONGESTION_GAS_USED, GAS_TARGET), + decreased_price + ); + assert_eq!( + calculate_next_base_gas_price(INIT_PRICE, STABLE_CONGESTION_GAS_USED, GAS_TARGET), + INIT_PRICE + ); +} + +#[test] +// This test ensures that the gas price calculation does not overflow with extreme values, +fn test_gas_price_with_extreme_values() { + let price = MIN_GAS_PRICE; + let gas_target = MAX_BLOCK_SIZE / 2; + let gas_used = 0; + assert_eq!(calculate_next_base_gas_price(price, gas_used, gas_target), MIN_GAS_PRICE); + + let price = MIN_GAS_PRICE; + let gas_target = MAX_BLOCK_SIZE / 2; + let gas_used = MAX_BLOCK_SIZE; + assert!(calculate_next_base_gas_price(price, gas_used, gas_target) > MIN_GAS_PRICE); + + let price = u64::MAX; + let gas_target = MAX_BLOCK_SIZE / 2; + let gas_used = 0; + calculate_next_base_gas_price(price, gas_used, gas_target); // Should not panic. + + // To avoid overflow when updating the price, the value is set below a certain threshold so that + // the new price does not exceed u64::MAX. + let max_u128 = u128::from(u64::MAX); + let price_u128 = + max_u128 * GAS_PRICE_MAX_CHANGE_DENOMINATOR / (GAS_PRICE_MAX_CHANGE_DENOMINATOR + 1); + let gas_target = MAX_BLOCK_SIZE / 2; + let gas_used = MAX_BLOCK_SIZE; + calculate_next_base_gas_price(u64::try_from(price_u128).unwrap(), gas_used, gas_target); // Should not panic. +} diff --git a/crates/batcher/src/lib.rs b/crates/batcher/src/lib.rs index 5e5c03af26..5055c49d42 100644 --- a/crates/batcher/src/lib.rs +++ b/crates/batcher/src/lib.rs @@ -1,6 +1,7 @@ pub mod batcher; pub mod communication; pub mod config; +pub mod fee_market; pub mod proposals_manager; #[cfg(test)] mod proposals_manager_test; diff --git a/crates/batcher/src/proposals_manager.rs b/crates/batcher/src/proposals_manager.rs index 6198ab959a..c24a2a1f3d 100644 --- a/crates/batcher/src/proposals_manager.rs +++ b/crates/batcher/src/proposals_manager.rs @@ -5,9 +5,11 @@ use papyrus_config::dumping::{ser_param, SerializeConfig}; use papyrus_config::{ParamPath, ParamPrivacyInput, SerializedParam}; use serde::{Deserialize, Serialize}; use starknet_api::block::BlockNumber; +use starknet_api::executable_transaction::Transaction; use starknet_mempool_types::communication::{MempoolClientError, SharedMempoolClient}; use thiserror::Error; use tokio::sync::Mutex; +use tokio_stream::wrappers::ReceiverStream; use tracing::{debug, error, info, instrument}; // TODO: Should be defined in SN_API probably (shared with the consensus). @@ -16,23 +18,32 @@ pub type ProposalId = u64; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ProposalsManagerConfig { pub max_txs_per_mempool_request: usize, + pub outstream_content_buffer_size: usize, } impl Default for ProposalsManagerConfig { fn default() -> Self { // TODO: Get correct value for default max_txs_per_mempool_request. - Self { max_txs_per_mempool_request: 10 } + Self { max_txs_per_mempool_request: 10, outstream_content_buffer_size: 100 } } } impl SerializeConfig for ProposalsManagerConfig { fn dump(&self) -> BTreeMap { - BTreeMap::from_iter([ser_param( - "max_txs_per_mempool_request", - &self.max_txs_per_mempool_request, - "Maximum transactions to get from the mempool per iteration of proposal generation", - ParamPrivacyInput::Public, - )]) + BTreeMap::from_iter([ + ser_param( + "max_txs_per_mempool_request", + &self.max_txs_per_mempool_request, + "Maximum transactions to get from the mempool per iteration of proposal generation", + ParamPrivacyInput::Public, + ), + ser_param( + "outstream_content_buffer_size", + &self.outstream_content_buffer_size, + "Maximum items to add to the outstream buffer before blocking", + ParamPrivacyInput::Public, + ), + ]) } } @@ -46,6 +57,8 @@ pub enum ProposalsManagerError { current_generating_proposal_id: ProposalId, new_proposal_id: ProposalId, }, + #[error("Internal error.")] + InternalError, #[error(transparent)] MempoolError(#[from] MempoolClientError), } @@ -79,28 +92,31 @@ impl ProposalsManager { /// Starts a new block proposal generation task for the given proposal_id and height with /// transactions from the mempool. - #[instrument(skip(self), err)] + #[instrument(skip(self))] pub async fn generate_block_proposal( &mut self, proposal_id: ProposalId, timeout: tokio::time::Instant, _height: BlockNumber, - ) -> ProposalsManagerResult<()> { + ) -> ProposalsManagerResult> { info!("Starting generation of new proposal."); self.set_proposal_in_generation(proposal_id).await?; + let (sender, receiver) = + tokio::sync::mpsc::channel::(self.config.outstream_content_buffer_size); // TODO: Find where to join the task - needed to make sure it starts immediatly. let _handle = tokio::spawn( ProposalGenerationTask { timeout, mempool_client: self.mempool_client.clone(), max_txs_per_mempool_request: self.config.max_txs_per_mempool_request, + sender, proposal_in_generation: self.proposal_in_generation.clone(), } .run(), ); - Ok(()) + Ok(ReceiverStream::new(receiver)) } // Checks if there is already a proposal being generated, and if not, sets the given proposal_id @@ -145,7 +161,11 @@ mod block_builder { } /// Returning true if the block is ready to be proposed. - pub fn add_txs(&self, _txs: &[Transaction]) -> bool { + pub fn add_txs_and_stream( + &self, + _txs: &[Transaction], + _sender: &tokio::sync::mpsc::Sender, + ) -> bool { false } @@ -160,6 +180,7 @@ struct ProposalGenerationTask { pub timeout: tokio::time::Instant, pub mempool_client: SharedMempoolClient, pub max_txs_per_mempool_request: usize, + pub sender: tokio::sync::mpsc::Sender, pub proposal_in_generation: Arc>>, } @@ -183,7 +204,8 @@ impl ProposalGenerationTask { debug!("Adding {} mempool transactions to proposal in generation.", mempool_txs.len()); // TODO: This is cpu bound operation, should use spawn_blocking / Rayon / std::thread // here or from inside the function. - let is_block_ready = block_builder.add_txs(mempool_txs.as_slice()); + let is_block_ready = + block_builder.add_txs_and_stream(mempool_txs.as_slice(), &self.sender); if is_block_ready { break; } diff --git a/crates/batcher/src/proposals_manager_test.rs b/crates/batcher/src/proposals_manager_test.rs index 69a0ffc130..fd3933e3e5 100644 --- a/crates/batcher/src/proposals_manager_test.rs +++ b/crates/batcher/src/proposals_manager_test.rs @@ -14,7 +14,7 @@ async fn multiple_proposals_generation_fails() { mempool_client.expect_get_txs().returning(|_| Ok(vec![])); let mut proposals_manager = ProposalsManager::new(ProposalsManagerConfig::default(), Arc::new(mempool_client)); - proposals_manager + let _ = proposals_manager .generate_block_proposal( 0, tokio::time::Instant::now() + GENERATION_TIMEOUT, diff --git a/crates/blockifier/Cargo.toml b/crates/blockifier/Cargo.toml index 2bcd38b52a..62eeaf95ed 100644 --- a/crates/blockifier/Cargo.toml +++ b/crates/blockifier/Cargo.toml @@ -14,6 +14,7 @@ concurrency = [] jemalloc = ["dep:tikv-jemallocator"] testing = ["rand", "rstest"] use-sierra-emu = [] +transaction_serde = [] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -38,14 +39,15 @@ indexmap.workspace = true tracing.workspace = true itertools.workspace = true keccak.workspace = true +lazy_static.workspace = true log.workspace = true num-bigint.workspace = true num-integer.workspace = true -num-rational.workspace = true +num-rational = { workspace = true, features = ["serde"] } num-traits.workspace = true papyrus_config.workspace = true paste.workspace = true -phf.workspace = true +phf = { workspace = true, features = ["macros"] } rand = { workspace = true, optional = true } rstest = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"] } @@ -85,3 +87,8 @@ required-features = ["testing"] name = "erc20_tests" path = "tests/erc20_tests.rs" required-features = ["testing"] + +[[test]] +name = "test_native_contract" +path = "tests/test_native_contract.rs" +required-features = ["testing"] diff --git a/crates/blockifier/feature_contracts/cairo0/compiled/test_contract_compiled.json b/crates/blockifier/feature_contracts/cairo0/compiled/test_contract_compiled.json index a2fe7d15f7..8b97584afb 100644 --- a/crates/blockifier/feature_contracts/cairo0/compiled/test_contract_compiled.json +++ b/crates/blockifier/feature_contracts/cairo0/compiled/test_contract_compiled.json @@ -264,6 +264,21 @@ ], "type": "function" }, + { + "inputs": [ + { + "name": "contract_address", + "type": "felt" + }, + { + "name": "function_selector", + "type": "felt" + } + ], + "name": "test_call_contract_fail_with_attr_error_msg", + "outputs": [], + "type": "function" + }, { "inputs": [ { @@ -645,23 +660,23 @@ ], "EXTERNAL": [ { - "offset": 1238, + "offset": 1269, "selector": "0x1143aa89c8e3ebf8ed14df2a3606c1cd2dd513fac8040b0f8ab441f5c52fe4" }, { - "offset": 1280, + "offset": 1311, "selector": "0x600c98a299d72ef1e09a2e1503206fbc76081233172c65f7e2438ef0069d8d" }, { - "offset": 1154, + "offset": 1185, "selector": "0x62c83572d28cb834a3de3c1e94977a4191469a4a8c26d1d7bc55305e640ed5" }, { - "offset": 1794, + "offset": 1825, "selector": "0x679c22735055a10db4f275395763a3752a1e3a3043c192299ab6b574fba8d6" }, { - "offset": 1718, + "offset": 1749, "selector": "0x7772be8b80a8a33dc6c1f9a6ab820c02e537c73e859de67f288c70f92571bb" }, { @@ -669,11 +684,11 @@ "selector": "0xad451bd0dba3d8d97104e1bfc474f88605ccc7acbe1c846839a120fdf30d95" }, { - "offset": 1544, + "offset": 1575, "selector": "0xd47144c49bce05b6de6bce9d5ff0cc8da9420f8945453e20ef779cbea13ad4" }, { - "offset": 897, + "offset": 928, "selector": "0xe7510edcf6e9f1b70f7bd1f488767b50f0363422f3c563160ab77adf62467b" }, { @@ -685,11 +700,11 @@ "selector": "0x120c24672855cfe872cb35256ea85172417f2aada7a22c15908906dc5f3c69d" }, { - "offset": 1511, + "offset": 1542, "selector": "0x127a04cfe41aceb22fc022bce0c5c70f2d860a7c7c054681bd821cdc18e6dbc" }, { - "offset": 1871, + "offset": 1902, "selector": "0x12ead94ae9d3f9d2bdb6b847cf255f1f398193a1f88884a0ae8e18f24a037b6" }, { @@ -697,23 +712,23 @@ "selector": "0x137a07fa9c479e27114b8ae1fbf252f2065cf91a0d8615272e060a7ccf37309" }, { - "offset": 1924, + "offset": 1955, "selector": "0x14dae1999ae9ab799bc72def6dc6e90890cf8ac0d64525021b7e71d05cb13e8" }, { - "offset": 1402, + "offset": 1433, "selector": "0x167ac610845cc0ab1501b38169a7e50f1bf60602d3c2a961b30987454f97812" }, { - "offset": 933, + "offset": 964, "selector": "0x169f135eddda5ab51886052d777a57f2ea9c162d713691b5e04a6d4ed71d47f" }, { - "offset": 1835, + "offset": 1866, "selector": "0x1ae1a515cf2d214b29bdf63a79ee2d490efd4dd1acc99d383a8e549c3cecb5d" }, { - "offset": 1055, + "offset": 1086, "selector": "0x1b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d" }, { @@ -721,7 +736,7 @@ "selector": "0x1b47f727a0668d8593c5bb115d5b53a470f29833fd4d598e748f68e65f4f003" }, { - "offset": 1481, + "offset": 1512, "selector": "0x1de4779362d5ca708d55fe1d4d499501b7f692730d2e01656e9180708985e07" }, { @@ -729,19 +744,19 @@ "selector": "0x27c3334165536f239cfd400ed956eabff55fc60de4fb56728b6a4f6b87db01c" }, { - "offset": 1347, + "offset": 1378, "selector": "0x309687d54611a7db521175c78ba48b082df1372350d2529981a8c0dd09a6529" }, { - "offset": 1750, + "offset": 1781, "selector": "0x30f842021fbf02caf80d09a113997c1e00a32870eee0c6136bed27acb348bea" }, { - "offset": 1670, + "offset": 1701, "selector": "0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f" }, { - "offset": 1187, + "offset": 1218, "selector": "0x32564d7e0fe091d49b4c20f4632191e4ed6986bf993849879abfef9465def25" }, { @@ -749,7 +764,7 @@ "selector": "0x3307b3297ab2ab7a46a9b7d139a52dddf9c343e9a0a3ac69c5b4048d80e3aaf" }, { - "offset": 1426, + "offset": 1457, "selector": "0x33ce93a3eececa5c9fc70da05f4aff3b00e1820b79587924d514bc76788991a" }, { @@ -757,11 +772,11 @@ "selector": "0x3604cea1cdb094a73a31144f14a3e5861613c008e1e879939ebc4827d10cd50" }, { - "offset": 985, + "offset": 1016, "selector": "0x36fa6de2810d05c3e1a0ebe23f60b9c2f4629bbead09e5a9704e1c5632630d5" }, { - "offset": 1021, + "offset": 1052, "selector": "0x38215592552d97419658d30db8f189b242ec2056641de3dff8a7217745ec205" }, { @@ -781,18 +796,59 @@ "selector": "0x3b097c62d3e4b85742aadd0dfb823f96134b886ec13bda57b68faf86f294d97" }, { - "offset": 1378, + "offset": 904, + "selector": "0x3bf01fb7497d041938cb7b2954d8c4590006d26b3acd0f5aec1af45dc4f94b2" + }, + { + "offset": 1409, "selector": "0x3dc5da2d6d1275aeed57f43461d31967b0fed58bfe739b4ffad4091e89c4b03" }, { - "offset": 1213, + "offset": 1244, "selector": "0x3eb640b15f75fcc06d43182cdb94ed38c8e71755d5fb57c16dd673b466db1d4" } ], "L1_HANDLER": [] }, "program": { - "attributes": [], + "attributes": [ + { + "accessible_scopes": [ + "__main__", + "__main__", + "__main__.test_call_contract_fail_with_attr_error_msg" + ], + "end_pc": 902, + "flow_tracking_data": { + "ap_tracking": { + "group": 75, + "offset": 0 + }, + "reference_ids": {} + }, + "name": "error_message", + "start_pc": 892, + "value": "Be aware of failure ahead..." + }, + { + "accessible_scopes": [ + "__main__", + "__main__", + "__main__.fail" + ], + "end_pc": 1217, + "flow_tracking_data": { + "ap_tracking": { + "group": 97, + "offset": 0 + }, + "reference_ids": {} + }, + "name": "error_message", + "start_pc": 1213, + "value": "You shall not pass!" + } + ], "builtins": [ "pedersen", "range_check", @@ -1693,10 +1749,41 @@ "0x48127ff87fff8000", "0x48127ff87fff8000", "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffc9e", + "0x480a7ffb7fff8000", "0x480a7ffc7fff8000", "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffd0a", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffc9b", + "0x48127ffd7fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ffd8000", + "0x2", + "0x402a7ffd7ffc7fff", + "0x480280007ffb8000", + "0x480280007ffd8000", + "0x480280017ffd8000", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffef", + "0x40780017fff7fff", + "0x1", + "0x48127ffe7fff8000", + "0x480280017ffb8000", + "0x480280027ffb8000", + "0x480280037ffb8000", + "0x480280047ffb8000", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x1104800180018000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffceb", "0x208b7fff7fff7ffe", "0x482680017ffd8000", "0x1", @@ -1723,7 +1810,7 @@ "0x480a7ffc7fff8000", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffc9e", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffc7f", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x1", @@ -1775,11 +1862,11 @@ "0x480680017fff8000", "0x27", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffdfb", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffddc", "0x480680017fff8000", "0x1", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffde9", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffdca", "0x400680017fff7fff", "0x27", "0x48127ffc7fff8000", @@ -1811,7 +1898,7 @@ "0x480a7ffc7fff8000", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffd9c", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffd7d", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x1", @@ -1895,7 +1982,7 @@ "0x482680017ffd8000", "0x3", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffbda", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffbbb", "0x48127ffd7fff8000", "0x480680017fff8000", "0x0", @@ -1913,7 +2000,7 @@ "0x482680017ffd8000", "0x3", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffbd4", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffbb5", "0x48127ffd7fff8000", "0x480680017fff8000", "0x0", @@ -2067,7 +2154,7 @@ "0x482680017ffd8000", "0x800000000000011000000000000000000000000000000000000000000000000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb29", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb0a", "0x482480017fff8000", "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffffe", "0x40137fff7fff8000", @@ -2078,7 +2165,7 @@ "0x3", "0x480a80007fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb23", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb04", "0x48127ffd7fff8000", "0x208b7fff7fff7ffe", "0x482680017ffd8000", @@ -2107,15 +2194,15 @@ "0x480a7ff97fff8000", "0x480a7ffa7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb56", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb37", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb28", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb09", "0x480a7ffb7fff8000", "0x480a7ffc7fff8000", "0x480680017fff8000", "0x0", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffaf9", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffada", "0x482480017fff8000", "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffffd", "0x40137fff7fff8000", @@ -2127,7 +2214,7 @@ "0x4", "0x480a80007fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffaf2", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffad3", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x3", @@ -2143,7 +2230,7 @@ "0x480a7ffc7fff8000", "0x480a7ffb7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffacd", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffaae", "0x480a80017fff8000", "0x4829800080008002", "0x480a80007fff8000", @@ -2175,7 +2262,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffaf4", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffad5", "0x400a7ffd7fff7fff", "0x48127ffe7fff8000", "0x208b7fff7fff7ffe", @@ -2199,7 +2286,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffae3", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffac4", "0x400a7ffd7fff7fff", "0x48127ffe7fff8000", "0x208b7fff7fff7ffe", @@ -2223,7 +2310,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffabd", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa9e", "0x400a7ffd7fff7fff", "0x48127ffe7fff8000", "0x208b7fff7fff7ffe", @@ -2247,7 +2334,7 @@ "0x208b7fff7fff7ffe", "0x480a7ff67fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffadc", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffabd", "0x480080007fff8000", "0x480080017ffe8000", "0x480080027ffd8000", @@ -2269,17 +2356,17 @@ "0x12c", "0x48127ffb7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffab4", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa95", "0x480680017fff8000", "0x137", "0x48127ff67fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffaaf", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa90", "0x480680017fff8000", "0x142", "0x48127ff17fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffaaa", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa8b", "0x480a7ff77fff8000", "0x208b7fff7fff7ffe", "0x482680017ffd8000", @@ -2308,7 +2395,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa9f", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa80", "0x400180007fff7ffd", "0x48127ffe7fff8000", "0x208b7fff7fff7ffe", @@ -2336,13 +2423,13 @@ "0x480680017fff8000", "0x0", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa71", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa52", "0x480680017fff8000", "0xf", "0x480680017fff8000", "0x1", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa6b", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa4c", "0x480a7ffd7fff8000", "0x208b7fff7fff7ffe", "0x402b7ffd7ffc7ffd", @@ -2364,7 +2451,7 @@ "0x40780017fff7fff", "0x1", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9e7", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9c8", "0x40137fff7fff8000", "0x4003800080007ffb", "0x4003800180007ffc", @@ -2378,7 +2465,7 @@ "0x4828800080007ffc", "0x480a80007fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9f7", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9d8", "0x48127ffd7fff8000", "0x480a7ff97fff8000", "0x208b7fff7fff7ffe", @@ -2387,11 +2474,11 @@ "0x2691cb735b18f3f656c3b82bd97a32b65d15019b64117513f8604d1e06fe58b", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9d3", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9b4", "0x480a7ffc7fff8000", "0x48127ffe7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa67", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa48", "0x48127fe17fff8000", "0x48127ffd7fff8000", "0x48127ffd7fff8000", @@ -2404,12 +2491,12 @@ "0x480a7ffa7fff8000", "0x48127ffe7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa25", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa06", "0x48127ffe7fff8000", "0x482480017ff78000", "0x1", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa20", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa01", "0x48127ffe7fff8000", "0x48127fee7fff8000", "0x48127fee7fff8000", @@ -2425,12 +2512,12 @@ "0x48127ffe7fff8000", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa18", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9f9", "0x482480017ff88000", "0x1", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa13", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9f4", "0x48127ff07fff8000", "0x48127ff07fff8000", "0x208b7fff7fff7ffe", @@ -2447,12 +2534,12 @@ "0x48127ffe7fff8000", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa02", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9e3", "0x482480017ff88000", "0x1", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9fd", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9de", "0x48127ff07fff8000", "0x48127ff07fff8000", "0x208b7fff7fff7ffe", @@ -2503,12 +2590,12 @@ "0x48127ffd7fff8000", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa1f", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa00", "0x48127ffe7fff8000", "0x48127ff77fff8000", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa1a", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9fb", "0x48127fed7fff8000", "0x48127fed7fff8000", "0x48127fed7fff8000", @@ -2585,7 +2672,7 @@ "0x480680017fff8000", "0x4b5810004d9272776dec83ecc20c19353453b956e594188890b48467cb53c19", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa0f", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9f0", "0x480a7ffa7fff8000", "0x480a7ffb7fff8000", "0x480a7ffc7fff8000", @@ -2615,7 +2702,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff94a", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff92b", "0x400680017fff7ffe", "0x2", "0x48127ffd7fff8000", @@ -2663,14 +2750,14 @@ "0x400780017fff8001", "0x22", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff8d4", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff8b5", "0x480a7ffc7fff8000", "0x480a7ffd7fff8000", "0x480680017fff8000", "0x2", "0x48127ffb7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9d9", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9ba", "0x208b7fff7fff7ffe", "0x482680017ffd8000", "0x1", @@ -2702,7 +2789,7 @@ "0x480a7ffc7fff8000", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff90b", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff8ec", "0x480a7ff77fff8000", "0x480a7ff87fff8000", "0x482680017ff98000", @@ -3385,25 +3472,43 @@ } } ], - "904": [ + "912": [ { "accessible_scopes": [ "__main__", "__main__", "__wrappers__", - "__wrappers__.test_replace_class" + "__wrappers__.test_call_contract_fail_with_attr_error_msg" ], "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { "group": 76, + "offset": 23 + }, + "reference_ids": {} + } + } + ], + "935": [ + { + "accessible_scopes": [ + "__main__", + "__main__", + "__wrappers__", + "__wrappers__.test_replace_class" + ], + "code": "memory[ap] = segments.add()", + "flow_tracking_data": { + "ap_tracking": { + "group": 78, "offset": 11 }, "reference_ids": {} } } ], - "924": [ + "955": [ { "accessible_scopes": [ "__main__", @@ -3414,14 +3519,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 78, + "group": 80, "offset": 0 }, "reference_ids": {} } } ], - "991": [ + "1022": [ { "accessible_scopes": [ "__main__", @@ -3432,14 +3537,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 81, + "group": 83, "offset": 126 }, "reference_ids": {} } } ], - "1012": [ + "1043": [ { "accessible_scopes": [ "__main__", @@ -3450,14 +3555,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 84, + "group": 86, "offset": 0 }, "reference_ids": {} } } ], - "1058": [ + "1089": [ { "accessible_scopes": [ "__main__", @@ -3468,14 +3573,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 88, + "group": 90, "offset": 2 }, "reference_ids": {} } } ], - "1145": [ + "1176": [ { "accessible_scopes": [ "__main__", @@ -3486,14 +3591,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 92, + "group": 94, "offset": 0 }, "reference_ids": {} } } ], - "1190": [ + "1221": [ { "accessible_scopes": [ "__main__", @@ -3504,14 +3609,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 96, + "group": 98, "offset": 3 }, "reference_ids": {} } } ], - "1219": [ + "1250": [ { "accessible_scopes": [ "__main__", @@ -3522,14 +3627,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 100, + "group": 102, "offset": 0 }, "reference_ids": {} } } ], - "1244": [ + "1275": [ { "accessible_scopes": [ "__main__", @@ -3540,14 +3645,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 104, + "group": 106, "offset": 0 }, "reference_ids": {} } } ], - "1289": [ + "1320": [ { "accessible_scopes": [ "__main__", @@ -3558,14 +3663,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 107, + "group": 109, "offset": 0 }, "reference_ids": {} } } ], - "1328": [ + "1359": [ { "accessible_scopes": [ "__main__", @@ -3576,14 +3681,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 109, + "group": 111, "offset": 0 }, "reference_ids": {} } } ], - "1385": [ + "1416": [ { "accessible_scopes": [ "__main__", @@ -3594,14 +3699,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 114, + "group": 116, "offset": 12 }, "reference_ids": {} } } ], - "1409": [ + "1440": [ { "accessible_scopes": [ "__main__", @@ -3612,14 +3717,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 116, + "group": 118, "offset": 12 }, "reference_ids": {} } } ], - "1433": [ + "1464": [ { "accessible_scopes": [ "__main__", @@ -3630,14 +3735,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 118, + "group": 120, "offset": 12 }, "reference_ids": {} } } ], - "1494": [ + "1525": [ { "accessible_scopes": [ "__main__", @@ -3648,14 +3753,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 120, + "group": 122, "offset": 45 }, "reference_ids": {} } } ], - "1518": [ + "1549": [ { "accessible_scopes": [ "__main__", @@ -3666,14 +3771,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 122, + "group": 124, "offset": 12 }, "reference_ids": {} } } ], - "1549": [ + "1580": [ { "accessible_scopes": [ "__main__", @@ -3684,14 +3789,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 124, + "group": 126, "offset": 18 }, "reference_ids": {} } } ], - "1681": [ + "1712": [ { "accessible_scopes": [ "__main__", @@ -3702,14 +3807,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 132, + "group": 134, "offset": 145 }, "reference_ids": {} } } ], - "1730": [ + "1761": [ { "accessible_scopes": [ "__main__", @@ -3720,14 +3825,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 134, + "group": 136, "offset": 161 }, "reference_ids": {} } } ], - "1761": [ + "1792": [ { "accessible_scopes": [ "__main__", @@ -3738,14 +3843,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 136, + "group": 138, "offset": 35 }, "reference_ids": {} } } ], - "1801": [ + "1832": [ { "accessible_scopes": [ "__main__", @@ -3756,14 +3861,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 140, + "group": 142, "offset": 0 }, "reference_ids": {} } } ], - "1844": [ + "1875": [ { "accessible_scopes": [ "__main__", @@ -3774,14 +3879,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 142, + "group": 144, "offset": 153 }, "reference_ids": {} } } ], - "1878": [ + "1909": [ { "accessible_scopes": [ "__main__", @@ -3792,14 +3897,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 144, + "group": 146, "offset": 17 }, "reference_ids": {} } } ], - "1953": [ + "1984": [ { "accessible_scopes": [ "__main__", @@ -3810,7 +3915,7 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 150, + "group": 152, "offset": 0 }, "reference_ids": {} @@ -3899,7 +4004,7 @@ }, "__main__.MyContract.xor_counters": { "decorators": [], - "pc": 1560, + "pc": 1591, "type": "function" }, "__main__.MyContract.xor_counters.Args": { @@ -3952,7 +4057,7 @@ "decorators": [ "external" ], - "pc": 1812, + "pc": 1843, "type": "function" }, "__main__.add_signature_to_counters.Args": { @@ -3997,7 +4102,7 @@ "decorators": [ "external" ], - "pc": 1655, + "pc": 1686, "type": "function" }, "__main__.advance_counter.Args": { @@ -4099,7 +4204,7 @@ "decorators": [ "external" ], - "pc": 1741, + "pc": 1772, "type": "function" }, "__main__.call_xor_counters.Args": { @@ -4218,7 +4323,7 @@ }, "__main__.ec_point.addr": { "decorators": [], - "pc": 1633, + "pc": 1664, "type": "function" }, "__main__.ec_point.addr.Args": { @@ -4268,7 +4373,7 @@ }, "__main__.ec_point.write": { "decorators": [], - "pc": 1638, + "pc": 1669, "type": "function" }, "__main__.ec_point.write.Args": { @@ -4315,7 +4420,7 @@ }, "__main__.emit_event_recurse": { "decorators": [], - "pc": 1889, + "pc": 1920, "type": "function" }, "__main__.emit_event_recurse.Args": { @@ -4376,7 +4481,7 @@ "decorators": [ "external" ], - "pc": 1182, + "pc": 1213, "type": "function" }, "__main__.fail.Args": { @@ -4403,7 +4508,7 @@ "decorators": [ "external" ], - "pc": 1054, + "pc": 1085, "type": "function" }, "__main__.foo.Args": { @@ -4462,7 +4567,7 @@ "decorators": [ "external" ], - "pc": 1069, + "pc": 1100, "type": "function" }, "__main__.invoke_call_chain.Args": { @@ -4679,7 +4784,7 @@ "decorators": [ "external" ], - "pc": 1230, + "pc": 1261, "type": "function" }, "__main__.recurse.Args": { @@ -4711,7 +4816,7 @@ "decorators": [ "external" ], - "pc": 1201, + "pc": 1232, "type": "function" }, "__main__.recursive_fail.Args": { @@ -4743,7 +4848,7 @@ "decorators": [ "external" ], - "pc": 1255, + "pc": 1286, "type": "function" }, "__main__.recursive_syscall.Args": { @@ -4824,7 +4929,7 @@ "decorators": [ "external" ], - "pc": 1855, + "pc": 1886, "type": "function" }, "__main__.send_message.Args": { @@ -4986,11 +5091,52 @@ "type": "const", "value": 0 }, + "__main__.test_call_contract_fail_with_attr_error_msg": { + "decorators": [ + "external" + ], + "pc": 892, + "type": "function" + }, + "__main__.test_call_contract_fail_with_attr_error_msg.Args": { + "full_name": "__main__.test_call_contract_fail_with_attr_error_msg.Args", + "members": { + "contract_address": { + "cairo_type": "felt", + "offset": 0 + }, + "function_selector": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 2, + "type": "struct" + }, + "__main__.test_call_contract_fail_with_attr_error_msg.ImplicitArgs": { + "full_name": "__main__.test_call_contract_fail_with_attr_error_msg.ImplicitArgs", + "members": { + "syscall_ptr": { + "cairo_type": "felt*", + "offset": 0 + } + }, + "size": 1, + "type": "struct" + }, + "__main__.test_call_contract_fail_with_attr_error_msg.Return": { + "cairo_type": "()", + "type": "type_definition" + }, + "__main__.test_call_contract_fail_with_attr_error_msg.SIZEOF_LOCALS": { + "type": "const", + "value": 0 + }, "__main__.test_contract_address": { "decorators": [ "external" ], - "pc": 1002, + "pc": 1033, "type": "function" }, "__main__.test_contract_address.Args": { @@ -5047,7 +5193,7 @@ "decorators": [ "external" ], - "pc": 1529, + "pc": 1560, "type": "function" }, "__main__.test_count_actual_storage_changes.Args": { @@ -5087,7 +5233,7 @@ "decorators": [ "external" ], - "pc": 915, + "pc": 946, "type": "function" }, "__main__.test_deploy.Args": { @@ -5140,7 +5286,7 @@ "decorators": [ "external" ], - "pc": 1772, + "pc": 1803, "type": "function" }, "__main__.test_ec_op.Args": { @@ -5184,7 +5330,7 @@ "decorators": [ "external" ], - "pc": 1913, + "pc": 1944, "type": "function" }, "__main__.test_emit_events.Args": { @@ -5245,7 +5391,7 @@ "decorators": [ "external" ], - "pc": 1372, + "pc": 1403, "type": "function" }, "__main__.test_get_block_number.Args": { @@ -5282,7 +5428,7 @@ "decorators": [ "external" ], - "pc": 1396, + "pc": 1427, "type": "function" }, "__main__.test_get_block_timestamp.Args": { @@ -5319,7 +5465,7 @@ "decorators": [ "external" ], - "pc": 1420, + "pc": 1451, "type": "function" }, "__main__.test_get_sequencer_address.Args": { @@ -5356,7 +5502,7 @@ "decorators": [ "external" ], - "pc": 1444, + "pc": 1475, "type": "function" }, "__main__.test_get_tx_info.Args": { @@ -5547,7 +5693,7 @@ "decorators": [ "external" ], - "pc": 892, + "pc": 923, "type": "function" }, "__main__.test_replace_class.Args": { @@ -5625,7 +5771,7 @@ "decorators": [ "external" ], - "pc": 966, + "pc": 997, "type": "function" }, "__main__.test_storage_var.Args": { @@ -5665,7 +5811,7 @@ "decorators": [ "external" ], - "pc": 1505, + "pc": 1536, "type": "function" }, "__main__.test_tx_version.Args": { @@ -5702,7 +5848,7 @@ "decorators": [ "external" ], - "pc": 1300, + "pc": 1331, "type": "function" }, "__main__.test_write_and_transfer.Args": { @@ -5780,7 +5926,7 @@ }, "__main__.two_counters.addr": { "decorators": [], - "pc": 1581, + "pc": 1612, "type": "function" }, "__main__.two_counters.addr.Args": { @@ -5827,7 +5973,7 @@ }, "__main__.two_counters.read": { "decorators": [], - "pc": 1595, + "pc": 1626, "type": "function" }, "__main__.two_counters.read.Args": { @@ -5878,7 +6024,7 @@ }, "__main__.two_counters.write": { "decorators": [], - "pc": 1615, + "pc": 1646, "type": "function" }, "__main__.two_counters.write.Args": { @@ -6068,7 +6214,7 @@ "decorators": [ "external" ], - "pc": 1692, + "pc": 1723, "type": "function" }, "__main__.xor_counters.Args": { @@ -6117,7 +6263,7 @@ "decorators": [ "external" ], - "pc": 1835, + "pc": 1866, "type": "function" }, "__wrappers__.add_signature_to_counters.Args": { @@ -6152,7 +6298,7 @@ "decorators": [ "external" ], - "pc": 1670, + "pc": 1701, "type": "function" }, "__wrappers__.advance_counter.Args": { @@ -6222,7 +6368,7 @@ "decorators": [ "external" ], - "pc": 1750, + "pc": 1781, "type": "function" }, "__wrappers__.call_xor_counters.Args": { @@ -6292,7 +6438,7 @@ "decorators": [ "external" ], - "pc": 1187, + "pc": 1218, "type": "function" }, "__wrappers__.fail.Args": { @@ -6327,7 +6473,7 @@ "decorators": [ "external" ], - "pc": 1055, + "pc": 1086, "type": "function" }, "__wrappers__.foo.Args": { @@ -6362,7 +6508,7 @@ "decorators": [ "external" ], - "pc": 1154, + "pc": 1185, "type": "function" }, "__wrappers__.invoke_call_chain.Args": { @@ -6391,7 +6537,7 @@ }, "__wrappers__.invoke_call_chain_encode_return": { "decorators": [], - "pc": 1145, + "pc": 1176, "type": "function" }, "__wrappers__.invoke_call_chain_encode_return.Args": { @@ -6431,7 +6577,7 @@ "decorators": [ "external" ], - "pc": 1238, + "pc": 1269, "type": "function" }, "__wrappers__.recurse.Args": { @@ -6466,7 +6612,7 @@ "decorators": [ "external" ], - "pc": 1213, + "pc": 1244, "type": "function" }, "__wrappers__.recursive_fail.Args": { @@ -6501,7 +6647,7 @@ "decorators": [ "external" ], - "pc": 1280, + "pc": 1311, "type": "function" }, "__wrappers__.recursive_syscall.Args": { @@ -6605,7 +6751,7 @@ "decorators": [ "external" ], - "pc": 1871, + "pc": 1902, "type": "function" }, "__wrappers__.send_message.Args": { @@ -6707,11 +6853,46 @@ "destination": "starkware.cairo.common.memcpy.memcpy", "type": "alias" }, + "__wrappers__.test_call_contract_fail_with_attr_error_msg": { + "decorators": [ + "external" + ], + "pc": 904, + "type": "function" + }, + "__wrappers__.test_call_contract_fail_with_attr_error_msg.Args": { + "full_name": "__wrappers__.test_call_contract_fail_with_attr_error_msg.Args", + "members": {}, + "size": 0, + "type": "struct" + }, + "__wrappers__.test_call_contract_fail_with_attr_error_msg.ImplicitArgs": { + "full_name": "__wrappers__.test_call_contract_fail_with_attr_error_msg.ImplicitArgs", + "members": {}, + "size": 0, + "type": "struct" + }, + "__wrappers__.test_call_contract_fail_with_attr_error_msg.Return": { + "cairo_type": "(syscall_ptr: felt*, pedersen_ptr: felt, range_check_ptr: felt, bitwise_ptr: felt, ec_op_ptr: felt, size: felt, retdata: felt*)", + "type": "type_definition" + }, + "__wrappers__.test_call_contract_fail_with_attr_error_msg.SIZEOF_LOCALS": { + "type": "const", + "value": 0 + }, + "__wrappers__.test_call_contract_fail_with_attr_error_msg.__wrapped_func": { + "destination": "__main__.test_call_contract_fail_with_attr_error_msg", + "type": "alias" + }, + "__wrappers__.test_call_contract_fail_with_attr_error_msg_encode_return.memcpy": { + "destination": "starkware.cairo.common.memcpy.memcpy", + "type": "alias" + }, "__wrappers__.test_contract_address": { "decorators": [ "external" ], - "pc": 1021, + "pc": 1052, "type": "function" }, "__wrappers__.test_contract_address.Args": { @@ -6740,7 +6921,7 @@ }, "__wrappers__.test_contract_address_encode_return": { "decorators": [], - "pc": 1012, + "pc": 1043, "type": "function" }, "__wrappers__.test_contract_address_encode_return.Args": { @@ -6780,7 +6961,7 @@ "decorators": [ "external" ], - "pc": 1544, + "pc": 1575, "type": "function" }, "__wrappers__.test_count_actual_storage_changes.Args": { @@ -6815,7 +6996,7 @@ "decorators": [ "external" ], - "pc": 933, + "pc": 964, "type": "function" }, "__wrappers__.test_deploy.Args": { @@ -6844,7 +7025,7 @@ }, "__wrappers__.test_deploy_encode_return": { "decorators": [], - "pc": 924, + "pc": 955, "type": "function" }, "__wrappers__.test_deploy_encode_return.Args": { @@ -6884,7 +7065,7 @@ "decorators": [ "external" ], - "pc": 1794, + "pc": 1825, "type": "function" }, "__wrappers__.test_ec_op.Args": { @@ -6919,7 +7100,7 @@ "decorators": [ "external" ], - "pc": 1924, + "pc": 1955, "type": "function" }, "__wrappers__.test_emit_events.Args": { @@ -6954,7 +7135,7 @@ "decorators": [ "external" ], - "pc": 1378, + "pc": 1409, "type": "function" }, "__wrappers__.test_get_block_number.Args": { @@ -6989,7 +7170,7 @@ "decorators": [ "external" ], - "pc": 1402, + "pc": 1433, "type": "function" }, "__wrappers__.test_get_block_timestamp.Args": { @@ -7024,7 +7205,7 @@ "decorators": [ "external" ], - "pc": 1426, + "pc": 1457, "type": "function" }, "__wrappers__.test_get_sequencer_address.Args": { @@ -7059,7 +7240,7 @@ "decorators": [ "external" ], - "pc": 1481, + "pc": 1512, "type": "function" }, "__wrappers__.test_get_tx_info.Args": { @@ -7268,7 +7449,7 @@ "decorators": [ "external" ], - "pc": 897, + "pc": 928, "type": "function" }, "__wrappers__.test_replace_class.Args": { @@ -7372,7 +7553,7 @@ "decorators": [ "external" ], - "pc": 985, + "pc": 1016, "type": "function" }, "__wrappers__.test_storage_var.Args": { @@ -7407,7 +7588,7 @@ "decorators": [ "external" ], - "pc": 1511, + "pc": 1542, "type": "function" }, "__wrappers__.test_tx_version.Args": { @@ -7442,7 +7623,7 @@ "decorators": [ "external" ], - "pc": 1347, + "pc": 1378, "type": "function" }, "__wrappers__.test_write_and_transfer.Args": { @@ -7471,7 +7652,7 @@ }, "__wrappers__.test_write_and_transfer_encode_return": { "decorators": [], - "pc": 1328, + "pc": 1359, "type": "function" }, "__wrappers__.test_write_and_transfer_encode_return.Args": { @@ -7651,7 +7832,7 @@ "decorators": [ "external" ], - "pc": 1718, + "pc": 1749, "type": "function" }, "__wrappers__.xor_counters.Args": { diff --git a/crates/blockifier/feature_contracts/cairo0/test_contract.cairo b/crates/blockifier/feature_contracts/cairo0/test_contract.cairo index 7354464f7a..8f2cfc6701 100644 --- a/crates/blockifier/feature_contracts/cairo0/test_contract.cairo +++ b/crates/blockifier/feature_contracts/cairo0/test_contract.cairo @@ -165,6 +165,21 @@ func test_call_contract{syscall_ptr: felt*}( return (retdata_size=retdata_size, retdata=retdata); } +@external +func test_call_contract_fail_with_attr_error_msg{syscall_ptr: felt*}( + contract_address: felt, function_selector: felt +) -> () { + with_attr error_message("Be aware of failure ahead...") { + call_contract( + contract_address=contract_address, + function_selector=function_selector, + calldata_size=0, + calldata=new(), + ); + } + return (); +} + @external func test_replace_class{syscall_ptr: felt*}(class_hash: felt) -> () { replace_class(class_hash=class_hash); @@ -274,7 +289,9 @@ func invoke_call_chain{syscall_ptr: felt*}(calldata_len: felt, calldata: felt*) @external func fail() { - assert 0 = 1; + with_attr error_message("You shall not pass!") { + assert 0 = 1; + } return (); } @@ -502,3 +519,4 @@ func test_emit_events{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_chec ) { return emit_event_recurse(events_count, keys_len, keys, data_len, data); } + diff --git a/crates/blockifier/feature_contracts/cairo1/account_faulty.cairo b/crates/blockifier/feature_contracts/cairo1/account_faulty.cairo index 3c08b1535f..32e0b637b4 100644 --- a/crates/blockifier/feature_contracts/cairo1/account_faulty.cairo +++ b/crates/blockifier/feature_contracts/cairo1/account_faulty.cairo @@ -114,7 +114,7 @@ mod Account { } if (scenario == CALL_CONTRACT) { let contract_address: felt252 = *signature[1_u32]; - let mut calldata = Default::default(); + let mut calldata: Array = Default::default(); call_contract_syscall( address: contract_address_try_from_felt252(contract_address).unwrap(), entry_point_selector: FOO_ENTRY_POINT_SELECTOR, @@ -143,4 +143,4 @@ mod Account { starknet::VALIDATED } -} +} \ No newline at end of file diff --git a/crates/blockifier/feature_contracts/cairo1/compiled/account_faulty.casm.json b/crates/blockifier/feature_contracts/cairo1/compiled/account_faulty.casm.json index 8d2abe5ec2..929af0a634 100644 --- a/crates/blockifier/feature_contracts/cairo1/compiled/account_faulty.casm.json +++ b/crates/blockifier/feature_contracts/cairo1/compiled/account_faulty.casm.json @@ -1,6 +1,6 @@ { "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "compiler_version": "2.6.0", + "compiler_version": "2.8.0", "bytecode": [ "0xa0680017fff8000", "0x7", diff --git a/crates/blockifier/feature_contracts/cairo1/compiled/account_with_dummy_validate.casm.json b/crates/blockifier/feature_contracts/cairo1/compiled/account_with_dummy_validate.casm.json index 1037d4c7b4..d2d24d2e55 100644 --- a/crates/blockifier/feature_contracts/cairo1/compiled/account_with_dummy_validate.casm.json +++ b/crates/blockifier/feature_contracts/cairo1/compiled/account_with_dummy_validate.casm.json @@ -1,6 +1,6 @@ { "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "compiler_version": "2.6.0", + "compiler_version": "2.8.0", "bytecode": [ "0xa0680017fff8000", "0x7", diff --git a/crates/blockifier/feature_contracts/cairo1/compiled/account_with_long_validate.casm.json b/crates/blockifier/feature_contracts/cairo1/compiled/account_with_long_validate.casm.json index 48807a6494..90657d1d15 100644 --- a/crates/blockifier/feature_contracts/cairo1/compiled/account_with_long_validate.casm.json +++ b/crates/blockifier/feature_contracts/cairo1/compiled/account_with_long_validate.casm.json @@ -1,6 +1,6 @@ { "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "compiler_version": "2.6.0", + "compiler_version": "2.8.0", "bytecode": [ "0xa0680017fff8000", "0x7", diff --git a/crates/blockifier/feature_contracts/cairo1/compiled/empty_contract.casm.json b/crates/blockifier/feature_contracts/cairo1/compiled/empty_contract.casm.json index 45030bbbd7..3c51ffa991 100644 --- a/crates/blockifier/feature_contracts/cairo1/compiled/empty_contract.casm.json +++ b/crates/blockifier/feature_contracts/cairo1/compiled/empty_contract.casm.json @@ -1,6 +1,6 @@ { "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "compiler_version": "2.6.0", + "compiler_version": "2.8.0", "bytecode": [], "bytecode_segment_lengths": 0, "hints": [], diff --git a/crates/blockifier/feature_contracts/cairo1/compiled/test_contract.casm.json b/crates/blockifier/feature_contracts/cairo1/compiled/test_contract.casm.json index c470c611c6..6e61a64d92 100644 --- a/crates/blockifier/feature_contracts/cairo1/compiled/test_contract.casm.json +++ b/crates/blockifier/feature_contracts/cairo1/compiled/test_contract.casm.json @@ -1,6 +1,6 @@ { "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "compiler_version": "2.7.0", + "compiler_version": "2.8.0", "bytecode": [ "0xa0680017fff8000", "0x7", @@ -100,9 +100,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x4529", + "0x4795", "0x482480017fff8000", - "0x4528", + "0x4794", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -275,9 +275,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x447a", + "0x46e6", "0x482480017fff8000", - "0x4479", + "0x46e5", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -588,9 +588,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x4341", + "0x45ad", "0x482480017fff8000", - "0x4340", + "0x45ac", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -922,9 +922,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x41f3", + "0x445f", "0x482480017fff8000", - "0x41f2", + "0x445e", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -1128,9 +1128,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x4125", + "0x4391", "0x482480017fff8000", - "0x4124", + "0x4390", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -1344,9 +1344,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x404d", + "0x42b9", "0x482480017fff8000", - "0x404c", + "0x42b8", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -1682,9 +1682,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3efb", + "0x4167", "0x482480017fff8000", - "0x3efa", + "0x4166", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -1969,9 +1969,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3ddc", + "0x4048", "0x482480017fff8000", - "0x3ddb", + "0x4047", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -2186,9 +2186,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3d03", + "0x3f6f", "0x482480017fff8000", - "0x3d02", + "0x3f6e", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -2402,9 +2402,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3c2b", + "0x3e97", "0x482480017fff8000", - "0x3c2a", + "0x3e96", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -2541,9 +2541,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3ba0", + "0x3e0c", "0x482480017fff8000", - "0x3b9f", + "0x3e0b", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -2814,9 +2814,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3a8f", + "0x3cfb", "0x482480017fff8000", - "0x3a8e", + "0x3cfa", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -2992,9 +2992,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x39dd", + "0x3c49", "0x482480017fff8000", - "0x39dc", + "0x3c48", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -3096,9 +3096,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3975", + "0x3be1", "0x482480017fff8000", - "0x3974", + "0x3be0", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -3201,15 +3201,15 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x390c", + "0x3b78", "0x482480017fff8000", - "0x390b", + "0x3b77", "0x480080007fff8000", "0x480080017fff8000", "0x484480017fff8000", "0x8", "0x482480017fff8000", - "0x4142e", + "0x40312", "0xa0680017fff8000", "0x8", "0x48307ffe80007ff5", @@ -3313,21 +3313,21 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x389c", + "0x3b08", "0x482480017fff8000", - "0x389b", + "0x3b07", "0x480080007fff8000", "0xa0680017fff8000", "0x9", "0x4824800180007ff8", - "0x382d4", + "0x371b8", "0x482480017fff8000", "0x100000000000000000000000000000000", "0x400080007ff77fff", "0x10780017fff7fff", "0x1f", "0x4824800180007ff8", - "0x382d4", + "0x371b8", "0x400080007ff87fff", "0x482480017ff88000", "0x1", @@ -3459,9 +3459,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x380a", + "0x3a76", "0x482480017fff8000", - "0x3809", + "0x3a75", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -3661,9 +3661,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3740", + "0x39ac", "0x482480017fff8000", - "0x373f", + "0x39ab", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -3783,9 +3783,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x36c6", + "0x3932", "0x482480017fff8000", - "0x36c5", + "0x3931", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -3897,9 +3897,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3654", + "0x38c0", "0x482480017fff8000", - "0x3653", + "0x38bf", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -4036,9 +4036,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x35c9", + "0x3835", "0x482480017fff8000", - "0x35c8", + "0x3834", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -4241,9 +4241,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x34fc", + "0x3768", "0x482480017fff8000", - "0x34fb", + "0x3767", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -4485,9 +4485,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3408", + "0x3674", "0x482480017fff8000", - "0x3407", + "0x3673", "0x480080007fff8000", "0x480080007fff8000", "0x484480017fff8000", @@ -4653,9 +4653,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3360", + "0x35cc", "0x482480017fff8000", - "0x335f", + "0x35cb", "0x480080007fff8000", "0x480080007fff8000", "0x484480017fff8000", @@ -4844,9 +4844,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x32a1", + "0x350d", "0x482480017fff8000", - "0x32a0", + "0x350c", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -5001,9 +5001,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3204", + "0x3470", "0x482480017fff8000", - "0x3203", + "0x346f", "0x480080007fff8000", "0x480080027fff8000", "0x482480017fff8000", @@ -5133,9 +5133,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3180", + "0x33ec", "0x482480017fff8000", - "0x317f", + "0x33eb", "0x480080007fff8000", "0x480080007fff8000", "0x484480017fff8000", @@ -5282,9 +5282,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x30eb", + "0x3357", "0x482480017fff8000", - "0x30ea", + "0x3356", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -5420,9 +5420,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x3061", + "0x32cd", "0x482480017fff8000", - "0x3060", + "0x32cc", "0x480080007fff8000", "0x480080047fff8000", "0x484480017fff8000", @@ -5546,9 +5546,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x2fe3", + "0x324f", "0x482480017fff8000", - "0x2fe2", + "0x324e", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -5710,9 +5710,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x2f3f", + "0x31ab", "0x482480017fff8000", - "0x2f3e", + "0x31aa", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -5916,9 +5916,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x2e71", + "0x30dd", "0x482480017fff8000", - "0x2e70", + "0x30dc", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -6121,9 +6121,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x2da4", + "0x3010", "0x482480017fff8000", - "0x2da3", + "0x300f", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -8702,9 +8702,9 @@ "0x20680017fff7ffd", "0x37", "0x1104800180018000", - "0x2373", + "0x25df", "0x482480017fff8000", - "0x2372", + "0x25de", "0x48127ff97fff8000", "0x480a7ffc7fff8000", "0x480a7ffd7fff8000", @@ -9146,15 +9146,15 @@ "0x20680017fff7ffc", "0x12", "0x40780017fff7fff", - "0x327", + "0x30c", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x53686f756c64206265206e6f6e65", "0x400080007ffe7fff", "0x480a7ffb7fff8000", - "0x48127cd47fff8000", - "0x48127cd47fff8000", + "0x48127cef7fff8000", + "0x48127cef7fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", @@ -9181,15 +9181,15 @@ "0x20680017fff7fff", "0x13", "0x40780017fff7fff", - "0x321", + "0x306", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x53686f756c64206661696c", "0x400080007ffe7fff", "0x480a7ffb7fff8000", - "0x480080067cd58000", - "0x482480017cd48000", + "0x480080067cf08000", + "0x482480017cef8000", "0xa", "0x480680017fff8000", "0x1", @@ -9271,7 +9271,7 @@ "0x10780017fff7fff", "0x6", "0x40780017fff7fff", - "0x301", + "0x2e6", "0x10780017fff7fff", "0xa", "0x4824800180007ffa", @@ -9281,7 +9281,7 @@ "0x10780017fff7fff", "0x6", "0x40780017fff7fff", - "0x300", + "0x2e5", "0x10780017fff7fff", "0x14", "0x4824800180007ffc", @@ -9291,7 +9291,7 @@ "0x10780017fff7fff", "0x6", "0x40780017fff7fff", - "0x2ff", + "0x2e4", "0x10780017fff7fff", "0xa", "0x4824800180007ffc", @@ -9301,15 +9301,15 @@ "0x10780017fff7fff", "0x12", "0x40780017fff7fff", - "0x2fe", + "0x2e3", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x556e657870656374656420636f6f7264696e61746573", "0x400080007ffe7fff", - "0x48127ce97fff8000", - "0x48127cf77fff8000", - "0x48127cf77fff8000", + "0x48127d047fff8000", + "0x48127d127fff8000", + "0x48127d127fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", @@ -9404,15 +9404,15 @@ "0x48127ffa7fff8000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x2ea", + "0x2cf", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x4f7074696f6e3a3a756e77726170206661696c65642e", "0x400080007ffe7fff", - "0x48127d0d7fff8000", - "0x48127d117fff8000", - "0x48127d117fff8000", + "0x48127d287fff8000", + "0x48127d2c7fff8000", + "0x48127d2c7fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", @@ -9420,37 +9420,37 @@ "0x1", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x2f0", - "0x48127d0d7fff8000", - "0x480080067cf88000", - "0x482480017cf78000", + "0x2d5", + "0x48127d287fff8000", + "0x480080067d138000", + "0x482480017d128000", "0xa", "0x480680017fff8000", "0x1", - "0x480080087cf58000", - "0x480080097cf48000", + "0x480080087d108000", + "0x480080097d0f8000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x30a", - "0x48127ce97fff8000", - "0x480080037cf28000", - "0x482480017cf18000", + "0x2ef", + "0x48127d047fff8000", + "0x480080037d0d8000", + "0x482480017d0c8000", "0x7", "0x480680017fff8000", "0x1", - "0x480080057cef8000", - "0x480080067cee8000", + "0x480080057d0a8000", + "0x480080067d098000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x30a", + "0x2ef", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x4f7074696f6e3a3a756e77726170206661696c65642e", "0x400080007ffe7fff", - "0x48127ce97fff8000", - "0x48127cf17fff8000", - "0x48127cf17fff8000", + "0x48127d047fff8000", + "0x48127d0c7fff8000", + "0x48127d0c7fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", @@ -9458,26 +9458,26 @@ "0x1", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x310", - "0x48127ce97fff8000", - "0x480080067ce08000", - "0x482480017cdf8000", + "0x2f5", + "0x48127d047fff8000", + "0x480080067cfb8000", + "0x482480017cfa8000", "0xa", "0x480680017fff8000", "0x1", - "0x480080087cdd8000", - "0x480080097cdc8000", + "0x480080087cf88000", + "0x480080097cf78000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x314", + "0x2f9", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x57726f6e67206572726f72206d7367", "0x400080007ffe7fff", - "0x48127ce97fff8000", - "0x48127cdf7fff8000", - "0x48127cdf7fff8000", + "0x48127d047fff8000", + "0x48127cfa7fff8000", + "0x48127cfa7fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", @@ -9485,7 +9485,7 @@ "0x1", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x319", + "0x2fe", "0x40780017fff7fff", "0x1", "0x480680017fff8000", @@ -9493,8 +9493,8 @@ "0x400080007ffe7fff", "0x482680017ffb8000", "0x1", - "0x48127cdf7fff8000", - "0x48127cdf7fff8000", + "0x48127cfa7fff8000", + "0x48127cfa7fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", @@ -9502,7 +9502,7 @@ "0x1", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x32d", + "0x312", "0x480a7ffb7fff8000", "0x480280067ffd8000", "0x482680017ffd8000", @@ -11304,9 +11304,9 @@ "0x20680017fff7fff", "0x14d", "0x1104800180018000", - "0x1952", + "0x1bbe", "0x482480017fff8000", - "0x1951", + "0x1bbd", "0x480680017fff8000", "0x2", "0x482480017ffe8000", @@ -11388,7 +11388,7 @@ "0x480680017fff8000", "0x0", "0x1104800180018000", - "0xa11", + "0xbd4", "0x402580017fd38005", "0x1", "0x20680017fff7fff", @@ -11407,7 +11407,7 @@ "0x480680017fff8000", "0x1f", "0x1104800180018000", - "0xa1d", + "0xbe0", "0x20680017fff7ffb", "0x70", "0x48127ffa7fff8000", @@ -11420,7 +11420,7 @@ "0x480680017fff8000", "0x1f", "0x1104800180018000", - "0xa10", + "0xbd3", "0x20680017fff7ffb", "0x59", "0x48127ffa7fff8000", @@ -11433,7 +11433,7 @@ "0x480680017fff8000", "0x1f", "0x1104800180018000", - "0xa03", + "0xbc6", "0x20680017fff7ffb", "0x42", "0x48127ffa7fff8000", @@ -11446,7 +11446,7 @@ "0x480680017fff8000", "0x2", "0x1104800180018000", - "0x9f6", + "0xbb9", "0x20680017fff7ffb", "0x2b", "0x40780017fff7fff", @@ -11468,7 +11468,7 @@ "0x482480017ff88000", "0x2", "0x1104800180018000", - "0xe50", + "0x1013", "0x20680017fff7ffd", "0x9", "0x400180007fff8003", @@ -11925,7 +11925,7 @@ "0x480a7ff97fff8000", "0x480a7ffa7fff8000", "0x1104800180018000", - "0xcc9", + "0xe8c", "0x20680017fff7ffc", "0x11", "0x400280007ffc7ffd", @@ -12295,7 +12295,7 @@ "0x480080007ffc8000", "0x480080017ffb8000", "0x1104800180018000", - "0xc07", + "0xdca", "0x20680017fff7ffd", "0xb", "0x48127ffc7fff8000", @@ -12544,7 +12544,7 @@ "0x48127ffa7fff8000", "0x48127ffb7fff8000", "0x1104800180018000", - "0xbab", + "0xd6e", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x1", @@ -12750,7 +12750,7 @@ "0x48127ff27fff8000", "0x48307ffc80007ffd", "0x1104800180018000", - "0xb30", + "0xcf3", "0x484480017f9b8000", "0x20", "0xa0680017fff8000", @@ -13079,7 +13079,7 @@ "0x480a7ffb7fff8000", "0x480a7ffc7fff8000", "0x1104800180018000", - "0xad6", + "0xc99", "0x20680017fff7ffd", "0x3e", "0x20680017fff7ffe", @@ -13090,7 +13090,7 @@ "0x48127ff97fff8000", "0x48127ffb7fff8000", "0x1104800180018000", - "0xd8d", + "0x1112", "0x20680017fff7ffd", "0x1b", "0x48317fff80007ffd", @@ -13188,7 +13188,7 @@ "0x20680017fff7fff", "0x4", "0x10780017fff7fff", - "0x2fd", + "0x4c0", "0x480680017fff8000", "0xffffffff00000000ffffffffffffffff", "0x48317fff80017ffa", @@ -13209,10 +13209,10 @@ "0x10780017fff7fff", "0x7", "0x40780017fff7fff", - "0x2d3", - "0x48127d2b7fff8000", + "0x2b8", + "0x48127d467fff8000", "0x10780017fff7fff", - "0x2e8", + "0x4ab", "0x480680017fff8000", "0xbce6faada7179e84f3b9cac2fc632551", "0x48317fff80017ff9", @@ -13225,11 +13225,11 @@ "0x9", "0x400080007ffb7fff", "0x40780017fff7fff", - "0x2d0", - "0x482480017d2b8000", + "0x2b5", + "0x482480017d468000", "0x1", "0x10780017fff7fff", - "0x2d7", + "0x49a", "0x482480017ffa8000", "0x1", "0x10780017fff7fff", @@ -13322,7 +13322,7 @@ "0x1", "0x48307ffe80007fff", "0x20680017fff7fff", - "0x272", + "0x435", "0x480680017fff8000", "0xbce6faada7179e84f3b9cac2fc632551", "0x480680017fff8000", @@ -13428,7 +13428,7 @@ "0x40317ff97ffb7ffc", "0x40307ffa7ffc7ff1", "0x10780017fff7fff", - "0x1bb", + "0x37e", "0x4824800180008002", "0xffffffffffffffff0000000000000000", "0x480080097fcb8001", @@ -13675,23 +13675,472 @@ "0x480a7ff87fff8000", "0x48127f597fff8000", "0x48127f597fff8000", + "0x1104800180018000", + "0xf8f", "0x480680017fff8000", "0xbce6faada7179e84f3b9cac2fc632551", "0x480680017fff8000", "0xffffffff00000000ffffffffffffffff", - "0x1104800180018000", - "0xc06", - "0x48127ffd7fff8000", + "0x480080007ff98000", + "0x480080017ff88000", + "0x480080027ff78000", + "0x480080037ff68000", + "0x480080047ff58000", + "0x480080057ff48000", + "0x48307fff80007ff9", + "0x40780017fff7fff", + "0xc", + "0x20680017fff7ff3", + "0x8", + "0x40307ff17ff47feb", + "0x402480017ff57ff4", + "0x1", + "0x400080067fe67ff5", + "0x10780017fff7fff", + "0x3", + "0x400080067fe67ff3", + "0x48307ff17ff68000", + "0x48307fe680007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x40507fff7fff7fff", + "0x48307ff47fff8000", + "0x48307ff47fff8000", + "0x48307ff57fff8000", + "0x48307fec7fff8000", + "0x48307fe180007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x400080077fdd7fff", + "0x482480017fff8000", + "0xfffffffffffffffffffffffffffffffc", + "0x400080087fdc7fff", + "0x48307fef7ffe8000", + "0x48307ff07fff8000", + "0x48307ff07fff8000", + "0x48307ff17fff8000", + "0x48307fdb80007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x400080097fd67fff", + "0x482480017fff8000", + "0xfffffffffffffffffffffffffffffffc", + "0x4000800a7fd57fff", + "0xa0680017fff7fdf", + "0xc", + "0xa0680017fff8001", + "0x6", + "0x48127fd97fff7ffe", + "0x40127fdb7fff7ffe", + "0x10780017fff7fff", + "0x10", + "0x48127fdc7fff7ffe", + "0x40127fd87fff7ffe", + "0x10780017fff7fff", + "0xc", + "0x480680017fff7fda", + "0x0", + "0xa0680017fff8000", + "0x6", + "0x40127fd77fff7ffd", + "0x40127fdc7fff7ffe", + "0x10780017fff7fff", + "0x4", + "0x40127fdc7fff7ffd", + "0x40127fd77fff7ffe", + "0x482480017ffd8000", + "0xffffffffffffffff0000000000000000", + "0x4000800b7fd17fff", + "0x48507ffd7ffc8000", + "0x48307fe97ff98000", + "0x48307fe67fff8000", + "0x40307ffd7fff7fd2", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x4800800c7fcd8001", + "0x4800800d7fcc7ffe", + "0x4000800e7fcb7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fd3", + "0x48507fcf7ffc8000", + "0x48507fce7ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x4800800f7fc78001", + "0x480080107fc67fff", + "0x400080117fc57ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080127fc17fff", + "0x480080137fc07ffd", + "0x400080147fbf7fd7", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fd77ffe7fff", + "0x40307ffc7ff77fd8", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080157fbe8001", + "0x480080167fbd7ffe", + "0x400080177fbc7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fc3", + "0x48507fc17ffc8000", + "0x48507fc07ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080187fb88001", + "0x480080197fb77fff", + "0x4000801a7fb67ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x4800801b7fb27fff", + "0x4800801c7fb17ffd", + "0x4000801d7fb07fc6", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fc67ffe7fff", + "0x40307ffc7ff77fc7", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x4800801e7faf8001", + "0x4800801f7fae7ffe", + "0x400080207fad7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fb4", + "0x48507fb17ffc8000", + "0x48507fb07ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080217fa98001", + "0x480080227fa87fff", + "0x400080237fa77ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080247fa37fff", + "0x480080257fa27ffd", + "0x400080267fa17fb3", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fb37ffe7fff", + "0x40307ffc7ff77fb4", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080277fa08001", + "0x480080287f9f7ffe", + "0x400080297f9e7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fa4", + "0x48507fa37ffc8000", + "0x48507fa27ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x4800802a7f9a8001", + "0x4800802b7f997fff", + "0x4000802c7f987ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x4800802d7f947fff", + "0x4800802e7f937ffd", + "0x4000802f7f927fa6", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fa67ffe7fff", + "0x40307ffc7ff77fa7", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080307f918001", + "0x480080317f907ffe", + "0x400080327f8f7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7f95", + "0x48507f937ffc8000", + "0x48507f927ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080337f8b8001", + "0x480080347f8a7fff", + "0x400080357f897ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080367f857fff", + "0x480080377f847ffd", + "0x400080387f837f93", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307f937ffe7fff", + "0x40307ffc7ff77f94", + "0x482480017f838000", + "0x39", "0x480a7ff97fff8000", "0x480a7ffa7fff8000", - "0x48127e5d7fff8000", - "0x48127e5d7fff8000", + "0x48127e6b7fff8000", + "0x48127e6b7fff8000", + "0x1104800180018000", + "0xea3", "0x480680017fff8000", "0xbce6faada7179e84f3b9cac2fc632551", "0x480680017fff8000", "0xffffffff00000000ffffffffffffffff", - "0x1104800180018000", - "0xbfb", + "0x480080007ff98000", + "0x480080017ff88000", + "0x480080027ff78000", + "0x480080037ff68000", + "0x480080047ff58000", + "0x480080057ff48000", + "0x48307fff80007ff9", + "0x40780017fff7fff", + "0xc", + "0x20680017fff7ff3", + "0x8", + "0x40307ff17ff47feb", + "0x402480017ff57ff4", + "0x1", + "0x400080067fe67ff5", + "0x10780017fff7fff", + "0x3", + "0x400080067fe67ff3", + "0x48307ff17ff68000", + "0x48307fe680007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x40507fff7fff7fff", + "0x48307ff47fff8000", + "0x48307ff47fff8000", + "0x48307ff57fff8000", + "0x48307fec7fff8000", + "0x48307fe180007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x400080077fdd7fff", + "0x482480017fff8000", + "0xfffffffffffffffffffffffffffffffc", + "0x400080087fdc7fff", + "0x48307fef7ffe8000", + "0x48307ff07fff8000", + "0x48307ff07fff8000", + "0x48307ff17fff8000", + "0x48307fdb80007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x400080097fd67fff", + "0x482480017fff8000", + "0xfffffffffffffffffffffffffffffffc", + "0x4000800a7fd57fff", + "0xa0680017fff7fdf", + "0xc", + "0xa0680017fff8001", + "0x6", + "0x48127fd97fff7ffe", + "0x40127fdb7fff7ffe", + "0x10780017fff7fff", + "0x10", + "0x48127fdc7fff7ffe", + "0x40127fd87fff7ffe", + "0x10780017fff7fff", + "0xc", + "0x480680017fff7fda", + "0x0", + "0xa0680017fff8000", + "0x6", + "0x40127fd77fff7ffd", + "0x40127fdc7fff7ffe", + "0x10780017fff7fff", + "0x4", + "0x40127fdc7fff7ffd", + "0x40127fd77fff7ffe", + "0x482480017ffd8000", + "0xffffffffffffffff0000000000000000", + "0x4000800b7fd17fff", + "0x48507ffd7ffc8000", + "0x48307fe97ff98000", + "0x48307fe67fff8000", + "0x40307ffd7fff7fd2", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x4800800c7fcd8001", + "0x4800800d7fcc7ffe", + "0x4000800e7fcb7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fd3", + "0x48507fcf7ffc8000", + "0x48507fce7ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x4800800f7fc78001", + "0x480080107fc67fff", + "0x400080117fc57ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080127fc17fff", + "0x480080137fc07ffd", + "0x400080147fbf7fd7", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fd77ffe7fff", + "0x40307ffc7ff77fd8", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080157fbe8001", + "0x480080167fbd7ffe", + "0x400080177fbc7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fc3", + "0x48507fc17ffc8000", + "0x48507fc07ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080187fb88001", + "0x480080197fb77fff", + "0x4000801a7fb67ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x4800801b7fb27fff", + "0x4800801c7fb17ffd", + "0x4000801d7fb07fc6", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fc67ffe7fff", + "0x40307ffc7ff77fc7", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x4800801e7faf8001", + "0x4800801f7fae7ffe", + "0x400080207fad7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fb4", + "0x48507fb17ffc8000", + "0x48507fb07ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080217fa98001", + "0x480080227fa87fff", + "0x400080237fa77ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080247fa37fff", + "0x480080257fa27ffd", + "0x400080267fa17fb3", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fb37ffe7fff", + "0x40307ffc7ff77fb4", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080277fa08001", + "0x480080287f9f7ffe", + "0x400080297f9e7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fa4", + "0x48507fa37ffc8000", + "0x48507fa27ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x4800802a7f9a8001", + "0x4800802b7f997fff", + "0x4000802c7f987ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x4800802d7f947fff", + "0x4800802e7f937ffd", + "0x4000802f7f927fa6", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fa67ffe7fff", + "0x40307ffc7ff77fa7", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080307f918001", + "0x480080317f907ffe", + "0x400080327f8f7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7f95", + "0x48507f937ffc8000", + "0x48507f927ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080337f8b8001", + "0x480080347f8a7fff", + "0x400080357f897ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080367f857fff", + "0x480080377f847ffd", + "0x400080387f837f93", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307f937ffe7fff", + "0x40307ffc7ff77f94", "0x480680017fff8000", "0x77037d812deb33a0f4a13945d898c296", "0x480680017fff8000", @@ -13700,14 +14149,16 @@ "0x2bce33576b315ececbb6406837bf51f5", "0x480680017fff8000", "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e16", + "0x482480017f7f8000", + "0x39", "0x480680017fff8000", "0x5365637032353672314e6577", "0x400280007ff67fff", "0x400380017ff67ff5", - "0x400280027ff67ffb", - "0x400280037ff67ffc", - "0x400280047ff67ffd", - "0x400280057ff67ffe", + "0x400280027ff67ffa", + "0x400280037ff67ffb", + "0x400280047ff67ffc", + "0x400280057ff67ffd", "0x480280077ff68000", "0x20680017fff7fff", "0x92", @@ -13723,8 +14174,8 @@ "0x400080007ffe7fff", "0x400080017ffe7ffd", "0x400080027ffe7ffc", - "0x400080037ffe7ef7", - "0x400080047ffe7ef8", + "0x400080037ffe7e94", + "0x400080047ffe7e95", "0x480080067ffe8000", "0x20680017fff7fff", "0x68", @@ -13735,8 +14186,8 @@ "0x400080087ffa7fff", "0x400080097ffa7ffd", "0x4001800a7ffa7ffd", - "0x4000800b7ffa7fef", - "0x4000800c7ffa7ff0", + "0x4000800b7ffa7f7e", + "0x4000800c7ffa7f7f", "0x4800800e7ffa8000", "0x20680017fff7fff", "0x51", @@ -13788,7 +14239,7 @@ "0x4", "0x480680017fff8000", "0x1", - "0x48127fde7fff8000", + "0x48127fe47fff8000", "0x48127ffa7fff8000", "0x48127ffa7fff8000", "0x480680017fff8000", @@ -13799,7 +14250,7 @@ "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x7", - "0x48127fde7fff8000", + "0x48127fe47fff8000", "0x4800801a7fe98000", "0x482480017fe88000", "0x1e", @@ -13810,7 +14261,7 @@ "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0xb", - "0x48127fde7fff8000", + "0x48127fe47fff8000", "0x480080147fe98000", "0x482480017fe88000", "0x18", @@ -13821,7 +14272,7 @@ "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0xf", - "0x48127fde7fff8000", + "0x48127fe47fff8000", "0x4800800d7fe98000", "0x482480017fe88000", "0x11", @@ -13832,7 +14283,7 @@ "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x13", - "0x48127fde7fff8000", + "0x48127fe47fff8000", "0x480080057fe98000", "0x482480017fe88000", "0x9", @@ -13862,7 +14313,7 @@ "0xa", "0x480280087ff68000", "0x480280097ff68000", - "0x48127fde7fff8000", + "0x48127fe47fff8000", "0x48127ffb7fff8000", "0x48127ffb7fff8000", "0x480680017fff8000", @@ -13871,22 +14322,22 @@ "0x48127ffa7fff8000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x28f", + "0x274", "0x4824800180008002", "0xffffffffffffffff0000000000000000", - "0x480080077d5c8001", - "0x480080087d5b7ffe", - "0x400080097d5a7ffe", + "0x480080077d778001", + "0x480080087d767ffe", + "0x400080097d757ffe", "0x484480017ffe8000", "0x10000000000000000", - "0x40307ffc7fff7d5f", - "0x48507d637ffc8000", - "0x48507d627ffc8000", + "0x40307ffc7fff7d7a", + "0x48507d7e7ffc8000", + "0x48507d7d7ffc8000", "0x4824800180018002", "0xffffffffffffffff0000000000000000", - "0x4800800a7d568001", - "0x4800800b7d557fff", - "0x4000800c7d547ffd", + "0x4800800a7d718001", + "0x4800800b7d707fff", + "0x4000800c7d6f7ffd", "0x484480017ffd8000", "0x10000000000000000", "0x40307ffd7fff7ffb", @@ -13895,28 +14346,28 @@ "0x48307fff7ff98003", "0x482480017fff8000", "0xfffffffffffffffe0000000000000000", - "0x4800800d7d507fff", - "0x4800800e7d4f7ffd", - "0x4000800f7d4e7d52", + "0x4800800d7d6b7fff", + "0x4800800e7d6a7ffd", + "0x4000800f7d697d6d", "0x404480017ffc7ffe", "0x100000000000000000000000000000000", - "0x40307d527ffe7fff", - "0x40307ffc7ff77d5c", + "0x40307d6d7ffe7fff", + "0x40307ffc7ff77d77", "0x4824800180008002", "0xffffffffffffffff0000000000000000", - "0x480080107d4d8001", - "0x480080117d4c7ffe", - "0x400080127d4b7ffe", + "0x480080107d688001", + "0x480080117d677ffe", + "0x400080127d667ffe", "0x484480017ffe8000", "0x10000000000000000", - "0x40307ffc7fff7d50", - "0x48507d527ffc8000", - "0x48507d517ffc8000", + "0x40307ffc7fff7d6b", + "0x48507d6d7ffc8000", + "0x48507d6c7ffc8000", "0x4824800180018002", "0xffffffffffffffff0000000000000000", - "0x480080137d478001", - "0x480080147d467fff", - "0x400080157d457ffd", + "0x480080137d628001", + "0x480080147d617fff", + "0x400080157d607ffd", "0x484480017ffd8000", "0x10000000000000000", "0x40307ffd7fff7ffb", @@ -13925,19 +14376,19 @@ "0x48307fff7ff98003", "0x482480017fff8000", "0xfffffffffffffffe0000000000000000", - "0x480080167d417fff", - "0x480080177d407ffd", - "0x400180187d3f7ffb", + "0x480080167d5c7fff", + "0x480080177d5b7ffd", + "0x400180187d5a7ffb", "0x404480017ffc7ffe", "0x100000000000000000000000000000000", "0x40287ffb7ffe7fff", - "0x40307ffc7ff77d4c", + "0x40307ffc7ff77d67", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x4f7074696f6e3a3a756e77726170206661696c65642e", "0x400080007ffe7fff", - "0x482480017d3d8000", + "0x482480017d588000", "0x19", "0x480a7ff57fff8000", "0x480a7ff67fff8000", @@ -13948,12 +14399,12 @@ "0x1", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x2bf", - "0x48127d3d7fff8000", + "0x2a4", + "0x48127d587fff8000", "0x10780017fff7fff", "0x5", "0x40780017fff7fff", - "0x2d8", + "0x2bd", "0x480a7ff47fff8000", "0x480a7ff57fff8000", "0x480a7ff67fff8000", @@ -14115,7 +14566,7 @@ "0x1", "0x48127ffe7fff8000", "0x1104800180018000", - "0xc7b", + "0xd24", "0x20680017fff7ffd", "0xb7", "0x20680017fff7fff", @@ -14190,7 +14641,7 @@ "0x7", "0x48127ffe7fff8000", "0x1104800180018000", - "0xc30", + "0xcd9", "0x20680017fff7ffd", "0x7", "0x48127ffc7fff8000", @@ -14225,7 +14676,7 @@ "0x6", "0x48127ff67fff8000", "0x1104800180018000", - "0xc0d", + "0xcb6", "0x20680017fff7ffd", "0x34", "0x48127ffc7fff8000", @@ -14367,7 +14818,7 @@ "0x48127ffd7fff8000", "0x48127fef7fff8000", "0x1104800180018000", - "0xb7f", + "0xc28", "0x20680017fff7ffd", "0xdd", "0x20680017fff7fff", @@ -14417,7 +14868,7 @@ "0x5", "0x48127ffe7fff8000", "0x1104800180018000", - "0xb4d", + "0xbf6", "0x20680017fff7ffd", "0x96", "0x480680017fff8000", @@ -14459,7 +14910,7 @@ "0x3", "0x48127ffe7fff8000", "0x1104800180018000", - "0xb23", + "0xbcc", "0x20680017fff7ffd", "0x7", "0x48127ffc7fff8000", @@ -14494,7 +14945,7 @@ "0x2", "0x48127ff67fff8000", "0x1104800180018000", - "0xb00", + "0xba9", "0x20680017fff7ffd", "0x34", "0x48127ffc7fff8000", @@ -14679,7 +15130,7 @@ "0x3", "0x48127ffe7fff8000", "0x1104800180018000", - "0xa47", + "0xaf0", "0x20680017fff7ffd", "0x7", "0x48127ffc7fff8000", @@ -14714,7 +15165,7 @@ "0x2", "0x48127ff87fff8000", "0x1104800180018000", - "0xa24", + "0xacd", "0x20680017fff7ffd", "0x3a", "0x48127ffc7fff8000", @@ -14849,7 +15300,7 @@ "0x2", "0x48127ffe7fff8000", "0x1104800180018000", - "0x99d", + "0xa46", "0x20680017fff7ffd", "0x7", "0x48127ffc7fff8000", @@ -14884,7 +15335,7 @@ "0x1", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x97a", + "0xa23", "0x20680017fff7ffd", "0x3c", "0x48127ffc7fff8000", @@ -14996,7 +15447,7 @@ "0x2", "0x48127ffe7fff8000", "0x1104800180018000", - "0x90a", + "0x9b3", "0x20680017fff7ffd", "0x7", "0x48127ffc7fff8000", @@ -15031,7 +15482,7 @@ "0x1", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x8e7", + "0x990", "0x20680017fff7ffd", "0x2d", "0x48127ffc7fff8000", @@ -15861,14 +16312,14 @@ "0x400380047ff67ffd", "0x480280067ff68000", "0x20680017fff7fff", - "0x2af", + "0x471", "0x480280077ff68000", "0x480280087ff68000", "0x480280057ff68000", "0x482680017ff68000", "0x9", "0x20680017fff7ffc", - "0x29c", + "0x45e", "0x480680017fff8000", "0x29bfcdb2dce28d959f2815b16f81798", "0x480680017fff8000", @@ -15887,14 +16338,14 @@ "0x400080057ffa7ffe", "0x480080077ffa8000", "0x20680017fff7fff", - "0x27a", + "0x43c", "0x480080087ff98000", "0x480080097ff88000", "0x480080067ff78000", "0x482480017ff68000", "0xa", "0x20680017fff7ffc", - "0x265", + "0x427", "0x480680017fff8000", "0xbaaedce6af48a03bbfd25e8cd0364141", "0x480680017fff8000", @@ -16000,7 +16451,7 @@ "0x40317ff97ffb7ffa", "0x40307ffa7ffc7ff1", "0x10780017fff7fff", - "0x1ae", + "0x370", "0x4824800180008002", "0xffffffffffffffff0000000000000000", "0x480280097ff48001", @@ -16247,40 +16698,264 @@ "0x480a7ff87fff8000", "0x48127f597fff8000", "0x48127f597fff8000", + "0x1104800180018000", + "0x3c0", "0x480680017fff8000", "0xbaaedce6af48a03bbfd25e8cd0364141", "0x480680017fff8000", "0xfffffffffffffffffffffffffffffffe", - "0x1104800180018000", - "0x1fa", + "0x480080007ff98000", + "0x480080017ff88000", + "0x480080027ff78000", + "0x480080037ff68000", + "0x480080047ff58000", + "0x480080057ff48000", + "0x48307fff80007ff9", + "0x40780017fff7fff", + "0xc", + "0x20680017fff7ff3", + "0x8", + "0x40307ff17ff47feb", + "0x402480017ff57ff4", + "0x1", + "0x400080067fe67ff5", + "0x10780017fff7fff", + "0x3", + "0x400080067fe67ff3", + "0x48307ff17ff68000", + "0x48307fe680007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x40507fff7fff7fff", + "0x48307ff47fff8000", + "0x48307ff47fff8000", + "0x48307ff57fff8000", + "0x48307fec7fff8000", + "0x48307fe180007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x400080077fdd7fff", + "0x482480017fff8000", + "0xfffffffffffffffffffffffffffffffc", + "0x400080087fdc7fff", + "0x48307fef7ffe8000", + "0x48307ff07fff8000", + "0x48307ff07fff8000", + "0x48307ff17fff8000", + "0x48307fdb80007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x400080097fd67fff", + "0x482480017fff8000", + "0xfffffffffffffffffffffffffffffffc", + "0x4000800a7fd57fff", + "0xa0680017fff7fdf", + "0xc", + "0xa0680017fff8001", + "0x6", + "0x48127fd97fff7ffe", + "0x40127fdb7fff7ffe", + "0x10780017fff7fff", + "0x10", + "0x48127fdc7fff7ffe", + "0x40127fd87fff7ffe", + "0x10780017fff7fff", + "0xc", + "0x480680017fff7fda", + "0x0", + "0xa0680017fff8000", + "0x6", + "0x40127fd77fff7ffd", + "0x40127fdc7fff7ffe", + "0x10780017fff7fff", + "0x4", + "0x40127fdc7fff7ffd", + "0x40127fd77fff7ffe", + "0x482480017ffd8000", + "0xffffffffffffffff0000000000000000", + "0x4000800b7fd17fff", + "0x48507ffd7ffc8000", + "0x48307fe97ff98000", + "0x48307fe67fff8000", + "0x40307ffd7fff7fd2", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x4800800c7fcd8001", + "0x4800800d7fcc7ffe", + "0x4000800e7fcb7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fd3", + "0x48507fcf7ffc8000", + "0x48507fce7ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x4800800f7fc78001", + "0x480080107fc67fff", + "0x400080117fc57ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080127fc17fff", + "0x480080137fc07ffd", + "0x400080147fbf7fd7", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fd77ffe7fff", + "0x40307ffc7ff77fd8", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080157fbe8001", + "0x480080167fbd7ffe", + "0x400080177fbc7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fc3", + "0x48507fc17ffc8000", + "0x48507fc07ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080187fb88001", + "0x480080197fb77fff", + "0x4000801a7fb67ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x4800801b7fb27fff", + "0x4800801c7fb17ffd", + "0x4000801d7fb07fc6", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fc67ffe7fff", + "0x40307ffc7ff77fc7", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x4800801e7faf8001", + "0x4800801f7fae7ffe", + "0x400080207fad7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fb4", + "0x48507fb17ffc8000", + "0x48507fb07ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080217fa98001", + "0x480080227fa87fff", + "0x400080237fa77ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080247fa37fff", + "0x480080257fa27ffd", + "0x400080267fa17fb3", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fb37ffe7fff", + "0x40307ffc7ff77fb4", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080277fa08001", + "0x480080287f9f7ffe", + "0x400080297f9e7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fa4", + "0x48507fa37ffc8000", + "0x48507fa27ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x4800802a7f9a8001", + "0x4800802b7f997fff", + "0x4000802c7f987ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x4800802d7f947fff", + "0x4800802e7f937ffd", + "0x4000802f7f927fa6", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fa67ffe7fff", + "0x40307ffc7ff77fa7", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080307f918001", + "0x480080317f907ffe", + "0x400080327f8f7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7f95", + "0x48507f937ffc8000", + "0x48507f927ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080337f8b8001", + "0x480080347f8a7fff", + "0x400080357f897ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080367f857fff", + "0x480080377f847ffd", + "0x400080387f837f93", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307f937ffe7fff", + "0x40307ffc7ff77f94", "0x480680017fff8000", "0xfffffffffffffffffffffffffffffffe", - "0x48307ffe80017fff", + "0x48307f8e80017fff", "0xa0680017fff7fff", "0x7", "0x482480017fff8000", "0x100000000000000000000000000000000", - "0x400080007ff97fff", + "0x400080397f7f7fff", "0x10780017fff7fff", "0xc", - "0x400080007ffa7fff", + "0x400080397f807fff", "0x40780017fff7fff", "0x1", - "0x482480017ff98000", - "0x1", + "0x482480017f7f8000", + "0x3a", "0x48127ffd7fff8000", "0x480680017fff8000", "0x0", "0x10780017fff7fff", "0x7", - "0x482480017ff98000", - "0x1", + "0x482480017f7f8000", + "0x3a", "0x48127ffe7fff8000", "0x480680017fff8000", "0x1", "0x480680017fff8000", "0xbaaedce6af48a03bbfd25e8cd0364141", - "0x48307ff680017fff", + "0x48307f8680017fff", "0xa0680017fff7fff", "0x7", "0x482480017fff8000", @@ -16325,104 +17000,330 @@ "0x480680017fff8000", "0x1", "0x20680017fff7fff", - "0x59", + "0x13b", "0x48127ffc7fff8000", "0x480a7ffb7fff8000", "0x480a7ffc7fff8000", - "0x48127e4a7fff8000", - "0x48127e4a7fff8000", + "0x48127e587fff8000", + "0x48127e587fff8000", + "0x1104800180018000", + "0x28c", "0x480680017fff8000", "0xbaaedce6af48a03bbfd25e8cd0364141", "0x480680017fff8000", "0xfffffffffffffffffffffffffffffffe", - "0x1104800180018000", - "0x1a6", - "0x48127f017fff8000", - "0x48127f017fff8000", + "0x480080007ff98000", + "0x480080017ff88000", + "0x480080027ff78000", + "0x480080037ff68000", + "0x480080047ff58000", + "0x480080057ff48000", + "0x48307fff80007ff9", + "0x40780017fff7fff", + "0xc", + "0x20680017fff7ff3", + "0x8", + "0x40307ff17ff47feb", + "0x402480017ff57ff4", + "0x1", + "0x400080067fe67ff5", + "0x10780017fff7fff", + "0x3", + "0x400080067fe67ff3", + "0x48307ff17ff68000", + "0x48307fe680007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x40507fff7fff7fff", + "0x48307ff47fff8000", + "0x48307ff47fff8000", + "0x48307ff57fff8000", + "0x48307fec7fff8000", + "0x48307fe180007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x400080077fdd7fff", + "0x482480017fff8000", + "0xfffffffffffffffffffffffffffffffc", + "0x400080087fdc7fff", + "0x48307fef7ffe8000", + "0x48307ff07fff8000", + "0x48307ff07fff8000", + "0x48307ff17fff8000", + "0x48307fdb80007fff", + "0x4844800180007fff", + "0x100000000000000000000000000000000", + "0x400080097fd67fff", + "0x482480017fff8000", + "0xfffffffffffffffffffffffffffffffc", + "0x4000800a7fd57fff", + "0xa0680017fff7fdf", + "0xc", + "0xa0680017fff8001", + "0x6", + "0x48127fd97fff7ffe", + "0x40127fdb7fff7ffe", + "0x10780017fff7fff", + "0x10", + "0x48127fdc7fff7ffe", + "0x40127fd87fff7ffe", + "0x10780017fff7fff", + "0xc", + "0x480680017fff7fda", + "0x0", + "0xa0680017fff8000", + "0x6", + "0x40127fd77fff7ffd", + "0x40127fdc7fff7ffe", + "0x10780017fff7fff", + "0x4", + "0x40127fdc7fff7ffd", + "0x40127fd77fff7ffe", + "0x482480017ffd8000", + "0xffffffffffffffff0000000000000000", + "0x4000800b7fd17fff", + "0x48507ffd7ffc8000", + "0x48307fe97ff98000", + "0x48307fe67fff8000", + "0x40307ffd7fff7fd2", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x4800800c7fcd8001", + "0x4800800d7fcc7ffe", + "0x4000800e7fcb7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fd3", + "0x48507fcf7ffc8000", + "0x48507fce7ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x4800800f7fc78001", + "0x480080107fc67fff", + "0x400080117fc57ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080127fc17fff", + "0x480080137fc07ffd", + "0x400080147fbf7fd7", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fd77ffe7fff", + "0x40307ffc7ff77fd8", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080157fbe8001", + "0x480080167fbd7ffe", + "0x400080177fbc7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fc3", + "0x48507fc17ffc8000", + "0x48507fc07ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080187fb88001", + "0x480080197fb77fff", + "0x4000801a7fb67ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x4800801b7fb27fff", + "0x4800801c7fb17ffd", + "0x4000801d7fb07fc6", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fc67ffe7fff", + "0x40307ffc7ff77fc7", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x4800801e7faf8001", + "0x4800801f7fae7ffe", + "0x400080207fad7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fb4", + "0x48507fb17ffc8000", + "0x48507fb07ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080217fa98001", + "0x480080227fa87fff", + "0x400080237fa77ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080247fa37fff", + "0x480080257fa27ffd", + "0x400080267fa17fb3", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fb37ffe7fff", + "0x40307ffc7ff77fb4", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080277fa08001", + "0x480080287f9f7ffe", + "0x400080297f9e7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7fa4", + "0x48507fa37ffc8000", + "0x48507fa27ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x4800802a7f9a8001", + "0x4800802b7f997fff", + "0x4000802c7f987ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x4800802d7f947fff", + "0x4800802e7f937ffd", + "0x4000802f7f927fa6", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307fa67ffe7fff", + "0x40307ffc7ff77fa7", + "0x4824800180008002", + "0xffffffffffffffff0000000000000000", + "0x480080307f918001", + "0x480080317f907ffe", + "0x400080327f8f7ffe", + "0x484480017ffe8000", + "0x10000000000000000", + "0x40307ffc7fff7f95", + "0x48507f937ffc8000", + "0x48507f927ffc8000", + "0x4824800180018002", + "0xffffffffffffffff0000000000000000", + "0x480080337f8b8001", + "0x480080347f8a7fff", + "0x400080357f897ffd", + "0x484480017ffd8000", + "0x10000000000000000", + "0x40307ffd7fff7ffb", + "0x484480017ffd8000", + "0x10000000000000000", + "0x48307fff7ff98003", + "0x482480017fff8000", + "0xfffffffffffffffe0000000000000000", + "0x480080367f857fff", + "0x480080377f847ffd", + "0x400080387f837f93", + "0x404480017ffc7ffe", + "0x100000000000000000000000000000000", + "0x40307f937ffe7fff", + "0x40307ffc7ff77f94", + "0x48127f0f7fff8000", + "0x48127f0f7fff8000", + "0x482480017f818000", + "0x39", "0x480680017fff8000", "0x536563703235366b314d756c", - "0x400080007d497fff", - "0x400080017d497d48", - "0x400080027d497d47", - "0x400080037d497ffd", - "0x400080047d497ffe", - "0x480080067d498000", + "0x400080007d647fff", + "0x400080017d647d63", + "0x400080027d647d62", + "0x400080037d647ffc", + "0x400080047d647ffd", + "0x480080067d648000", "0x20680017fff7fff", "0x37", - "0x480080057d488000", - "0x480080077d478000", + "0x480080057d638000", + "0x480080077d628000", "0x480680017fff8000", "0x536563703235366b314d756c", - "0x400080087d457fff", - "0x400080097d457ffd", - "0x4000800a7d457d39", - "0x4000800b7d457ff7", - "0x4000800c7d457ff8", - "0x4800800e7d458000", + "0x400080087d607fff", + "0x400080097d607ffd", + "0x4000800a7d607d54", + "0x4000800b7d607f86", + "0x4000800c7d607f87", + "0x4800800e7d608000", "0x20680017fff7fff", "0x20", - "0x4800800d7d448000", - "0x4800800f7d438000", + "0x4800800d7d5f8000", + "0x4800800f7d5e8000", "0x480680017fff8000", "0x536563703235366b31416464", - "0x400080107d417fff", - "0x400080117d417ffd", - "0x400080127d417ffa", - "0x400080137d417ffe", - "0x480080157d418000", + "0x400080107d5c7fff", + "0x400080117d5c7ffd", + "0x400080127d5c7ffa", + "0x400080137d5c7ffe", + "0x480080157d5c8000", "0x20680017fff7fff", "0xc", - "0x48127ff17fff8000", - "0x480080147d3f8000", - "0x482480017d3e8000", + "0x48127ff57fff8000", + "0x480080147d5a8000", + "0x482480017d598000", "0x17", "0x480680017fff8000", "0x0", "0x480680017fff8000", "0x0", - "0x480080167d3b8000", + "0x480080167d568000", "0x208b7fff7fff7ffe", - "0x48127ff17fff8000", - "0x480080147d3f8000", - "0x482480017d3e8000", + "0x48127ff57fff8000", + "0x480080147d5a8000", + "0x482480017d598000", "0x18", "0x480680017fff8000", "0x1", - "0x480080167d3c8000", - "0x480080177d3b8000", + "0x480080167d578000", + "0x480080177d568000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x4", - "0x48127ff17fff8000", - "0x4800800d7d3f8000", - "0x482480017d3e8000", + "0x48127ff57fff8000", + "0x4800800d7d5a8000", + "0x482480017d598000", "0x11", "0x480680017fff8000", "0x1", - "0x4800800f7d3c8000", - "0x480080107d3b8000", + "0x4800800f7d578000", + "0x480080107d568000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x8", - "0x48127ff17fff8000", - "0x480080057d3f8000", - "0x482480017d3e8000", + "0x48127ff57fff8000", + "0x480080057d5a8000", + "0x482480017d598000", "0x9", "0x480680017fff8000", "0x1", - "0x480080077d3c8000", - "0x480080087d3b8000", + "0x480080077d578000", + "0x480080087d568000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x106", + "0xf9", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x753235365f737562204f766572666c6f77", "0x400080007ffe7fff", - "0x48127ef47fff8000", - "0x48127d3e7fff8000", - "0x48127d3e7fff8000", + "0x48127f017fff8000", + "0x48127d597fff8000", + "0x48127d597fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", @@ -16430,7 +17331,7 @@ "0x1", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x28f", + "0x274", "0x4824800180008002", "0xffffffffffffffff0000000000000000", "0x480280077ff48001", @@ -16438,9 +17339,9 @@ "0x400280097ff47ffe", "0x484480017ffe8000", "0x10000000000000000", - "0x40307ffc7fff7d5f", - "0x48507d637ffc8000", - "0x48507d627ffc8000", + "0x40307ffc7fff7d7a", + "0x48507d7e7ffc8000", + "0x48507d7d7ffc8000", "0x4824800180018002", "0xffffffffffffffff0000000000000000", "0x4802800a7ff48001", @@ -16456,11 +17357,11 @@ "0xfffffffffffffffe0000000000000000", "0x4802800d7ff47fff", "0x4802800e7ff47ffd", - "0x4002800f7ff47d52", + "0x4002800f7ff47d6d", "0x404480017ffc7ffe", "0x100000000000000000000000000000000", - "0x40307d527ffe7fff", - "0x40307ffc7ff77d5c", + "0x40307d6d7ffe7fff", + "0x40307ffc7ff77d77", "0x4824800180008002", "0xffffffffffffffff0000000000000000", "0x480280107ff48001", @@ -16468,9 +17369,9 @@ "0x400280127ff47ffe", "0x484480017ffe8000", "0x10000000000000000", - "0x40307ffc7fff7d50", - "0x48507d527ffc8000", - "0x48507d517ffc8000", + "0x40307ffc7fff7d6b", + "0x48507d6d7ffc8000", + "0x48507d6c7ffc8000", "0x4824800180018002", "0xffffffffffffffff0000000000000000", "0x480280137ff48001", @@ -16490,7 +17391,7 @@ "0x404480017ffc7ffe", "0x100000000000000000000000000000000", "0x40287ff97ffe7fff", - "0x40307ffc7ff77d4c", + "0x40307ffc7ff77d67", "0x40780017fff7fff", "0x1", "0x480680017fff8000", @@ -16498,8 +17399,8 @@ "0x400080007ffe7fff", "0x482680017ff48000", "0x19", - "0x48127d3e7fff8000", - "0x48127d3e7fff8000", + "0x48127d597fff8000", + "0x48127d597fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", @@ -16507,26 +17408,26 @@ "0x1", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x2b9", + "0x29e", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x4f7074696f6e3a3a756e77726170206661696c65642e", "0x400080007ffe7fff", - "0x48127d437fff8000", - "0x48127d437fff8000", + "0x48127d5e7fff8000", + "0x48127d5e7fff8000", "0x48127ffc7fff8000", "0x482480017ffb8000", "0x1", "0x10780017fff7fff", "0x9", "0x40780017fff7fff", - "0x2bf", - "0x480080067d3a8000", - "0x482480017d398000", + "0x2a4", + "0x480080067d558000", + "0x482480017d548000", "0xa", - "0x480080087d388000", - "0x480080097d378000", + "0x480080087d538000", + "0x480080097d528000", "0x480a7ff47fff8000", "0x48127ffb7fff8000", "0x48127ffb7fff8000", @@ -16536,10 +17437,10 @@ "0x48127ffa7fff8000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x2c9", + "0x2ae", "0x480a7ff47fff8000", - "0x48127d347fff8000", - "0x48127d347fff8000", + "0x48127d4f7fff8000", + "0x48127d4f7fff8000", "0x480680017fff8000", "0x0", "0x480680017fff8000", @@ -16548,7 +17449,7 @@ "0x0", "0x208b7fff7fff7ffe", "0x40780017fff7fff", - "0x2cd", + "0x2b2", "0x480a7ff47fff8000", "0x480280057ff68000", "0x482680017ff68000", @@ -16589,7 +17490,7 @@ "0x402780017ffc8001", "0x9", "0x1104800180018000", - "0x354", + "0x23b", "0x40137ffa7fff8000", "0x20680017fff7ffb", "0x8e", @@ -16602,7 +17503,7 @@ "0x480680017fff8000", "0x0", "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffef61", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffebdc", "0x20680017fff7ffd", "0x7b", "0x480680017fff8000", @@ -16761,19 +17662,19 @@ "0x2", "0x4824800180008002", "0xffffffffffffffff0000000000000000", - "0x480280007ff78001", - "0x480280017ff77ffe", - "0x400280027ff77ffe", + "0x480280007ff98001", + "0x480280017ff97ffe", + "0x400280027ff97ffe", "0x484480017ffe8000", "0x10000000000000000", - "0x40317ffc7fff7ff8", - "0x48487ffa7ffc8000", - "0x48487ffa7ffc8000", + "0x40317ffc7fff7ffa", + "0x48487ffc7ffc8000", + "0x48487ffc7ffc8000", "0x4824800180018002", "0xffffffffffffffff0000000000000000", - "0x480280037ff78001", - "0x480280047ff77fff", - "0x400280057ff77ffd", + "0x480280037ff98001", + "0x480280047ff97fff", + "0x400280057ff97ffd", "0x484480017ffd8000", "0x10000000000000000", "0x40307ffd7fff7ffb", @@ -16782,9 +17683,9 @@ "0x48307fff7ff98003", "0x482480017fff8000", "0xfffffffffffffffe0000000000000000", - "0x480280067ff77fff", - "0x480280077ff77ffd", - "0x400280087ff77ff0", + "0x480280067ff97fff", + "0x480280077ff97ffd", + "0x400280087ff97ff0", "0x404480017ffc7ffe", "0x100000000000000000000000000000000", "0x40307ff07ffe7fff", @@ -16793,19 +17694,19 @@ "0x2", "0x4824800180008002", "0xffffffffffffffff0000000000000000", - "0x480280097ff78001", - "0x4802800a7ff77ffe", - "0x4002800b7ff77ffe", + "0x480280097ff98001", + "0x4802800a7ff97ffe", + "0x4002800b7ff97ffe", "0x484480017ffe8000", "0x10000000000000000", - "0x40317ffc7fff7ff8", - "0x48487ffb7ffc8000", - "0x48487ffb7ffc8000", + "0x40317ffc7fff7ffa", + "0x48487ffd7ffc8000", + "0x48487ffd7ffc8000", "0x4824800180018002", "0xffffffffffffffff0000000000000000", - "0x4802800c7ff78001", - "0x4802800d7ff77fff", - "0x4002800e7ff77ffd", + "0x4802800c7ff98001", + "0x4802800d7ff97fff", + "0x4002800e7ff97ffd", "0x484480017ffd8000", "0x10000000000000000", "0x40307ffd7fff7ffb", @@ -16814,9 +17715,9 @@ "0x48307fff7ff98003", "0x482480017fff8000", "0xfffffffffffffffe0000000000000000", - "0x4802800f7ff77fff", - "0x480280107ff77ffd", - "0x400280117ff77ff0", + "0x4802800f7ff97fff", + "0x480280107ff97ffd", + "0x400280117ff97ff0", "0x404480017ffc7ffe", "0x100000000000000000000000000000000", "0x40307ff07ffe7fff", @@ -16826,20 +17727,20 @@ "0x7", "0x4824800180007fff", "0x100000000000000000000000000000000", - "0x400280127ff77fff", + "0x400280127ff97fff", "0x10780017fff7fff", "0xc", - "0x400280127ff77fff", + "0x400280127ff97fff", "0x40780017fff7fff", "0x1", - "0x482680017ff78000", + "0x482680017ff98000", "0x13", "0x48127ffd7fff8000", "0x480680017fff8000", "0x0", "0x10780017fff7fff", "0x7", - "0x482680017ff78000", + "0x482680017ff98000", "0x13", "0x48127ffe7fff8000", "0x480680017fff8000", @@ -16853,9 +17754,9 @@ "0x400080027ff87ffe", "0x484480017ffe8000", "0x10000000000000000", - "0x40317ffc7fff7ff9", - "0x48487ffa7ffc8000", - "0x48487ffa7ffc8000", + "0x40317ffc7fff7ffb", + "0x48487ffc7ffc8000", + "0x48487ffc7ffc8000", "0x4824800180018002", "0xffffffffffffffff0000000000000000", "0x480080037ff48001", @@ -16931,9 +17832,9 @@ "0x400080027ff87ffe", "0x484480017ffe8000", "0x10000000000000000", - "0x40317ffc7fff7ff9", - "0x48487ffb7ffc8000", - "0x48487ffb7ffc8000", + "0x40317ffc7fff7ffb", + "0x48487ffd7ffc8000", + "0x48487ffd7ffc8000", "0x4824800180018002", "0xffffffffffffffff0000000000000000", "0x480080037ff48001", @@ -16954,360 +17855,79 @@ "0x100000000000000000000000000000000", "0x40307ff07ffe7fff", "0x40307ffc7ff77fef", - "0x48307fee7fef8001", + "0x48307ff07fed8001", "0xa0680017fff7fff", "0x7", "0x4824800180007fff", "0x100000000000000000000000000000000", "0x400080097fe97fff", "0x10780017fff7fff", - "0xa", + "0xc", "0x400080097fea7fff", "0x40780017fff7fff", "0x1", "0x482480017fe98000", "0xa", "0x48127ffd7fff8000", - "0x10780017fff7fff", - "0x5", - "0x482480017fe98000", - "0xa", - "0x48127ffe7fff8000", - "0x48307feb7fe88001", - "0xa0680017fff7fff", - "0x7", - "0x4824800180007fff", - "0x100000000000000000000000000000000", - "0x400080007ffb7fff", - "0x10780017fff7fff", - "0xc", - "0x400080007ffc7fff", - "0x40780017fff7fff", - "0x1", - "0x482480017ffb8000", - "0x1", - "0x48127ffd7fff8000", "0x480680017fff8000", "0x0", "0x10780017fff7fff", "0x7", - "0x482480017ffb8000", - "0x1", - "0x48127ffe7fff8000", - "0x480680017fff8000", - "0x1", - "0x48307fff7ff98001", - "0xa0680017fff7fff", - "0x7", - "0x4824800180007fff", - "0x100000000000000000000000000000000", - "0x400080007ffa7fff", - "0x10780017fff7fff", + "0x482480017fe98000", "0xa", - "0x400080007ffb7fff", - "0x40780017fff7fff", - "0x1", - "0x482480017ffa8000", - "0x1", - "0x48127ffd7fff8000", - "0x10780017fff7fff", - "0x5", - "0x482480017ffa8000", - "0x1", "0x48127ffe7fff8000", - "0x48307fd87fc18001", - "0xa0680017fff7fff", - "0x7", - "0x4824800180007fff", - "0x100000000000000000000000000000000", - "0x400080007ffb7fff", - "0x10780017fff7fff", - "0xa", - "0x400080007ffc7fff", - "0x40780017fff7fff", - "0x1", - "0x482480017ffb8000", - "0x1", - "0x48127ffd7fff8000", - "0x10780017fff7fff", - "0x5", - "0x482480017ffb8000", + "0x480680017fff8000", "0x1", - "0x48127ffe7fff8000", - "0x48307fff7ff48001", + "0x48307fe27fcb8000", + "0x48307fff7ffd8001", "0xa0680017fff7fff", "0x7", "0x4824800180007fff", "0x100000000000000000000000000000000", - "0x400080007ffb7fff", + "0x400080007ff97fff", "0x10780017fff7fff", "0xc", - "0x400080007ffc7fff", + "0x400080007ffa7fff", "0x40780017fff7fff", "0x1", - "0x482480017ffb8000", + "0x482480017ff98000", "0x1", "0x48127ffd7fff8000", "0x480680017fff8000", "0x0", "0x10780017fff7fff", "0x7", - "0x482480017ffb8000", + "0x482480017ff98000", "0x1", "0x48127ffe7fff8000", "0x480680017fff8000", "0x1", - "0x48307fff7ff48001", + "0x48307ff87fe18000", + "0x48307ffe7fff8000", + "0x48307fff7fe08001", "0xa0680017fff7fff", "0x7", "0x4824800180007fff", "0x100000000000000000000000000000000", - "0x400080007ffa7fff", + "0x400080007ff87fff", "0x10780017fff7fff", "0xa", - "0x400080007ffb7fff", + "0x400080007ff97fff", "0x40780017fff7fff", "0x1", - "0x482480017ffa8000", + "0x482480017ff88000", "0x1", "0x48127ffd7fff8000", "0x10780017fff7fff", "0x5", - "0x482480017ffa8000", + "0x482480017ff88000", "0x1", "0x48127ffe7fff8000", - "0x48127f8b7fff8000", - "0x48127fc67fff8000", - "0x48127ff77fff8000", - "0x48127ffc7fff8000", - "0x480080007ffa8000", - "0x480080017ff98000", - "0x480080027ff88000", - "0x480080037ff78000", - "0x480080047ff68000", - "0x480080057ff58000", - "0x48317fff80007ffd", - "0x40780017fff7fff", - "0xc", - "0x20680017fff7ff3", - "0x8", - "0x40317ff17ff47ffc", - "0x402480017ff57ff4", - "0x1", - "0x400080067fe77ff5", - "0x10780017fff7fff", - "0x3", - "0x400080067fe77ff3", - "0x48307ff17ff68000", - "0x48307fe880007fff", - "0x4844800180007fff", - "0x100000000000000000000000000000000", - "0x40507fff7fff7fff", - "0x48307ff47fff8000", - "0x48307ff47fff8000", - "0x48307ff57fff8000", - "0x48307fec7fff8000", - "0x48307fe380007fff", - "0x4844800180007fff", - "0x100000000000000000000000000000000", - "0x400080077fde7fff", - "0x482480017fff8000", - "0xfffffffffffffffffffffffffffffffc", - "0x400080087fdd7fff", - "0x48307fef7ffe8000", - "0x48307ff07fff8000", - "0x48307ff07fff8000", - "0x48307ff17fff8000", - "0x48307fdd80007fff", - "0x4844800180007fff", - "0x100000000000000000000000000000000", - "0x400080097fd77fff", - "0x482480017fff8000", - "0xfffffffffffffffffffffffffffffffc", - "0x4000800a7fd67fff", - "0xa0680017fff7fdf", - "0xc", - "0xa0680017fff8001", - "0x6", - "0x480a7ffd7fff7ffe", - "0x40127fdb7fff7ffe", - "0x10780017fff7fff", - "0x10", - "0x48127fdc7fff7ffe", - "0x400a7ffd7fff7ffe", - "0x10780017fff7fff", - "0xc", - "0x480780017fff7ffd", - "0x0", - "0xa0680017fff8000", - "0x6", - "0x400a7ffc7fff7ffd", - "0x40127fdc7fff7ffe", - "0x10780017fff7fff", - "0x4", - "0x40127fdc7fff7ffd", - "0x400a7ffc7fff7ffe", - "0x482480017ffd8000", - "0xffffffffffffffff0000000000000000", - "0x4000800b7fd27fff", - "0x48507ffd7ffc8000", - "0x48307fe97ff98000", - "0x48307fe67fff8000", - "0x40307ffd7fff7fd4", - "0x4824800180008002", - "0xffffffffffffffff0000000000000000", - "0x4800800c7fce8001", - "0x4800800d7fcd7ffe", - "0x4000800e7fcc7ffe", - "0x484480017ffe8000", - "0x10000000000000000", - "0x40307ffc7fff7fd3", - "0x48487ffc7ffc8000", - "0x48487ffc7ffc8000", - "0x4824800180018002", - "0xffffffffffffffff0000000000000000", - "0x4800800f7fc88001", - "0x480080107fc77fff", - "0x400080117fc67ffd", - "0x484480017ffd8000", - "0x10000000000000000", - "0x40307ffd7fff7ffb", - "0x484480017ffd8000", - "0x10000000000000000", - "0x48307fff7ff98003", - "0x482480017fff8000", - "0xfffffffffffffffe0000000000000000", - "0x480080127fc27fff", - "0x480080137fc17ffd", - "0x400080147fc07fd7", - "0x404480017ffc7ffe", - "0x100000000000000000000000000000000", - "0x40307fd77ffe7fff", - "0x40307ffc7ff77fd8", - "0x4824800180008002", - "0xffffffffffffffff0000000000000000", - "0x480080157fbf8001", - "0x480080167fbe7ffe", - "0x400080177fbd7ffe", - "0x484480017ffe8000", - "0x10000000000000000", - "0x40307ffc7fff7fc3", - "0x48487ffd7ffc8000", - "0x48487ffd7ffc8000", - "0x4824800180018002", - "0xffffffffffffffff0000000000000000", - "0x480080187fb98001", - "0x480080197fb87fff", - "0x4000801a7fb77ffd", - "0x484480017ffd8000", - "0x10000000000000000", - "0x40307ffd7fff7ffb", - "0x484480017ffd8000", - "0x10000000000000000", - "0x48307fff7ff98003", - "0x482480017fff8000", - "0xfffffffffffffffe0000000000000000", - "0x4800801b7fb37fff", - "0x4800801c7fb27ffd", - "0x4000801d7fb17fc6", - "0x404480017ffc7ffe", - "0x100000000000000000000000000000000", - "0x40307fc67ffe7fff", - "0x40307ffc7ff77fc7", - "0x4824800180008002", - "0xffffffffffffffff0000000000000000", - "0x4800801e7fb08001", - "0x4800801f7faf7ffe", - "0x400080207fae7ffe", - "0x484480017ffe8000", - "0x10000000000000000", - "0x40307ffc7fff7fb4", - "0x48487ffc7ffc8000", - "0x48487ffc7ffc8000", - "0x4824800180018002", - "0xffffffffffffffff0000000000000000", - "0x480080217faa8001", - "0x480080227fa97fff", - "0x400080237fa87ffd", - "0x484480017ffd8000", - "0x10000000000000000", - "0x40307ffd7fff7ffb", - "0x484480017ffd8000", - "0x10000000000000000", - "0x48307fff7ff98003", - "0x482480017fff8000", - "0xfffffffffffffffe0000000000000000", - "0x480080247fa47fff", - "0x480080257fa37ffd", - "0x400080267fa27fb3", - "0x404480017ffc7ffe", - "0x100000000000000000000000000000000", - "0x40307fb37ffe7fff", - "0x40307ffc7ff77fb4", - "0x4824800180008002", - "0xffffffffffffffff0000000000000000", - "0x480080277fa18001", - "0x480080287fa07ffe", - "0x400080297f9f7ffe", - "0x484480017ffe8000", - "0x10000000000000000", - "0x40307ffc7fff7fa4", - "0x48487ffd7ffc8000", - "0x48487ffd7ffc8000", - "0x4824800180018002", - "0xffffffffffffffff0000000000000000", - "0x4800802a7f9b8001", - "0x4800802b7f9a7fff", - "0x4000802c7f997ffd", - "0x484480017ffd8000", - "0x10000000000000000", - "0x40307ffd7fff7ffb", - "0x484480017ffd8000", - "0x10000000000000000", - "0x48307fff7ff98003", - "0x482480017fff8000", - "0xfffffffffffffffe0000000000000000", - "0x4800802d7f957fff", - "0x4800802e7f947ffd", - "0x4000802f7f937fa6", - "0x404480017ffc7ffe", - "0x100000000000000000000000000000000", - "0x40307fa67ffe7fff", - "0x40307ffc7ff77fa7", - "0x4824800180008002", - "0xffffffffffffffff0000000000000000", - "0x480080307f928001", - "0x480080317f917ffe", - "0x400080327f907ffe", - "0x484480017ffe8000", - "0x10000000000000000", - "0x40307ffc7fff7f95", - "0x48487ffc7ffc8000", - "0x48487ffc7ffc8000", - "0x4824800180018002", - "0xffffffffffffffff0000000000000000", - "0x480080337f8c8001", - "0x480080347f8b7fff", - "0x400080357f8a7ffd", - "0x484480017ffd8000", - "0x10000000000000000", - "0x40307ffd7fff7ffb", - "0x484480017ffd8000", - "0x10000000000000000", - "0x48307fff7ff98003", - "0x482480017fff8000", - "0xfffffffffffffffe0000000000000000", - "0x480080367f867fff", - "0x480080377f857ffd", - "0x400080387f847f93", - "0x404480017ffc7ffe", - "0x100000000000000000000000000000000", - "0x40307f937ffe7fff", - "0x40307ffc7ff77f94", - "0x482480017f848000", - "0x39", - "0x48127f8d7fff8000", - "0x48127f8d7fff8000", + "0x48127ffe7fff8000", + "0x48127f967fff8000", + "0x48127fd17fff8000", + "0x48127ff47fff8000", + "0x48127ffb7fff8000", "0x208b7fff7fff7ffe", "0xa0680017fff8000", "0x7", @@ -17869,7 +18489,7 @@ 258, 97, 220, - 791, + 1242, 31, 1136, 66, @@ -17877,9 +18497,9 @@ 157, 83, 239, - 706, + 1156, 199, - 552, + 271, 131, 104, 232, @@ -20651,7 +21271,7 @@ { "TestLessThanOrEqual": { "lhs": { - "Immediate": "0x382d4" + "Immediate": "0x371b8" }, "rhs": { "Deref": { @@ -28422,7 +29042,1275 @@ ] ], [ - 13706, + 13679, + [ + { + "Uint512DivModByUint256": { + "dividend0": { + "Deref": { + "register": "AP", + "offset": -6 + } + }, + "dividend1": { + "Deref": { + "register": "AP", + "offset": -5 + } + }, + "dividend2": { + "Deref": { + "register": "AP", + "offset": -4 + } + }, + "dividend3": { + "Deref": { + "register": "AP", + "offset": -3 + } + }, + "divisor0": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "divisor1": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "quotient0": { + "register": "AP", + "offset": 0 + }, + "quotient1": { + "register": "AP", + "offset": 1 + }, + "quotient2": { + "register": "AP", + "offset": 2 + }, + "quotient3": { + "register": "AP", + "offset": 3 + }, + "remainder0": { + "register": "AP", + "offset": 4 + }, + "remainder1": { + "register": "AP", + "offset": 5 + } + } + } + ] + ], + [ + 13697, + [ + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -19 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 + } + }, + "high": { + "register": "AP", + "offset": -9 + }, + "low": { + "register": "AP", + "offset": -10 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -18 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 + } + }, + "high": { + "register": "AP", + "offset": -7 + }, + "low": { + "register": "AP", + "offset": -8 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -19 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -20 + } + }, + "high": { + "register": "AP", + "offset": -5 + }, + "low": { + "register": "AP", + "offset": -6 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -18 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -20 + } + }, + "high": { + "register": "AP", + "offset": -3 + }, + "low": { + "register": "AP", + "offset": -4 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -17 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 + } + }, + "high": { + "register": "AP", + "offset": -1 + }, + "low": { + "register": "AP", + "offset": -2 + } + } + } + ] + ], + [ + 13726, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -35 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -38 + } + }, + "dst": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 13738, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -35 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -40 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 13753, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -41 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 13763, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 13774, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -38 + } + } + } + ] + ], + [ + 13783, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -57 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 13793, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 13804, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -55 + } + } + } + ] + ], + [ + 13813, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -72 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 13823, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 13834, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -74 + } + } + } + ] + ], + [ + 13843, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -88 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 13853, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 13864, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -87 + } + } + } + ] + ], + [ + 13873, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -103 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 13883, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 13894, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -106 + } + } + } + ] + ], + [ + 13915, + [ + { + "Uint512DivModByUint256": { + "dividend0": { + "Deref": { + "register": "AP", + "offset": -6 + } + }, + "dividend1": { + "Deref": { + "register": "AP", + "offset": -5 + } + }, + "dividend2": { + "Deref": { + "register": "AP", + "offset": -4 + } + }, + "dividend3": { + "Deref": { + "register": "AP", + "offset": -3 + } + }, + "divisor0": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "divisor1": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "quotient0": { + "register": "AP", + "offset": 0 + }, + "quotient1": { + "register": "AP", + "offset": 1 + }, + "quotient2": { + "register": "AP", + "offset": 2 + }, + "quotient3": { + "register": "AP", + "offset": 3 + }, + "remainder0": { + "register": "AP", + "offset": 4 + }, + "remainder1": { + "register": "AP", + "offset": 5 + } + } + } + ] + ], + [ + 13933, + [ + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -19 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 + } + }, + "high": { + "register": "AP", + "offset": -9 + }, + "low": { + "register": "AP", + "offset": -10 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -18 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 + } + }, + "high": { + "register": "AP", + "offset": -7 + }, + "low": { + "register": "AP", + "offset": -8 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -19 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -20 + } + }, + "high": { + "register": "AP", + "offset": -5 + }, + "low": { + "register": "AP", + "offset": -6 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -18 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -20 + } + }, + "high": { + "register": "AP", + "offset": -3 + }, + "low": { + "register": "AP", + "offset": -4 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -17 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 + } + }, + "high": { + "register": "AP", + "offset": -1 + }, + "low": { + "register": "AP", + "offset": -2 + } + } + } + ] + ], + [ + 13962, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -35 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -38 + } + }, + "dst": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 13974, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -35 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -40 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 13989, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -41 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 13999, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 14010, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -38 + } + } + } + ] + ], + [ + 14019, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -57 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 14029, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 14040, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -55 + } + } + } + ] + ], + [ + 14049, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -72 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 14059, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 14070, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -74 + } + } + } + ] + ], + [ + 14079, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -88 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 14089, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 14100, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -87 + } + } + } + ] + ], + [ + 14109, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -103 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 14119, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 14130, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -106 + } + } + } + ] + ], + [ + 14157, [ { "SystemCall": { @@ -28437,7 +30325,7 @@ ] ], [ - 13723, + 14174, [ { "SystemCall": { @@ -28452,7 +30340,7 @@ ] ], [ - 13735, + 14186, [ { "SystemCall": { @@ -28473,7 +30361,7 @@ ] ], [ - 13746, + 14197, [ { "SystemCall": { @@ -28494,7 +30382,7 @@ ] ], [ - 13756, + 14207, [ { "SystemCall": { @@ -28515,7 +30403,7 @@ ] ], [ - 13841, + 14292, [ { "AllocSegment": { @@ -28528,14 +30416,14 @@ ] ], [ - 13870, + 14321, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -669 + "offset": -642 } }, "rhs": { @@ -28554,7 +30442,7 @@ ] ], [ - 13880, + 14331, [ { "DivMod": { @@ -28580,7 +30468,7 @@ ] ], [ - 13891, + 14342, [ { "DivMod": { @@ -28599,21 +30487,21 @@ }, "remainder": { "register": "AP", - "offset": -683 + "offset": -656 } } } ] ], [ - 13900, + 14351, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -684 + "offset": -657 } }, "rhs": { @@ -28632,7 +30520,7 @@ ] ], [ - 13910, + 14361, [ { "DivMod": { @@ -28658,7 +30546,7 @@ ] ], [ - 13921, + 14372, [ { "DivMod": { @@ -28684,7 +30572,7 @@ ] ], [ - 13930, + 14381, [ { "AllocSegment": { @@ -28697,7 +30585,7 @@ ] ], [ - 13999, + 14450, [ { "TestLessThan": { @@ -28728,7 +30616,7 @@ ] ], [ - 14014, + 14465, [ { "TestLessThan": { @@ -28750,7 +30638,7 @@ ] ], [ - 14033, + 14484, [ { "TestLessThan": { @@ -28772,7 +30660,7 @@ ] ], [ - 14052, + 14503, [ { "TestLessThan": { @@ -28794,7 +30682,7 @@ ] ], [ - 14062, + 14513, [ { "TestLessThan": { @@ -28816,7 +30704,7 @@ ] ], [ - 14064, + 14515, [ { "DivMod": { @@ -28842,7 +30730,7 @@ ] ], [ - 14101, + 14552, [ { "TestLessThan": { @@ -28864,7 +30752,7 @@ ] ], [ - 14120, + 14571, [ { "AllocSegment": { @@ -28877,7 +30765,7 @@ ] ], [ - 14131, + 14582, [ { "DivMod": { @@ -28906,7 +30794,7 @@ ] ], [ - 14137, + 14588, [ { "TestLessThan": { @@ -28928,7 +30816,7 @@ ] ], [ - 14151, + 14602, [ { "TestLessThan": { @@ -28950,7 +30838,7 @@ ] ], [ - 14165, + 14616, [ { "TestLessThan": { @@ -28972,7 +30860,7 @@ ] ], [ - 14176, + 14627, [ { "TestLessThan": { @@ -28994,7 +30882,7 @@ ] ], [ - 14205, + 14656, [ { "AllocSegment": { @@ -29007,7 +30895,7 @@ ] ], [ - 14230, + 14681, [ { "TestLessThan": { @@ -29029,7 +30917,7 @@ ] ], [ - 14234, + 14685, [ { "LinearSplit": { @@ -29058,7 +30946,7 @@ ] ], [ - 14244, + 14695, [ { "LinearSplit": { @@ -29087,7 +30975,7 @@ ] ], [ - 14264, + 14715, [ { "AllocSegment": { @@ -29100,7 +30988,7 @@ ] ], [ - 14285, + 14736, [ { "AllocSegment": { @@ -29113,7 +31001,7 @@ ] ], [ - 14306, + 14757, [ { "AllocSegment": { @@ -29126,7 +31014,7 @@ ] ], [ - 14326, + 14777, [ { "TestLessThan": { @@ -29148,7 +31036,7 @@ ] ], [ - 14328, + 14779, [ { "DivMod": { @@ -29174,7 +31062,7 @@ ] ], [ - 14372, + 14823, [ { "AllocSegment": { @@ -29187,7 +31075,7 @@ ] ], [ - 14383, + 14834, [ { "DivMod": { @@ -29216,7 +31104,7 @@ ] ], [ - 14389, + 14840, [ { "TestLessThan": { @@ -29238,7 +31126,7 @@ ] ], [ - 14403, + 14854, [ { "TestLessThan": { @@ -29260,7 +31148,7 @@ ] ], [ - 14421, + 14872, [ { "TestLessThan": { @@ -29282,7 +31170,7 @@ ] ], [ - 14434, + 14885, [ { "TestLessThan": { @@ -29304,7 +31192,7 @@ ] ], [ - 14445, + 14896, [ { "TestLessThan": { @@ -29326,7 +31214,7 @@ ] ], [ - 14474, + 14925, [ { "AllocSegment": { @@ -29339,7 +31227,7 @@ ] ], [ - 14499, + 14950, [ { "TestLessThan": { @@ -29361,7 +31249,7 @@ ] ], [ - 14503, + 14954, [ { "LinearSplit": { @@ -29390,7 +31278,7 @@ ] ], [ - 14513, + 14964, [ { "LinearSplit": { @@ -29419,7 +31307,7 @@ ] ], [ - 14533, + 14984, [ { "AllocSegment": { @@ -29432,7 +31320,7 @@ ] ], [ - 14554, + 15005, [ { "AllocSegment": { @@ -29445,7 +31333,7 @@ ] ], [ - 14575, + 15026, [ { "AllocSegment": { @@ -29458,7 +31346,7 @@ ] ], [ - 14604, + 15055, [ { "TestLessThan": { @@ -29480,7 +31368,7 @@ ] ], [ - 14606, + 15057, [ { "DivMod": { @@ -29506,7 +31394,7 @@ ] ], [ - 14643, + 15094, [ { "TestLessThan": { @@ -29528,7 +31416,7 @@ ] ], [ - 14654, + 15105, [ { "TestLessThan": { @@ -29550,7 +31438,7 @@ ] ], [ - 14665, + 15116, [ { "TestLessThan": { @@ -29572,7 +31460,7 @@ ] ], [ - 14694, + 15145, [ { "AllocSegment": { @@ -29585,7 +31473,7 @@ ] ], [ - 14719, + 15170, [ { "TestLessThan": { @@ -29607,7 +31495,7 @@ ] ], [ - 14723, + 15174, [ { "LinearSplit": { @@ -29636,7 +31524,7 @@ ] ], [ - 14733, + 15184, [ { "LinearSplit": { @@ -29665,7 +31553,7 @@ ] ], [ - 14759, + 15210, [ { "AllocSegment": { @@ -29678,7 +31566,7 @@ ] ], [ - 14780, + 15231, [ { "AllocSegment": { @@ -29691,7 +31579,7 @@ ] ], [ - 14802, + 15253, [ { "AllocSegment": { @@ -29704,7 +31592,7 @@ ] ], [ - 14824, + 15275, [ { "TestLessThan": { @@ -29726,7 +31614,7 @@ ] ], [ - 14835, + 15286, [ { "TestLessThan": { @@ -29748,7 +31636,7 @@ ] ], [ - 14864, + 15315, [ { "AllocSegment": { @@ -29761,7 +31649,7 @@ ] ], [ - 14889, + 15340, [ { "TestLessThan": { @@ -29783,7 +31671,7 @@ ] ], [ - 14893, + 15344, [ { "LinearSplit": { @@ -29812,7 +31700,7 @@ ] ], [ - 14903, + 15354, [ { "LinearSplit": { @@ -29841,7 +31729,7 @@ ] ], [ - 14926, + 15377, [ { "AllocSegment": { @@ -29854,7 +31742,7 @@ ] ], [ - 14971, + 15422, [ { "TestLessThan": { @@ -29876,7 +31764,7 @@ ] ], [ - 14982, + 15433, [ { "TestLessThan": { @@ -29898,7 +31786,7 @@ ] ], [ - 15011, + 15462, [ { "AllocSegment": { @@ -29911,7 +31799,7 @@ ] ], [ - 15034, + 15485, [ { "TestLessThan": { @@ -29942,7 +31830,7 @@ ] ], [ - 15058, + 15509, [ { "AllocSegment": { @@ -29955,7 +31843,7 @@ ] ], [ - 15102, + 15553, [ { "AllocSegment": { @@ -29968,7 +31856,7 @@ ] ], [ - 15129, + 15580, [ { "TestLessThanOrEqual": { @@ -29990,7 +31878,7 @@ ] ], [ - 15181, + 15632, [ { "AllocSegment": { @@ -30003,7 +31891,7 @@ ] ], [ - 15238, + 15689, [ { "TestLessThan": { @@ -30031,7 +31919,7 @@ ] ], [ - 15242, + 15693, [ { "LinearSplit": { @@ -30060,7 +31948,7 @@ ] ], [ - 15284, + 15735, [ { "TestLessThan": { @@ -30082,7 +31970,7 @@ ] ], [ - 15286, + 15737, [ { "DivMod": { @@ -30108,7 +31996,7 @@ ] ], [ - 15373, + 15824, [ { "DivMod": { @@ -30137,7 +32025,7 @@ ] ], [ - 15379, + 15830, [ { "TestLessThan": { @@ -30159,7 +32047,7 @@ ] ], [ - 15390, + 15841, [ { "TestLessThan": { @@ -30181,7 +32069,7 @@ ] ], [ - 15400, + 15851, [ { "TestLessThan": { @@ -30203,7 +32091,7 @@ ] ], [ - 15414, + 15865, [ { "DivMod": { @@ -30232,7 +32120,7 @@ ] ], [ - 15420, + 15871, [ { "TestLessThan": { @@ -30254,7 +32142,7 @@ ] ], [ - 15434, + 15885, [ { "TestLessThan": { @@ -30276,7 +32164,7 @@ ] ], [ - 15444, + 15895, [ { "TestLessThan": { @@ -30298,7 +32186,7 @@ ] ], [ - 15466, + 15917, [ { "AllocSegment": { @@ -30311,7 +32199,7 @@ ] ], [ - 15480, + 15931, [ { "AllocSegment": { @@ -30324,7 +32212,7 @@ ] ], [ - 15498, + 15949, [ { "AllocSegment": { @@ -30337,7 +32225,7 @@ ] ], [ - 15512, + 15963, [ { "AllocSegment": { @@ -30350,7 +32238,7 @@ ] ], [ - 15528, + 15979, [ { "TestLessThanOrEqual": { @@ -30372,7 +32260,7 @@ ] ], [ - 15555, + 16006, [ { "TestLessThan": { @@ -30394,7 +32282,7 @@ ] ], [ - 15572, + 16023, [ { "AllocSegment": { @@ -30407,7 +32295,7 @@ ] ], [ - 15597, + 16048, [ { "AllocSegment": { @@ -30420,7 +32308,7 @@ ] ], [ - 15857, + 16308, [ { "SystemCall": { @@ -30435,7 +32323,7 @@ ] ], [ - 15883, + 16334, [ { "SystemCall": { @@ -30450,7 +32338,7 @@ ] ], [ - 15897, + 16348, [ { "U256InvModN": { @@ -30507,7 +32395,7 @@ ] ], [ - 15915, + 16366, [ { "WideMul128": { @@ -30704,7 +32592,7 @@ ] ], [ - 15968, + 16419, [ { "WideMul128": { @@ -30757,7 +32645,7 @@ ] ], [ - 15972, + 16423, [ { "TestLessThan": { @@ -30779,7 +32667,7 @@ ] ], [ - 15986, + 16437, [ { "TestLessThan": { @@ -30801,7 +32689,7 @@ ] ], [ - 15999, + 16450, [ { "DivMod": { @@ -30827,7 +32715,319 @@ ] ], [ - 16009, + 16460, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 16471, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -35 + } + } + } + ] + ], + [ + 16480, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -62 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 16490, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 16501, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -52 + } + } + } + ] + ], + [ + 16510, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -78 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 16520, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 16531, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -69 + } + } + } + ] + ], + [ + 16540, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -93 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 16550, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 16561, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -86 + } + } + } + ] + ], + [ + 16570, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -103 + } + }, + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 16580, [ { "DivMod": { @@ -30853,7 +33053,7 @@ ] ], [ - 16020, + 16591, [ { "DivMod": { @@ -30872,21 +33072,21 @@ }, "remainder": { "register": "AP", - "offset": -35 + "offset": -103 } } } ] ], [ - 16029, + 16600, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -62 + "offset": -118 } }, "rhs": { @@ -30905,7 +33105,7 @@ ] ], [ - 16039, + 16610, [ { "DivMod": { @@ -30931,7 +33131,7 @@ ] ], [ - 16050, + 16621, [ { "DivMod": { @@ -30950,21 +33150,21 @@ }, "remainder": { "register": "AP", - "offset": -52 + "offset": -120 } } } ] ], [ - 16059, + 16630, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -78 + "offset": -134 } }, "rhs": { @@ -30983,7 +33183,7 @@ ] ], [ - 16069, + 16640, [ { "DivMod": { @@ -31009,7 +33209,7 @@ ] ], [ - 16080, + 16651, [ { "DivMod": { @@ -31028,21 +33228,21 @@ }, "remainder": { "register": "AP", - "offset": -69 + "offset": -137 } } } ] ], [ - 16089, + 16660, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -93 + "offset": -149 } }, "rhs": { @@ -31061,7 +33261,7 @@ ] ], [ - 16099, + 16670, [ { "DivMod": { @@ -31087,7 +33287,7 @@ ] ], [ - 16110, + 16681, [ { "DivMod": { @@ -31106,135 +33306,224 @@ }, "remainder": { "register": "AP", - "offset": -86 + "offset": -154 } } } ] ], [ - 16119, + 16702, [ { - "DivMod": { - "lhs": { + "Uint512DivModByUint256": { + "dividend0": { "Deref": { "register": "AP", - "offset": -103 + "offset": -6 } }, - "rhs": { - "Immediate": "0x10000000000000000" + "dividend1": { + "Deref": { + "register": "AP", + "offset": -5 + } }, - "quotient": { + "dividend2": { + "Deref": { + "register": "AP", + "offset": -4 + } + }, + "dividend3": { + "Deref": { + "register": "AP", + "offset": -3 + } + }, + "divisor0": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "divisor1": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "quotient0": { + "register": "AP", + "offset": 0 + }, + "quotient1": { "register": "AP", "offset": 1 }, - "remainder": { + "quotient2": { "register": "AP", - "offset": 0 + "offset": 2 + }, + "quotient3": { + "register": "AP", + "offset": 3 + }, + "remainder0": { + "register": "AP", + "offset": 4 + }, + "remainder1": { + "register": "AP", + "offset": 5 } } } ] ], [ - 16129, + 16720, [ { - "DivMod": { + "WideMul128": { "lhs": { "Deref": { "register": "AP", - "offset": -1 + "offset": -19 } }, "rhs": { - "Immediate": "0x10000000000000000" + "Deref": { + "register": "AP", + "offset": -21 + } }, - "quotient": { + "high": { "register": "AP", - "offset": 0 + "offset": -9 }, - "remainder": { + "low": { "register": "AP", - "offset": 1 + "offset": -10 } } - } - ] - ], - [ - 16140, - [ + }, { - "DivMod": { + "WideMul128": { "lhs": { "Deref": { "register": "AP", - "offset": 2 + "offset": -18 } }, "rhs": { - "Immediate": "0x100000000000000000000000000000000" + "Deref": { + "register": "AP", + "offset": -21 + } }, - "quotient": { + "high": { "register": "AP", - "offset": -1 + "offset": -7 }, - "remainder": { + "low": { "register": "AP", - "offset": -103 + "offset": -8 } } - } - ] - ], - [ - 16149, - [ + }, { - "DivMod": { + "WideMul128": { "lhs": { "Deref": { "register": "AP", - "offset": -118 + "offset": -19 } }, "rhs": { - "Immediate": "0x10000000000000000" + "Deref": { + "register": "AP", + "offset": -20 + } }, - "quotient": { + "high": { "register": "AP", - "offset": 1 + "offset": -5 }, - "remainder": { + "low": { "register": "AP", - "offset": 0 + "offset": -6 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -18 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -20 + } + }, + "high": { + "register": "AP", + "offset": -3 + }, + "low": { + "register": "AP", + "offset": -4 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -17 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 + } + }, + "high": { + "register": "AP", + "offset": -1 + }, + "low": { + "register": "AP", + "offset": -2 } } } ] ], [ - 16159, + 16749, [ { - "DivMod": { + "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": -1 + "offset": -35 } }, "rhs": { - "Immediate": "0x10000000000000000" - }, - "quotient": { - "register": "AP", - "offset": 0 + "Deref": { + "register": "AP", + "offset": -38 + } }, - "remainder": { + "dst": { "register": "AP", "offset": 1 } @@ -31243,40 +33532,39 @@ ] ], [ - 16170, + 16761, [ { - "DivMod": { + "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": 2 + "offset": -35 } }, "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "quotient": { - "register": "AP", - "offset": -1 + "Deref": { + "register": "AP", + "offset": -40 + } }, - "remainder": { + "dst": { "register": "AP", - "offset": -120 + "offset": 0 } } } ] ], [ - 16179, + 16776, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -134 + "offset": -41 } }, "rhs": { @@ -31295,7 +33583,7 @@ ] ], [ - 16189, + 16786, [ { "DivMod": { @@ -31321,7 +33609,7 @@ ] ], [ - 16200, + 16797, [ { "DivMod": { @@ -31340,21 +33628,21 @@ }, "remainder": { "register": "AP", - "offset": -137 + "offset": -38 } } } ] ], [ - 16209, + 16806, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -149 + "offset": -57 } }, "rhs": { @@ -31373,7 +33661,7 @@ ] ], [ - 16219, + 16816, [ { "DivMod": { @@ -31399,7 +33687,7 @@ ] ], [ - 16230, + 16827, [ { "DivMod": { @@ -31418,157 +33706,99 @@ }, "remainder": { "register": "AP", - "offset": -154 + "offset": -55 } } } ] ], [ - 16254, + 16836, [ { - "TestLessThan": { + "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": 0 + "offset": -72 } }, "rhs": { - "Immediate": "0x100000000000000000000000000000000" + "Immediate": "0x10000000000000000" }, - "dst": { + "quotient": { "register": "AP", - "offset": -1 - } - } - } - ] - ], - [ - 16279, - [ - { - "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": 0 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" + "offset": 1 }, - "dst": { + "remainder": { "register": "AP", - "offset": -1 + "offset": 0 } } } ] ], [ - 16299, + 16846, [ { - "TestLessThan": { + "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": 0 + "offset": -1 } }, "rhs": { - "Immediate": "0x100000000000000000000000000000000" + "Immediate": "0x10000000000000000" }, - "dst": { + "quotient": { "register": "AP", - "offset": -1 + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 } } } ] ], [ - 16344, + 16857, [ { - "SystemCall": { - "system": { + "DivMod": { + "lhs": { "Deref": { - "register": "AP", - "offset": -695 - } - } - } - } - ] - ], - [ - 16356, - [ - { - "SystemCall": { - "system": { - "BinOp": { - "op": "Add", - "a": { - "register": "AP", - "offset": -699 - }, - "b": { - "Immediate": "0x8" - } - } - } - } - } - ] - ], - [ - 16367, - [ - { - "SystemCall": { - "system": { - "BinOp": { - "op": "Add", - "a": { - "register": "AP", - "offset": -703 - }, - "b": { - "Immediate": "0x10" - } - } - } - } - } - ] - ], - [ - 16413, - [ - { - "AllocSegment": { - "dst": { + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { "register": "AP", - "offset": 0 + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -74 } } } ] ], [ - 16429, + 16866, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -669 + "offset": -88 } }, "rhs": { @@ -31587,7 +33817,7 @@ ] ], [ - 16439, + 16876, [ { "DivMod": { @@ -31613,7 +33843,7 @@ ] ], [ - 16450, + 16887, [ { "DivMod": { @@ -31632,21 +33862,21 @@ }, "remainder": { "register": "AP", - "offset": -683 + "offset": -87 } } } ] ], [ - 16459, + 16896, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -684 + "offset": -103 } }, "rhs": { @@ -31665,7 +33895,7 @@ ] ], [ - 16469, + 16906, [ { "DivMod": { @@ -31691,7 +33921,7 @@ ] ], [ - 16480, + 16917, [ { "DivMod": { @@ -31709,187 +33939,332 @@ "offset": -1 }, "remainder": { - "register": "FP", - "offset": -7 + "register": "AP", + "offset": -106 } } } ] ], [ - 16489, + 16929, [ { - "AllocSegment": { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, "dst": { "register": "AP", - "offset": 0 + "offset": -1 } } } ] ], [ - 16506, + 16954, [ { - "AllocSegment": { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, "dst": { "register": "AP", - "offset": 0 + "offset": -1 } } } ] ], [ - 16563, + 16974, [ { - "SystemCall": { - "system": { + "TestLessThan": { + "lhs": { "Deref": { - "register": "FP", - "offset": -4 + "register": "AP", + "offset": 0 } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": -1 } } } ] ], [ - 16570, + 17010, [ { - "AllocConstantSize": { - "size": { - "Immediate": "0x4" + "Uint512DivModByUint256": { + "dividend0": { + "Deref": { + "register": "AP", + "offset": -6 + } }, - "dst": { + "dividend1": { + "Deref": { + "register": "AP", + "offset": -5 + } + }, + "dividend2": { + "Deref": { + "register": "AP", + "offset": -4 + } + }, + "dividend3": { + "Deref": { + "register": "AP", + "offset": -3 + } + }, + "divisor0": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "divisor1": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "quotient0": { "register": "AP", "offset": 0 + }, + "quotient1": { + "register": "AP", + "offset": 1 + }, + "quotient2": { + "register": "AP", + "offset": 2 + }, + "quotient3": { + "register": "AP", + "offset": 3 + }, + "remainder0": { + "register": "AP", + "offset": 4 + }, + "remainder1": { + "register": "AP", + "offset": 5 } } } ] ], [ - 16574, + 17028, [ { - "AllocSegment": { - "dst": { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -19 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 + } + }, + "high": { "register": "AP", - "offset": 0 + "offset": -9 + }, + "low": { + "register": "AP", + "offset": -10 } } - } - ] - ], - [ - 16609, - [ + }, { - "SystemCall": { - "system": { + "WideMul128": { + "lhs": { "Deref": { - "register": "FP", - "offset": 1 + "register": "AP", + "offset": -18 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 } + }, + "high": { + "register": "AP", + "offset": -7 + }, + "low": { + "register": "AP", + "offset": -8 } } - } - ] - ], - [ - 16682, - [ + }, { - "DivMod": { + "WideMul128": { "lhs": { "Deref": { "register": "AP", - "offset": -2 + "offset": -19 } }, "rhs": { "Deref": { "register": "AP", - "offset": -1 + "offset": -20 } }, - "quotient": { + "high": { "register": "AP", - "offset": 5 + "offset": -5 }, - "remainder": { + "low": { "register": "AP", - "offset": 6 + "offset": -6 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -18 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -20 + } + }, + "high": { + "register": "AP", + "offset": -3 + }, + "low": { + "register": "AP", + "offset": -4 + } + } + }, + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -17 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -21 + } + }, + "high": { + "register": "AP", + "offset": -1 + }, + "low": { + "register": "AP", + "offset": -2 } } } ] ], [ - 16688, + 17057, [ { "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": 0 + "offset": -35 } }, "rhs": { - "Immediate": "0x10000000000000000" + "Deref": { + "register": "AP", + "offset": -38 + } }, "dst": { "register": "AP", - "offset": -3 + "offset": 1 } } } ] ], [ - 16755, + 17069, [ { - "WideMul128": { + "TestLessThan": { "lhs": { "Deref": { - "register": "FP", - "offset": -8 + "register": "AP", + "offset": -35 } }, "rhs": { "Deref": { - "register": "FP", - "offset": -6 + "register": "AP", + "offset": -40 } }, - "high": { + "dst": { "register": "AP", "offset": 0 - }, - "low": { - "register": "AP", - "offset": 1 } } } ] ], [ - 16757, + 17084, [ { "DivMod": { "lhs": { "Deref": { - "register": "FP", - "offset": -8 + "register": "AP", + "offset": -41 } }, "rhs": { @@ -31908,7 +34283,7 @@ ] ], [ - 16767, + 17094, [ { "DivMod": { @@ -31934,7 +34309,7 @@ ] ], [ - 16778, + 17105, [ { "DivMod": { @@ -31953,34 +34328,57 @@ }, "remainder": { "register": "AP", - "offset": -13 + "offset": -38 } } } ] ], [ - 16787, + 17114, [ { - "WideMul128": { + "DivMod": { "lhs": { "Deref": { - "register": "FP", - "offset": -8 + "register": "AP", + "offset": -57 } }, "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 17124, + [ + { + "DivMod": { + "lhs": { "Deref": { - "register": "FP", - "offset": -5 + "register": "AP", + "offset": -1 } }, - "high": { + "rhs": { + "Immediate": "0x10000000000000000" + }, + "quotient": { "register": "AP", "offset": 0 }, - "low": { + "remainder": { "register": "AP", "offset": 1 } @@ -31989,14 +34387,40 @@ ] ], [ - 16789, + 17135, [ { "DivMod": { "lhs": { "Deref": { - "register": "FP", - "offset": -8 + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -55 + } + } + } + ] + ], + [ + 17144, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -72 } }, "rhs": { @@ -32015,7 +34439,7 @@ ] ], [ - 16799, + 17154, [ { "DivMod": { @@ -32041,7 +34465,7 @@ ] ], [ - 16810, + 17165, [ { "DivMod": { @@ -32060,56 +34484,57 @@ }, "remainder": { "register": "AP", - "offset": -13 + "offset": -74 } } } ] ], [ - 16820, + 17174, [ { - "TestLessThan": { + "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": 0 + "offset": -88 } }, "rhs": { - "Immediate": "0x100000000000000000000000000000000" + "Immediate": "0x10000000000000000" }, - "dst": { + "quotient": { "register": "AP", - "offset": -1 + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 } } } ] ], [ - 16842, + 17184, [ { - "WideMul128": { + "DivMod": { "lhs": { "Deref": { - "register": "FP", - "offset": -7 + "register": "AP", + "offset": -1 } }, "rhs": { - "Deref": { - "register": "FP", - "offset": -6 - } + "Immediate": "0x10000000000000000" }, - "high": { + "quotient": { "register": "AP", "offset": 0 }, - "low": { + "remainder": { "register": "AP", "offset": 1 } @@ -32118,14 +34543,40 @@ ] ], [ - 16844, + 17195, [ { "DivMod": { "lhs": { "Deref": { - "register": "FP", - "offset": -7 + "register": "AP", + "offset": 2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": -1 + }, + "remainder": { + "register": "AP", + "offset": -87 + } + } + } + ] + ], + [ + 17204, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -103 } }, "rhs": { @@ -32144,7 +34595,7 @@ ] ], [ - 16854, + 17214, [ { "DivMod": { @@ -32170,7 +34621,7 @@ ] ], [ - 16865, + 17225, [ { "DivMod": { @@ -32189,94 +34640,169 @@ }, "remainder": { "register": "AP", - "offset": -13 + "offset": -106 } } } ] ], [ - 16875, + 17245, [ { - "TestLessThan": { + "SystemCall": { + "system": { + "Deref": { + "register": "AP", + "offset": -668 + } + } + } + } + ] + ], + [ + 17257, + [ + { + "SystemCall": { + "system": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -672 + }, + "b": { + "Immediate": "0x8" + } + } + } + } + } + ] + ], + [ + 17268, + [ + { + "SystemCall": { + "system": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -676 + }, + "b": { + "Immediate": "0x10" + } + } + } + } + } + ] + ], + [ + 17314, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 17330, + [ + { + "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": 0 + "offset": -642 } }, "rhs": { - "Immediate": "0x100000000000000000000000000000000" + "Immediate": "0x10000000000000000" }, - "dst": { + "quotient": { "register": "AP", - "offset": -1 + "offset": 1 + }, + "remainder": { + "register": "AP", + "offset": 0 } } } ] ], [ - 16898, + 17340, [ { - "TestLessThan": { + "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": 0 + "offset": -1 } }, "rhs": { - "Immediate": "0x100000000000000000000000000000000" + "Immediate": "0x10000000000000000" }, - "dst": { + "quotient": { "register": "AP", - "offset": -1 + "offset": 0 + }, + "remainder": { + "register": "AP", + "offset": 1 } } } ] ], [ - 16920, + 17351, [ { - "WideMul128": { + "DivMod": { "lhs": { "Deref": { - "register": "FP", - "offset": -7 + "register": "AP", + "offset": 2 } }, "rhs": { - "Deref": { - "register": "FP", - "offset": -5 - } + "Immediate": "0x100000000000000000000000000000000" }, - "high": { + "quotient": { "register": "AP", - "offset": 0 + "offset": -1 }, - "low": { + "remainder": { "register": "AP", - "offset": 1 + "offset": -656 } } } ] ], [ - 16922, + 17360, [ { "DivMod": { "lhs": { "Deref": { - "register": "FP", - "offset": -7 + "register": "AP", + "offset": -657 } }, "rhs": { @@ -32295,7 +34821,7 @@ ] ], [ - 16932, + 17370, [ { "DivMod": { @@ -32321,7 +34847,7 @@ ] ], [ - 16943, + 17381, [ { "DivMod": { @@ -32339,247 +34865,158 @@ "offset": -1 }, "remainder": { - "register": "AP", - "offset": -13 + "register": "FP", + "offset": -7 } } } ] ], [ - 16953, + 17390, [ { - "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": 0 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, + "AllocSegment": { "dst": { "register": "AP", - "offset": -1 + "offset": 0 } } } ] ], [ - 16972, + 17407, [ { - "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": 0 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, + "AllocSegment": { "dst": { "register": "AP", - "offset": -1 + "offset": 0 } } } ] ], [ - 16995, + 17464, [ { - "TestLessThan": { - "lhs": { + "SystemCall": { + "system": { "Deref": { - "register": "AP", - "offset": 0 + "register": "FP", + "offset": -4 } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "dst": { - "register": "AP", - "offset": -1 } } } ] ], [ - 17014, + 17471, [ { - "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": 0 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" + "AllocConstantSize": { + "size": { + "Immediate": "0x4" }, "dst": { "register": "AP", - "offset": -1 + "offset": 0 } } } ] ], [ - 17033, + 17475, [ { - "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": 0 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, + "AllocSegment": { "dst": { "register": "AP", - "offset": -1 + "offset": 0 } } } ] ], [ - 17056, + 17510, [ { - "TestLessThan": { - "lhs": { + "SystemCall": { + "system": { "Deref": { - "register": "AP", - "offset": 0 + "register": "FP", + "offset": 1 } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "dst": { - "register": "AP", - "offset": -1 } } } ] ], [ - 17078, + 17583, [ { - "Uint512DivModByUint256": { - "dividend0": { - "Deref": { - "register": "AP", - "offset": -4 - } - }, - "dividend1": { - "Deref": { - "register": "AP", - "offset": -3 - } - }, - "dividend2": { + "DivMod": { + "lhs": { "Deref": { "register": "AP", "offset": -2 } }, - "dividend3": { + "rhs": { "Deref": { "register": "AP", "offset": -1 } }, - "divisor0": { - "Deref": { - "register": "FP", - "offset": -4 - } - }, - "divisor1": { - "Deref": { - "register": "FP", - "offset": -3 - } - }, - "quotient0": { - "register": "AP", - "offset": 0 - }, - "quotient1": { - "register": "AP", - "offset": 1 - }, - "quotient2": { - "register": "AP", - "offset": 2 - }, - "quotient3": { - "register": "AP", - "offset": 3 - }, - "remainder0": { + "quotient": { "register": "AP", - "offset": 4 + "offset": 5 }, - "remainder1": { + "remainder": { "register": "AP", - "offset": 5 + "offset": 6 } } } ] ], [ - 17096, + 17589, [ { - "WideMul128": { + "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": -19 + "offset": 0 } }, "rhs": { - "Deref": { - "register": "FP", - "offset": -4 - } - }, - "high": { - "register": "AP", - "offset": -9 + "Immediate": "0x10000000000000000" }, - "low": { + "dst": { "register": "AP", - "offset": -10 + "offset": -3 } } - }, + } + ] + ], + [ + 17656, + [ { "WideMul128": { "lhs": { "Deref": { - "register": "AP", - "offset": -18 + "register": "FP", + "offset": -6 } }, "rhs": { @@ -32590,97 +35027,103 @@ }, "high": { "register": "AP", - "offset": -7 + "offset": 0 }, "low": { "register": "AP", - "offset": -8 + "offset": 1 } } - }, + } + ] + ], + [ + 17658, + [ { - "WideMul128": { + "DivMod": { "lhs": { "Deref": { - "register": "AP", - "offset": -19 + "register": "FP", + "offset": -6 } }, "rhs": { - "Deref": { - "register": "FP", - "offset": -3 - } + "Immediate": "0x10000000000000000" }, - "high": { + "quotient": { "register": "AP", - "offset": -5 + "offset": 1 }, - "low": { + "remainder": { "register": "AP", - "offset": -6 + "offset": 0 } } - }, + } + ] + ], + [ + 17668, + [ { - "WideMul128": { + "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -18 + "offset": -1 } }, "rhs": { - "Deref": { - "register": "FP", - "offset": -3 - } + "Immediate": "0x10000000000000000" }, - "high": { + "quotient": { "register": "AP", - "offset": -3 + "offset": 0 }, - "low": { + "remainder": { "register": "AP", - "offset": -4 + "offset": 1 } } - }, + } + ] + ], + [ + 17679, + [ { - "WideMul128": { + "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -17 + "offset": 2 } }, "rhs": { - "Deref": { - "register": "FP", - "offset": -4 - } + "Immediate": "0x100000000000000000000000000000000" }, - "high": { + "quotient": { "register": "AP", "offset": -1 }, - "low": { + "remainder": { "register": "AP", - "offset": -2 + "offset": -13 } } } ] ], [ - 17125, + 17688, [ { - "TestLessThan": { + "WideMul128": { "lhs": { "Deref": { - "register": "AP", - "offset": -35 + "register": "FP", + "offset": -6 } }, "rhs": { @@ -32689,7 +35132,11 @@ "offset": -3 } }, - "dst": { + "high": { + "register": "AP", + "offset": 0 + }, + "low": { "register": "AP", "offset": 1 } @@ -32698,23 +35145,24 @@ ] ], [ - 17137, + 17690, [ { - "TestLessThan": { + "DivMod": { "lhs": { "Deref": { - "register": "AP", - "offset": -35 + "register": "FP", + "offset": -6 } }, "rhs": { - "Deref": { - "register": "FP", - "offset": -4 - } + "Immediate": "0x10000000000000000" }, - "dst": { + "quotient": { + "register": "AP", + "offset": 1 + }, + "remainder": { "register": "AP", "offset": 0 } @@ -32723,14 +35171,14 @@ ] ], [ - 17152, + 17700, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -41 + "offset": -1 } }, "rhs": { @@ -32738,77 +35186,102 @@ }, "quotient": { "register": "AP", - "offset": 1 + "offset": 0 }, "remainder": { "register": "AP", - "offset": 0 + "offset": 1 } } } ] ], [ - 17162, + 17711, [ { "DivMod": { "lhs": { "Deref": { "register": "AP", - "offset": -1 + "offset": 2 } }, "rhs": { - "Immediate": "0x10000000000000000" + "Immediate": "0x100000000000000000000000000000000" }, "quotient": { "register": "AP", - "offset": 0 + "offset": -1 }, "remainder": { "register": "AP", - "offset": 1 + "offset": -13 } } } ] ], [ - 17173, + 17721, [ { - "DivMod": { + "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": 2 + "offset": 0 } }, "rhs": { "Immediate": "0x100000000000000000000000000000000" }, - "quotient": { + "dst": { "register": "AP", "offset": -1 + } + } + } + ] + ], + [ + 17743, + [ + { + "WideMul128": { + "lhs": { + "Deref": { + "register": "FP", + "offset": -5 + } }, - "remainder": { + "rhs": { + "Deref": { + "register": "FP", + "offset": -4 + } + }, + "high": { "register": "AP", - "offset": -38 + "offset": 0 + }, + "low": { + "register": "AP", + "offset": 1 } } } ] ], [ - 17182, + 17745, [ { "DivMod": { "lhs": { "Deref": { - "register": "AP", - "offset": -57 + "register": "FP", + "offset": -5 } }, "rhs": { @@ -32827,7 +35300,7 @@ ] ], [ - 17192, + 17755, [ { "DivMod": { @@ -32853,7 +35326,7 @@ ] ], [ - 17203, + 17766, [ { "DivMod": { @@ -32872,99 +35345,94 @@ }, "remainder": { "register": "AP", - "offset": -55 + "offset": -13 } } } ] ], [ - 17212, + 17776, [ { - "DivMod": { + "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": -72 + "offset": 0 } }, "rhs": { - "Immediate": "0x10000000000000000" - }, - "quotient": { - "register": "AP", - "offset": 1 + "Immediate": "0x100000000000000000000000000000000" }, - "remainder": { + "dst": { "register": "AP", - "offset": 0 + "offset": -1 } } } ] ], [ - 17222, + 17799, [ { - "DivMod": { + "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": -1 + "offset": 0 } }, "rhs": { - "Immediate": "0x10000000000000000" - }, - "quotient": { - "register": "AP", - "offset": 0 + "Immediate": "0x100000000000000000000000000000000" }, - "remainder": { + "dst": { "register": "AP", - "offset": 1 + "offset": -1 } } } ] ], [ - 17233, + 17821, [ { - "DivMod": { + "WideMul128": { "lhs": { "Deref": { - "register": "AP", - "offset": 2 + "register": "FP", + "offset": -5 } }, "rhs": { - "Immediate": "0x100000000000000000000000000000000" + "Deref": { + "register": "FP", + "offset": -3 + } }, - "quotient": { + "high": { "register": "AP", - "offset": -1 + "offset": 0 }, - "remainder": { + "low": { "register": "AP", - "offset": -74 + "offset": 1 } } } ] ], [ - 17242, + 17823, [ { "DivMod": { "lhs": { "Deref": { - "register": "AP", - "offset": -88 + "register": "FP", + "offset": -5 } }, "rhs": { @@ -32983,7 +35451,7 @@ ] ], [ - 17252, + 17833, [ { "DivMod": { @@ -33009,7 +35477,7 @@ ] ], [ - 17263, + 17844, [ { "DivMod": { @@ -33028,92 +35496,80 @@ }, "remainder": { "register": "AP", - "offset": -87 + "offset": -13 } } } ] ], [ - 17272, + 17854, [ { - "DivMod": { + "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": -103 + "offset": 0 } }, "rhs": { - "Immediate": "0x10000000000000000" - }, - "quotient": { - "register": "AP", - "offset": 1 + "Immediate": "0x100000000000000000000000000000000" }, - "remainder": { + "dst": { "register": "AP", - "offset": 0 + "offset": -1 } } } ] ], [ - 17282, + 17878, [ { - "DivMod": { + "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": -1 + "offset": 0 } }, "rhs": { - "Immediate": "0x10000000000000000" - }, - "quotient": { - "register": "AP", - "offset": 0 + "Immediate": "0x100000000000000000000000000000000" }, - "remainder": { + "dst": { "register": "AP", - "offset": 1 + "offset": -1 } } } ] ], [ - 17293, + 17903, [ { - "DivMod": { + "TestLessThan": { "lhs": { "Deref": { "register": "AP", - "offset": 2 + "offset": 0 } }, "rhs": { "Immediate": "0x100000000000000000000000000000000" }, - "quotient": { + "dst": { "register": "AP", "offset": -1 - }, - "remainder": { - "register": "AP", - "offset": -106 } } } ] ], [ - 17307, + 17927, [ { "TestLessThan": { @@ -33135,7 +35591,7 @@ ] ], [ - 17425, + 18045, [ { "AllocSegment": { @@ -33148,7 +35604,7 @@ ] ], [ - 17448, + 18068, [ { "TestLessThanOrEqual": { @@ -33173,7 +35629,7 @@ ] ], [ - 17523, + 18143, [ { "AllocSegment": { @@ -33186,7 +35642,7 @@ ] ], [ - 17578, + 18198, [ { "DivMod": { @@ -33215,7 +35671,7 @@ ] ], [ - 17584, + 18204, [ { "TestLessThan": { @@ -33237,7 +35693,7 @@ ] ], [ - 17597, + 18217, [ { "TestLessThan": { @@ -33259,7 +35715,7 @@ ] ], [ - 17607, + 18227, [ { "TestLessThan": { @@ -33281,7 +35737,7 @@ ] ], [ - 17655, + 18275, [ { "DivMod": { @@ -33310,7 +35766,7 @@ ] ], [ - 17661, + 18281, [ { "TestLessThan": { @@ -33332,7 +35788,7 @@ ] ], [ - 17677, + 18297, [ { "TestLessThan": { @@ -33354,7 +35810,7 @@ ] ], [ - 17687, + 18307, [ { "TestLessThan": { @@ -33376,7 +35832,7 @@ ] ], [ - 17710, + 18330, [ { "AllocSegment": { @@ -33389,7 +35845,7 @@ ] ], [ - 17724, + 18344, [ { "AllocSegment": { @@ -33402,7 +35858,7 @@ ] ], [ - 17743, + 18363, [ { "AllocSegment": { @@ -33415,7 +35871,7 @@ ] ], [ - 17757, + 18377, [ { "AllocSegment": { diff --git a/crates/blockifier/feature_contracts/cairo1/compiled/test_contract.sierra.json b/crates/blockifier/feature_contracts/cairo1/compiled/test_contract.sierra.json deleted file mode 100644 index afd5bf7390..0000000000 --- a/crates/blockifier/feature_contracts/cairo1/compiled/test_contract.sierra.json +++ /dev/null @@ -1,6937 +0,0 @@ -{ - "sierra_program": [ - "0x1", - "0x6", - "0x0", - "0x2", - "0x7", - "0x0", - "0x705", - "0xfb", - "0x144", - "0x52616e6765436865636b", - "0x800000000000000100000000000000000000000000000000", - "0x75313238", - "0x800000000000000700000000000000000000000000000000", - "0x537472756374", - "0x800000000000000700000000000000000000000000000005", - "0x0", - "0x2907a9767b8e0b68c23345eea8650b1366373b598791523a07fddaa450ba526", - "0x1", - "0x426f78", - "0x800000000000000700000000000000000000000000000001", - "0x5", - "0x800000000000000700000000000000000000000000000003", - "0x25e2ca4b84968c2d8b83ef476ca8549410346b00836ce79beaf538155990bb2", - "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", - "0x4", - "0x42697477697365", - "0x556e696e697469616c697a6564", - "0x800000000000000200000000000000000000000000000001", - "0x6", - "0x436f6e7374", - "0x800000000000000000000000000000000000000000000002", - "0x2b", - "0x2", - "0x753235365f737562204f766572666c6f77", - "0x25", - "0x37", - "0x800000000000000000000000000000000000000000000003", - "0xf", - "0xc", - "0xe", - "0xd", - "0x483ada7726a3c4655da4fbfc0e1108a8", - "0x79be667ef9dcbbac55a06295ce870b07", - "0x29bfcdb2dce28d959f2815b16f81798", - "0xfd17b448a68554199c47d08ffb10d4b8", - "0xb", - "0xa", - "0x9", - "0x8", - "0x7", - "0x3", - "0xae", - "0x1d", - "0x1f", - "0x1e", - "0x10000000000000000", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e16", - "0x2bce33576b315ececbb6406837bf51f5", - "0x23", - "0x22", - "0x553132384d756c47756172616e746565", - "0x6b17d1f2e12c4247f8bce6e563a440f2", - "0x77037d812deb33a0f4a13945d898c296", - "0x26", - "0x4e6f6e5a65726f", - "0x29", - "0x28", - "0x5369676e6174757265206f7574206f662072616e6765", - "0xffffffff00000000ffffffffffffffff", - "0xbce6faada7179e84f3b9cac2fc632551", - "0x496e76616c6964207369676e6174757265", - "0x66656c74323532", - "0x800000000000000700000000000000000000000000000002", - "0x3233063c5dc6197e9bf4ddc53b925e10907665cf58255b7899f8212442d4605", - "0x2c", - "0x800000000000000f00000000000000000000000000000001", - "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", - "0x4172726179", - "0x800000000000000300000000000000000000000000000001", - "0x800000000000000300000000000000000000000000000003", - "0x2e", - "0x2f", - "0x456e756d", - "0x1d8a68005db1b26d0d9f54faae1798d540e7df6326fae758cc2cf8f7ee88e72", - "0x2d", - "0x30", - "0x536563703235366b31506f696e74", - "0x3179e7829d19e62b12c79010203ceee40c98166e97eb104c25ad1adb6b9675a", - "0x32", - "0x33", - "0x34", - "0x3c7b5436891664778e6019991e6bd154eeab5d43a552b1f19485dec008095d3", - "0x35", - "0x3b", - "0x3a", - "0x3d", - "0x14ef93a95bec47ff4e55863055b7a948870fa13be1cbddd481656bdaf5facc2", - "0x38", - "0xfffffffffffffffffffffffffffffffe", - "0xbaaedce6af48a03bbfd25e8cd0364141", - "0x753332", - "0x800000000000000700000000000000000000000000000011", - "0x3c", - "0x20", - "0x10", - "0x60", - "0x4f", - "0x80000000", - "0x7533325f6d756c204f766572666c6f77", - "0x7533325f616464204f766572666c6f77", - "0x800000", - "0x1000000", - "0x4c", - "0x8000", - "0x10000", - "0x49", - "0x80", - "0x100", - "0x46", - "0x50", - "0x8000000000000000", - "0x753634", - "0x100000000", - "0x10000000000", - "0x1000000000000", - "0x100000000000000", - "0x4b656363616b206c61737420696e70757420776f7264203e3762", - "0x61", - "0x11", - "0x313d53fcef2616901e3fd6801087e8d55f5cb59357e1fc8b603b82ae0af064c", - "0x62", - "0x66", - "0x38b0179dda7eba3d95708820abf10d3d4f66e97d9a9013dc38d712dce2af15", - "0x64", - "0x800000000000000700000000000000000000000000000004", - "0x3342418ef16b3e2799b906b1e4e89dbb9b111332dd44f72458ce44f9895b508", - "0x38f1b5bca324642b144da837412e9d82e31937ed4bbe21a1ebccb0c3d3d8d36", - "0x7533325f737562204f766572666c6f77", - "0x6d232c016ef1b12aec4b7f88cc0b3ab662be3b7dd7adbce5209fcfdbd42a504", - "0x45635374617465", - "0x4b5810004d9272776dec83ecc20c19353453b956e594188890b48467cb53c19", - "0x3dbce56de34e1cfe252ead5a1f14fd261d520d343ff6b7652174e62976ef44d", - "0x4563506f696e74", - "0x6e", - "0x4fad269cbf860980e38768fe9cb6b0b9ab03ee3fe84cfde2eccce597c874fd8", - "0x654fd7e67a123dd13868093b3b7777f1ffef596c2e324f25ceaf9146698482c", - "0x1671f96113fa573e5b6df9aef6a004dbf7cc3c475398dd3be1b2590f1f9cdd9", - "0x72", - "0x75", - "0x7538", - "0x53746f726167654261736541646472657373", - "0x3c4930bb381033105f3ca15ccded195c90cd2af5baa0e1ceb36fde292df7652", - "0x76", - "0x34482b42d8542e3c880c5c93d387fb8b01fe2a5d54b6f50d62fe82d9e6c2526", - "0x2691cb735b18f3f656c3b82bd97a32b65d15019b64117513f8604d1e06fe58b", - "0x7265637572736976655f6661696c", - "0x4469766973696f6e2062792030", - "0x32564d7e0fe091d49b4c20f4632191e4ed6986bf993849879abfef9465def25", - "0x62c83572d28cb834a3de3c1e94977a4191469a4a8c26d1d7bc55305e640ed5", - "0x3288d594b9a45d15bb2fcb7903f06cdb06b27f0ba88186ec4cfaa98307cb972", - "0x7f", - "0xa853c166304d20fb0711becf2cbdf482dee3cac4e9717d040b7a7ab1df7eec", - "0x87", - "0x84", - "0x86", - "0x85", - "0x177e60492c5a8242f76f07bfe3661bd", - "0xb292a619339f6e567a305c951c0dcbcc", - "0x42d16e47f219f9e98e76e09d8770b34a", - "0xe59ec2a17ce5bd2dab2abebdf89a62e2", - "0x8d", - "0x8a", - "0x8c", - "0x8b", - "0xe3b0c44298fc1c149afbf4c8996fb924", - "0x87d9315798aaa3a5ba01775787ced05e", - "0xaaf7b4e09fc81d6d1aa546e8365d525d", - "0x27ae41e4649b934ca495991b7852b855", - "0x93", - "0x90", - "0x92", - "0x91", - "0x4aaec73635726f213fb8a9e64da3b86", - "0x49288242", - "0x6e1cda979008bfaf874ff796eb3bb1c0", - "0x32e41495a944d0045b522eba7240fad5", - "0x99", - "0x96", - "0x98", - "0x97", - "0xdb0a2e6710c71ba80afeb3abdf69d306", - "0x502a43ce77c6f5c736a82f847fa95f8c", - "0x2d483fe223b12b91047d83258a958b0f", - "0xce729c7704f4ddf2eaaf0b76209fe1b0", - "0x9d", - "0x9c", - "0x536563703235367231506f696e74", - "0xffffffff000000010000000000000000", - "0xffffffffffffffffffffffff", - "0xcb47311929e7a903ce831cb2b3e67fe265f121b394a36bc46c17cf352547fc", - "0x9b", - "0x185fda19bc33857e9f1d92d61312b69416f20cf740fa3993dcc2de228a6671d", - "0x9f", - "0xf83fa82126e7aeaf5fe12fff6a0f4a02d8a185bf5aaee3d10d1c4e751399b4", - "0xa0", - "0x107a3e65b6e33d1b25fa00c80dfe693f414350005bc697782c25eaac141fedd", - "0xa8", - "0xa5", - "0xa7", - "0xa6", - "0x4ac5e5c0c0e8a4871583cc131f35fb49", - "0x4c8e4fbc1fbb1dece52185e532812c4f", - "0x7a5f81cf3ee10044320a0d03b62d3e9a", - "0xc2b7f60e6a8b84965830658f08f7410c", - "0xac", - "0xab", - "0x100000000000000000000000000000000", - "0xe888fbb4cf9ae6254f19ba12e6d9af54", - "0x788f195a6f509ca3e934f78d7a71dd85", - "0xaf", - "0xb3", - "0xb2", - "0x556e657870656374656420636f6f7264696e61746573", - "0x767410c1", - "0xbb448978bd42b984d7de5970bcaf5c43", - "0xb9", - "0xb6", - "0xb8", - "0xb7", - "0x8e182ca967f38e1bd6a49583f43f1876", - "0xf728b4fa42485e3a0a5d2f346baa9455", - "0xe3e70682c2094cac629f6fbed82c07cd", - "0x8e031ab54fc0c4a8f0dc94fad0d0611", - "0x496e76616c696420617267756d656e74", - "0xbe", - "0xbd", - "0x53686f756c64206265206e6f6e65", - "0xffffffffffffffffffffffffffffffff", - "0xfffffffffffffffffffffffefffffc2f", - "0xe8", - "0xe7", - "0x61be55a8", - "0x800000000000000700000000000000000000000000000009", - "0x536e617073686f74", - "0xc3", - "0x336711c2797eda3aaf8c07c5cf7b92162501924a7090b25482d45dd3a24ddce", - "0xc4", - "0x536861323536537461746548616e646c65", - "0xc5", - "0xc6", - "0x324f33e2d695adb91665eafd5b62ec62f181e09c2e0e60401806dcc4bb3fa1", - "0xc7", - "0x800000000000000000000000000000000000000000000009", - "0xc2", - "0xd2", - "0xd1", - "0xd0", - "0xcf", - "0xce", - "0xcd", - "0xcc", - "0xcb", - "0x5be0cd19", - "0x1f83d9ab", - "0x9b05688c", - "0x510e527f", - "0xa54ff53a", - "0x3c6ef372", - "0xbb67ae85", - "0x6a09e667", - "0x176a53827827a9b5839f3d68f1c2ed4673066bf89e920a3d4110d3e191ce66b", - "0xd3", - "0x61616161", - "0x496e646578206f7574206f6620626f756e6473", - "0x57726f6e67206572726f72206d7367", - "0x496e76616c696420696e707574206c656e677468", - "0x53686f756c64206661696c", - "0xa5963aa610cb75ba273817bce5f8c48f", - "0x57726f6e6720686173682076616c7565", - "0x587f7cc3722e9654ea3963d5fe8c0748", - "0xdd", - "0x3f829a4bc463d91621ba418d447cc38c95ddc483f9ccfebae79050eb7b3dcb6", - "0xde", - "0x25e50662218619229b3f53f1dc3253192a0f68ca423d900214253db415a90b4", - "0xe0", - "0xe2", - "0x38b507bf259d96f5c53e8ab8f187781c3d096482729ec2d57f3366318a8502f", - "0xe3", - "0x800000000000000300000000000000000000000000000004", - "0xe4", - "0x3c5ce4d28d473343dbe52c630edf038a582af9574306e1d609e379cd17fc87a", - "0xe5", - "0x424c4f434b5f494e464f5f4d49534d41544348", - "0x54585f494e464f5f4d49534d41544348", - "0x43414c4c45525f4d49534d41544348", - "0x434f4e54524143545f4d49534d41544348", - "0x53454c4543544f525f4d49534d41544348", - "0xef", - "0x1597b831feeb60c71f259624b79cf66995ea4f7e383403583674ab9c33b9cec", - "0xf0", - "0xf1", - "0x21afb2f280564fc34ddb766bf42f7ca36154bbba994fbc0f0235cd873ace36a", - "0xf2", - "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", - "0xf4", - "0xf5", - "0x45b67c75542d42836cef6c02cca4dbff4a80a8621fa521cbfff1b2dd4af35a", - "0xf6", - "0xfd", - "0x127", - "0x436f6e747261637441646472657373", - "0x800000000000000700000000000000000000000000000006", - "0x7d4d99e9ed8d285b5c61b493cedb63976bc3d9da867933d829f49ce838b5e7", - "0xf9", - "0xf8", - "0xfa", - "0xfb", - "0x80000000000000070000000000000000000000000000000e", - "0x348a62b7a38c0673e61e888d83a3ac1bf334ee7361a8514593d3d9532ed8b39", - "0x53797374656d", - "0xff", - "0x1ce0be45cbaa9547dfece0f040e22ec60de2d0d5a6c79fa5514066dfdbb7ca6", - "0x3128e9bfd21b6f544f537413d7dd38a8f2e017a3b81c1a4bcf8f51a64d0dc3d", - "0x103", - "0x33ecdfa3f249457fb2ae8b6a6713b3069fa0c38450e972297821b52ba929029", - "0x104", - "0x1d49f7a4b277bf7b55a2664ce8cef5d6922b5ffb806b89644b9e0cdbbcac378", - "0x106", - "0x13fdd7105045794a99550ae1c4ac13faa62610dfab62c16422bfcf5803baa6e", - "0x107", - "0x7536345f616464204f766572666c6f77", - "0x45634f70", - "0x7772be8b80a8a33dc6c1f9a6ab820c02e537c73e859de67f288c70f92571bb", - "0x502e0ef33256f20a8b605b438b5e2edbb11c60e139bf20fc591a02a09f3de2", - "0x3dd8e25703b1ccf5468890414136ead65670ac6bbdf7dc850c98a118e734315", - "0x110", - "0x506564657273656e", - "0x6661696c", - "0x36e3bf0277e7c1bb9cd72f230a2d616855c6cadbec152c14c3477ef805df7e2", - "0x114", - "0x28d17edd223fdeb248de26443744906e8d20b0a98f7aaefa59db1e6e43c2039", - "0x115", - "0x7820213d2079", - "0x73756363657373", - "0x800000000000000f00000000000000000000000000000003", - "0x3d44efdcfc7ca7740d5114d8d35abb1eca654dfc08005ed0a54bad41104f880", - "0x119", - "0x537175617368656446656c7432353244696374", - "0x46656c7432353244696374", - "0x800000000000000100000000000000000000000000000001", - "0x5365676d656e744172656e61", - "0x436c61737348617368", - "0x4661696c656420746f20646573657269616c697a6520706172616d202334", - "0x4661696c656420746f20646573657269616c697a6520706172616d202335", - "0x800000000000000f00000000000000000000000000000002", - "0xcc5e86243f861d2d64b08c35db21013e773ac5cf10097946fe0011304886d5", - "0x122", - "0x2271e6a0c1b1931cf78a8bfd030df986f9544c426af3bd6023dc55382237cf7", - "0x124", - "0x1d2ae7ecff8f8db67bf542f1d1f8201ff21e9f36f780ef569bcc7bc74ab634c", - "0x125", - "0x3808c701a5d13e100ab11b6c02f91f752ecae7e420d21b56c90ec0a475cc7e5", - "0x1cbd0cd3f779a7c0d3cdc804f89c39bcf71a85b43d3cf8a042111f0bc2ddf63", - "0x909b0519d7c88c554565d942b48b326c8dcbd2e2915301868fb8159e606aa3", - "0x12a", - "0x4661696c656420746f20646573657269616c697a6520706172616d202333", - "0x17b6ecc31946835b0d9d92c2dd7a9c14f29af0371571ae74a1b228828b2242", - "0x12f", - "0x34f9bd7c6cb2dd4263175964ad75f1ff1461ddc332fbfb274e0fb2a5d7ab968", - "0x130", - "0x29d7d57c04a880978e7b3689f6218e507f3be17588744b58dc17762447ad0e7", - "0x132", - "0x4f7074696f6e3a3a756e77726170206661696c65642e", - "0x4661696c656420746f20646573657269616c697a6520706172616d202331", - "0x4661696c656420746f20646573657269616c697a6520706172616d202332", - "0x4f7574206f6620676173", - "0x4275696c74696e436f737473", - "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", - "0x13c", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x53746f7261676541646472657373", - "0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511", - "0x4761734275696c74696e", - "0x2a5", - "0x7265766f6b655f61705f747261636b696e67", - "0x77697468647261775f676173", - "0x6272616e63685f616c69676e", - "0x7374727563745f6465636f6e737472756374", - "0x656e61626c655f61705f747261636b696e67", - "0x73746f72655f74656d70", - "0x61727261795f736e617073686f745f706f705f66726f6e74", - "0x756e626f78", - "0x72656e616d65", - "0x656e756d5f696e6974", - "0x142", - "0x6a756d70", - "0x7374727563745f636f6e737472756374", - "0x656e756d5f6d61746368", - "0x1ad5911ecb88aa4a50482c4de3232f196cfcaf7bd4e9c96d22b283733045007", - "0x64697361626c655f61705f747261636b696e67", - "0x64726f70", - "0x141", - "0x61727261795f6e6577", - "0x636f6e73745f61735f696d6d656469617465", - "0x140", - "0x61727261795f617070656e64", - "0x13f", - "0x143", - "0x6765745f6275696c74696e5f636f737473", - "0x13e", - "0x77697468647261775f6761735f616c6c", - "0x13d", - "0x647570", - "0x73746f726167655f77726974655f73797363616c6c", - "0x73746f726167655f726561645f73797363616c6c", - "0x736e617073686f745f74616b65", - "0x13b", - "0x13a", - "0x139", - "0x138", - "0x137", - "0x136", - "0x135", - "0x616c6c6f635f6c6f63616c", - "0x66696e616c697a655f6c6f63616c73", - "0x73746f72655f6c6f63616c", - "0x21adb5788e32c84f69a1863d85ef9394b7bf761a0ce1190f826984e5075c371", - "0x133", - "0x66756e6374696f6e5f63616c6c", - "0x131", - "0x63616c6c5f636f6e74726163745f73797363616c6c", - "0x12e", - "0x134", - "0x7536345f7472795f66726f6d5f66656c74323532", - "0x12d", - "0x12c", - "0x12b", - "0x6765745f626c6f636b5f686173685f73797363616c6c", - "0x21", - "0x128", - "0x126", - "0x123", - "0x121", - "0x120", - "0x129", - "0x636c6173735f686173685f7472795f66726f6d5f66656c74323532", - "0x11f", - "0x6c6962726172795f63616c6c5f73797363616c6c", - "0x24", - "0x7265706c6163655f636c6173735f73797363616c6c", - "0x73656e645f6d6573736167655f746f5f6c315f73797363616c6c", - "0x11e", - "0x66656c743235325f646963745f6e6577", - "0x11d", - "0x11c", - "0x66656c743235325f69735f7a65726f", - "0x11b", - "0x626f6f6c5f6e6f745f696d706c", - "0x6465706c6f795f73797363616c6c", - "0x11a", - "0x27", - "0x66656c743235325f737562", - "0x118", - "0x117", - "0x2a", - "0x116", - "0x113", - "0x636f6e74726163745f616464726573735f746f5f66656c74323532", - "0x112", - "0x111", - "0x753132385f746f5f66656c74323532", - "0x10f", - "0x10e", - "0x31", - "0x10d", - "0x10c", - "0x73746f726167655f626173655f616464726573735f636f6e7374", - "0x1275130f95dda36bcbb6e9d28796c1d7e10b6e9fd5ed083e0ede4b12f613528", - "0x73746f726167655f616464726573735f66726f6d5f62617365", - "0x66656c743235325f616464", - "0x7536345f6571", - "0x656d69745f6576656e745f73797363616c6c", - "0x10b", - "0x7536345f6f766572666c6f77696e675f616464", - "0x10a", - "0x75313238735f66726f6d5f66656c74323532", - "0x108", - "0x105", - "0x102", - "0x7533325f7472795f66726f6d5f66656c74323532", - "0x109", - "0x6765745f657865637574696f6e5f696e666f5f76325f73797363616c6c", - "0xfc", - "0xfe", - "0x753132385f6571", - "0x61727261795f6c656e", - "0x7533325f6571", - "0xf7", - "0xf3", - "0xee", - "0xed", - "0xec", - "0xeb", - "0xea", - "0x101", - "0x636c6173735f686173685f746f5f66656c74323532", - "0xe9", - "0x66656c743235325f646963745f737175617368", - "0x36", - "0xe6", - "0xe1", - "0xdf", - "0x6b656363616b5f73797363616c6c", - "0xdc", - "0xdb", - "0xda", - "0xd9", - "0x61727261795f676574", - "0xd8", - "0xd7", - "0xd6", - "0xd5", - "0xd4", - "0x636f6e73745f61735f626f78", - "0xc9", - "0x7368613235365f73746174655f68616e646c655f696e6974", - "0x39", - "0xc8", - "0x7368613235365f73746174655f68616e646c655f646967657374", - "0xca", - "0xc1", - "0xc0", - "0xbf", - "0x736563703235366b315f6e65775f73797363616c6c", - "0xbc", - "0xbb", - "0xba", - "0xb5", - "0xb4", - "0x736563703235366b315f6765745f78795f73797363616c6c", - "0xb1", - "0xb0", - "0xad", - "0x753132385f736166655f6469766d6f64", - "0xaa", - "0x66656c743235325f6d756c", - "0xa9", - "0xa4", - "0xa3", - "0xa2", - "0xa1", - "0x7365637032353672315f6e65775f73797363616c6c", - "0x9e", - "0x9a", - "0x95", - "0x94", - "0x7365637032353672315f6765745f78795f73797363616c6c", - "0x8f", - "0x8e", - "0x89", - "0x88", - "0x83", - "0x82", - "0x81", - "0x7e", - "0x7533325f6f766572666c6f77696e675f737562", - "0x61727261795f706f705f66726f6e74", - "0x7d", - "0x7c", - "0x7b", - "0x7a", - "0x79", - "0x78", - "0x706564657273656e", - "0xad292db4ff05a993c318438c1b6c8a8303266af2da151aa28ccece6726f1f1", - "0x77", - "0x74", - "0x2679d68052ccd03a53755ca9169677965fbd93e489df62f5f40d4f03c24f7a4", - "0x73", - "0x62697477697365", - "0x71", - "0x70", - "0x65635f706f696e745f7472795f6e65775f6e7a", - "0x6f", - "0x756e777261705f6e6f6e5f7a65726f", - "0x6d", - "0x6c", - "0x65635f706f696e745f69735f7a65726f", - "0x65635f73746174655f696e6974", - "0x6a", - "0x65635f73746174655f6164645f6d756c", - "0x6b", - "0x65635f73746174655f7472795f66696e616c697a655f6e7a", - "0x65635f706f696e745f7a65726f", - "0x65635f73746174655f616464", - "0x65635f706f696e745f756e77726170", - "0x161bc82433cf4a92809836390ccd14921dfc4dc410cf3d2adbfee5e21ecfec8", - "0x69", - "0x61727261795f736c696365", - "0x68", - "0x67", - "0x65", - "0x63", - "0x5f", - "0x7533325f736166655f6469766d6f64", - "0x5e", - "0x5d", - "0x5c", - "0x5b", - "0x5a", - "0x59", - "0x58", - "0x57", - "0x56", - "0x55", - "0x54", - "0x53", - "0x52", - "0x7536345f69735f7a65726f", - "0x7536345f736166655f6469766d6f64", - "0x3e", - "0x4e", - "0x4d", - "0x4b", - "0x4a", - "0x48", - "0x47", - "0x45", - "0x7533325f776964655f6d756c", - "0x646f776e63617374", - "0x7533325f6f766572666c6f77696e675f616464", - "0x44", - "0x43", - "0x42", - "0x41", - "0x7533325f746f5f66656c74323532", - "0x40", - "0x3f", - "0x61727261795f736e617073686f745f6d756c74695f706f705f66726f6e74", - "0x7368613235365f70726f636573735f626c6f636b5f73797363616c6c", - "0x753132385f6f766572666c6f77696e675f737562", - "0x753235365f67756172616e7465655f696e765f6d6f645f6e", - "0x753132385f6d756c5f67756172616e7465655f766572696679", - "0x1c", - "0x7365637032353672315f6d756c5f73797363616c6c", - "0x7365637032353672315f6164645f73797363616c6c", - "0x1b", - "0x1a", - "0x19", - "0x18", - "0x17", - "0x16", - "0x15", - "0x14", - "0x13", - "0x12", - "0x393d13543d6033e70e218aad8050e8de40a1dfbac0e80459811df56e3716ce6", - "0x736563703235366b315f6d756c5f73797363616c6c", - "0x736563703235366b315f6164645f73797363616c6c", - "0x696e746f5f626f78", - "0x7370616e5f66726f6d5f7475706c65", - "0x753132385f627974655f72657665727365", - "0x753132385f67756172616e7465655f6d756c", - "0x753132385f6f766572666c6f77696e675f616464", - "0x753531325f736166655f6469766d6f645f62795f75323536", - "0x2d48", - "0xffffffffffffffff", - "0x51", - "0x1ff", - "0x1ec", - "0x1e7", - "0x148", - "0x14d", - "0x1d5", - "0x156", - "0x15b", - "0x17a", - "0x171", - "0x183", - "0x1c4", - "0x198", - "0x1b4", - "0x1ab", - "0x1f2", - "0x31e", - "0x21e", - "0x223", - "0x30b", - "0x306", - "0x231", - "0x236", - "0x255", - "0x24c", - "0x25e", - "0x2f5", - "0x268", - "0x26d", - "0x28c", - "0x283", - "0x295", - "0x2e4", - "0x2aa", - "0x2d4", - "0x2cd", - "0x311", - "0x39c", - "0x33a", - "0x33f", - "0x38b", - "0x387", - "0x359", - "0x379", - "0x370", - "0x38f", - "0x49f", - "0x48f", - "0x487", - "0x477", - "0x3c8", - "0x3cd", - "0x465", - "0x3d7", - "0x3dc", - "0x452", - "0x3e6", - "0x3eb", - "0x43e", - "0x403", - "0x42b", - "0x424", - "0x589", - "0x4bf", - "0x4c4", - "0x576", - "0x571", - "0x4d2", - "0x4d7", - "0x55f", - "0x4e0", - "0x4e5", - "0x504", - "0x4fb", - "0x50d", - "0x54e", - "0x522", - "0x53e", - "0x535", - "0x57c", - "0x68c", - "0x5a7", - "0x5ac", - "0x67b", - "0x677", - "0x5b9", - "0x5be", - "0x666", - "0x5c8", - "0x5cd", - "0x654", - "0x5d7", - "0x5dc", - "0x641", - "0x5e6", - "0x5eb", - "0x62d", - "0x603", - "0x61a", - "0x67f", - "0x705", - "0x6a8", - "0x6ad", - "0x6f4", - "0x6f0", - "0x6c4", - "0x6e2", - "0x6d9", - "0x6f8", - "0x7c1", - "0x723", - "0x728", - "0x7b0", - "0x731", - "0x736", - "0x754", - "0x74c", - "0x75d", - "0x7a0", - "0x771", - "0x791", - "0x788", - "0x80d", - "0x7e6", - "0x7ff", - "0x933", - "0x82d", - "0x832", - "0x920", - "0x91b", - "0x840", - "0x845", - "0x909", - "0x84e", - "0x853", - "0x872", - "0x869", - "0x87b", - "0x8f8", - "0x884", - "0x889", - "0x8e5", - "0x894", - "0x899", - "0x8ae", - "0x8d3", - "0x8ca", - "0x926", - "0x985", - "0x958", - "0x978", - "0x971", - "0x9d5", - "0x9a8", - "0x9c8", - "0x9c1", - "0xa2a", - "0x9f9", - "0xa1c", - "0xa14", - "0xa7b", - "0xa4e", - "0xa6e", - "0xa67", - "0xb19", - "0xa97", - "0xa9c", - "0xb09", - "0xaa6", - "0xaab", - "0xaf8", - "0xac0", - "0xae8", - "0xada", - "0xbb1", - "0xb33", - "0xb38", - "0xb55", - "0xb4e", - "0xb5e", - "0xba2", - "0xb71", - "0xb94", - "0xb8d", - "0xbf3", - "0xbd4", - "0xbe6", - "0xc67", - "0xc0f", - "0xc14", - "0xc57", - "0xc28", - "0xc49", - "0xc42", - "0xcdb", - "0xc83", - "0xc88", - "0xccb", - "0xc9c", - "0xcbd", - "0xcb6", - "0xdb7", - "0xcf7", - "0xcfc", - "0xda6", - "0xda2", - "0xd09", - "0xd0e", - "0xd91", - "0xd18", - "0xd1d", - "0xd7f", - "0xd33", - "0xd6e", - "0xd43", - "0xd58", - "0xd64", - "0xdaa", - "0xe7c", - "0xdd3", - "0xdd8", - "0xe6b", - "0xde2", - "0xde7", - "0xe59", - "0xdf1", - "0xdf6", - "0xe46", - "0xe0d", - "0xe34", - "0xe2c", - "0xeef", - "0xede", - "0xea7", - "0xece", - "0xec5", - "0xf9b", - "0xf0d", - "0xf12", - "0xf8a", - "0xf86", - "0xf75", - "0xf30", - "0xf66", - "0xf5d", - "0xf8e", - "0xff0", - "0xfbf", - "0xfe2", - "0xfda", - "0x106c", - "0x100d", - "0x1012", - "0x105b", - "0x1027", - "0x104c", - "0x1044", - "0x10e9", - "0x1089", - "0x108e", - "0x10d9", - "0x10a2", - "0x10cb", - "0x10c2", - "0x116f", - "0x1105", - "0x110a", - "0x115f", - "0x1115", - "0x111a", - "0x114f", - "0x112e", - "0x1141", - "0x1230", - "0x118b", - "0x1190", - "0x1220", - "0x119b", - "0x11a0", - "0x120f", - "0x120b", - "0x11ad", - "0x11b2", - "0x11fa", - "0x11c7", - "0x11ea", - "0x11e0", - "0x1213", - "0x12cf", - "0x124c", - "0x1251", - "0x12bf", - "0x125b", - "0x1260", - "0x12ae", - "0x1275", - "0x129e", - "0x1293", - "0x1316", - "0x12ec", - "0x12f8", - "0x12fd", - "0x130b", - "0x136d", - "0x1361", - "0x1354", - "0x1343", - "0x1385", - "0x138a", - "0x13e5", - "0x13e1", - "0x139b", - "0x13a0", - "0x13d7", - "0x13d2", - "0x13b3", - "0x13b8", - "0x13c8", - "0x13c3", - "0x13cd", - "0x13dc", - "0x13e9", - "0x1400", - "0x1405", - "0x1657", - "0x1410", - "0x1415", - "0x1644", - "0x163a", - "0x1425", - "0x142a", - "0x1628", - "0x161d", - "0x160f", - "0x15ff", - "0x1444", - "0x1449", - "0x15ee", - "0x1454", - "0x1459", - "0x15dd", - "0x1464", - "0x1469", - "0x15cc", - "0x1472", - "0x1477", - "0x14a8", - "0x149b", - "0x1493", - "0x14b1", - "0x15bc", - "0x14ba", - "0x14bf", - "0x15a9", - "0x159c", - "0x158c", - "0x157a", - "0x14d6", - "0x14db", - "0x1564", - "0x1556", - "0x14ec", - "0x14f1", - "0x1540", - "0x1532", - "0x151f", - "0x150a", - "0x154e", - "0x1572", - "0x15b4", - "0x1632", - "0x164f", - "0x1a56", - "0x169a", - "0x16b2", - "0x16b3", - "0x1a49", - "0x1a3e", - "0x1a13", - "0x1a08", - "0x1737", - "0x1a1d", - "0x176e", - "0x1787", - "0x19f6", - "0x178a", - "0x1a20", - "0x19e9", - "0x19dc", - "0x19cf", - "0x145", - "0x146", - "0x147", - "0x149", - "0x14a", - "0x14b", - "0x14c", - "0x14e", - "0x14f", - "0x150", - "0x151", - "0x152", - "0x153", - "0x154", - "0x155", - "0x157", - "0x158", - "0x159", - "0x1827", - "0x15a", - "0x183f", - "0x15c", - "0x15d", - "0x15e", - "0x15f", - "0x19c2", - "0x160", - "0x161", - "0x162", - "0x163", - "0x164", - "0x1842", - "0x165", - "0x166", - "0x167", - "0x1a28", - "0x168", - "0x169", - "0x16a", - "0x16b", - "0x16c", - "0x16d", - "0x16e", - "0x16f", - "0x170", - "0x172", - "0x173", - "0x174", - "0x175", - "0x176", - "0x177", - "0x178", - "0x179", - "0x17b", - "0x17c", - "0x17d", - "0x17e", - "0x17f", - "0x180", - "0x181", - "0x182", - "0x184", - "0x185", - "0x186f", - "0x186", - "0x187", - "0x1a2a", - "0x188", - "0x189", - "0x18a", - "0x18b", - "0x18c", - "0x18d", - "0x18e", - "0x18f", - "0x190", - "0x191", - "0x192", - "0x193", - "0x194", - "0x195", - "0x196", - "0x197", - "0x199", - "0x19a", - "0x19b", - "0x19c", - "0x19d", - "0x19e", - "0x19f", - "0x1a0", - "0x1a1", - "0x1a2", - "0x1a3", - "0x1a4", - "0x1a5", - "0x1a6", - "0x1a7", - "0x1a8", - "0x1a9", - "0x1aa", - "0x18a5", - "0x1ac", - "0x1ad", - "0x18bd", - "0x1ae", - "0x1af", - "0x1b0", - "0x1b1", - "0x19b5", - "0x1b2", - "0x1b3", - "0x1b5", - "0x1b6", - "0x18c0", - "0x1b7", - "0x1b8", - "0x1b9", - "0x1a2c", - "0x1ba", - "0x1bb", - "0x1bc", - "0x1bd", - "0x1be", - "0x1bf", - "0x1c0", - "0x1c1", - "0x1c2", - "0x1c3", - "0x1c5", - "0x1c6", - "0x1c7", - "0x1c8", - "0x1c9", - "0x1ca", - "0x1cb", - "0x1cc", - "0x1cd", - "0x1ce", - "0x1cf", - "0x1d0", - "0x1d1", - "0x1d2", - "0x1d3", - "0x1d4", - "0x1d6", - "0x1d7", - "0x18ed", - "0x1d8", - "0x1d9", - "0x1a2e", - "0x1da", - "0x1db", - "0x1dc", - "0x1dd", - "0x1de", - "0x1df", - "0x1e0", - "0x1e1", - "0x1e2", - "0x1e3", - "0x1e4", - "0x1e5", - "0x1e6", - "0x1e8", - "0x1e9", - "0x1ea", - "0x1eb", - "0x1ed", - "0x1ee", - "0x1ef", - "0x1f0", - "0x1f1", - "0x1f3", - "0x1f4", - "0x1f5", - "0x1f6", - "0x1f7", - "0x1919", - "0x1f8", - "0x1f9", - "0x1a30", - "0x1fa", - "0x1fb", - "0x1fc", - "0x1fd", - "0x1fe", - "0x200", - "0x201", - "0x202", - "0x203", - "0x204", - "0x205", - "0x206", - "0x207", - "0x208", - "0x209", - "0x20a", - "0x20b", - "0x20c", - "0x20d", - "0x20e", - "0x20f", - "0x210", - "0x211", - "0x212", - "0x213", - "0x214", - "0x215", - "0x216", - "0x217", - "0x218", - "0x219", - "0x21a", - "0x21b", - "0x194b", - "0x21c", - "0x21d", - "0x1a32", - "0x21f", - "0x220", - "0x221", - "0x19aa", - "0x222", - "0x224", - "0x225", - "0x226", - "0x1962", - "0x227", - "0x228", - "0x229", - "0x1998", - "0x22a", - "0x22b", - "0x22c", - "0x1988", - "0x22d", - "0x22e", - "0x197a", - "0x22f", - "0x230", - "0x232", - "0x233", - "0x234", - "0x235", - "0x237", - "0x238", - "0x239", - "0x23a", - "0x23b", - "0x23c", - "0x23d", - "0x23e", - "0x23f", - "0x240", - "0x241", - "0x242", - "0x243", - "0x244", - "0x245", - "0x246", - "0x247", - "0x1a02", - "0x248", - "0x249", - "0x1a26", - "0x24a", - "0x24b", - "0x1a24", - "0x24d", - "0x1a22", - "0x24e", - "0x24f", - "0x250", - "0x251", - "0x252", - "0x253", - "0x254", - "0x256", - "0x257", - "0x258", - "0x259", - "0x25a", - "0x25b", - "0x25c", - "0x25d", - "0x1a9d", - "0x1a95", - "0x1b5f", - "0x1b56", - "0x1b4f", - "0x1aec", - "0x1afd", - "0x1b16", - "0x1b41", - "0x1b32", - "0x1b67", - "0x1bbb", - "0x1bb4", - "0x1bab", - "0x1bc1", - "0x1cfd", - "0x1be4", - "0x1bfb", - "0x1cee", - "0x1cde", - "0x1cd1", - "0x1cbf", - "0x1cb2", - "0x1c37", - "0x1c43", - "0x1c44", - "0x1c61", - "0x1c57", - "0x1c6f", - "0x1ca3", - "0x1c9d", - "0x1ca8", - "0x1e3f", - "0x1d23", - "0x1d39", - "0x1e31", - "0x1e22", - "0x1e16", - "0x1e05", - "0x1df9", - "0x1d74", - "0x1d80", - "0x1d81", - "0x1d9e", - "0x1d94", - "0x1daa", - "0x1def", - "0x1de0", - "0x1dd8", - "0x1f58", - "0x1f48", - "0x1e5d", - "0x1e62", - "0x1f37", - "0x1e6b", - "0x1e70", - "0x1f25", - "0x1e79", - "0x1e7e", - "0x1f12", - "0x1ead", - "0x1e9c", - "0x1e92", - "0x1f0d", - "0x1edd", - "0x1ecc", - "0x1ec2", - "0x1f0a", - "0x1eee", - "0x1f04", - "0x1f84", - "0x1f7b", - "0x1faa", - "0x1fa1", - "0x2024", - "0x201a", - "0x2008", - "0x2002", - "0x2011", - "0x202e", - "0x2040", - "0x2045", - "0x209f", - "0x204d", - "0x2052", - "0x2087", - "0x2082", - "0x2060", - "0x2065", - "0x2078", - "0x2072", - "0x208f", - "0x207c", - "0x208a", - "0x2098", - "0x214a", - "0x2141", - "0x212c", - "0x2117", - "0x2105", - "0x20ff", - "0x210d", - "0x2153", - "0x21f3", - "0x21e3", - "0x2173", - "0x2185", - "0x2181", - "0x218b", - "0x21a0", - "0x2191", - "0x219d", - "0x21b0", - "0x21d2", - "0x21cc", - "0x21da", - "0x22d3", - "0x22c1", - "0x22b8", - "0x22a5", - "0x2292", - "0x2280", - "0x227a", - "0x2289", - "0x22ca", - "0x22e6", - "0x22eb", - "0x233d", - "0x2334", - "0x2327", - "0x2318", - "0x230c", - "0x2371", - "0x2356", - "0x2367", - "0x23db", - "0x238c", - "0x2391", - "0x23d0", - "0x239d", - "0x23a2", - "0x23bf", - "0x23b4", - "0x246a", - "0x23f5", - "0x23fa", - "0x245f", - "0x2406", - "0x240b", - "0x244e", - "0x2441", - "0x242d", - "0x2445", - "0x2439", - "0x24af", - "0x2484", - "0x2489", - "0x24a5", - "0x249d", - "0x2546", - "0x2517", - "0x2511", - "0x250b", - "0x2505", - "0x24ff", - "0x24f9", - "0x24f5", - "0x24fd", - "0x2503", - "0x2509", - "0x250f", - "0x2515", - "0x251b", - "0x252e", - "0x2536", - "0x254c", - "0x256b", - "0x255d", - "0x257a", - "0x25da", - "0x25a9", - "0x259e", - "0x25a5", - "0x25b0", - "0x25cb", - "0x25bc", - "0x25e1", - "0x262d", - "0x2620", - "0x2613", - "0x2606", - "0x2671", - "0x2648", - "0x264e", - "0x2666", - "0x265c", - "0x2695", - "0x269e", - "0x2773", - "0x26c1", - "0x26b2", - "0x277a", - "0x26bd", - "0x26c8", - "0x26da", - "0x26e3", - "0x2763", - "0x2705", - "0x26f7", - "0x276a", - "0x2701", - "0x270c", - "0x275a", - "0x274a", - "0x2741", - "0x2735", - "0x25f", - "0x2795", - "0x279e", - "0x28e5", - "0x260", - "0x27c1", - "0x27b2", - "0x28ec", - "0x27bd", - "0x27c8", - "0x27da", - "0x27e3", - "0x2812", - "0x2807", - "0x27f6", - "0x2818", - "0x2800", - "0x28dd", - "0x261", - "0x262", - "0x263", - "0x264", - "0x28ca", - "0x265", - "0x266", - "0x267", - "0x269", - "0x28ba", - "0x28ac", - "0x26a", - "0x28a0", - "0x2895", - "0x26b", - "0x288b", - "0x2881", - "0x2869", - "0x287a", - "0x2876", - "0x26c", - "0x26e", - "0x26f", - "0x28c2", - "0x270", - "0x28ed", - "0x28fe", - "0x2903", - "0x2954", - "0x290b", - "0x2910", - "0x294a", - "0x2945", - "0x2921", - "0x2926", - "0x293b", - "0x2934", - "0x271", - "0x272", - "0x273", - "0x2940", - "0x274", - "0x294f", - "0x275", - "0x276", - "0x2999", - "0x298e", - "0x297f", - "0x2975", - "0x2988", - "0x29a3", - "0x29d9", - "0x29cd", - "0x29bf", - "0x29ed", - "0x29fc", - "0x2a0b", - "0x277", - "0x2a1a", - "0x278", - "0x2a29", - "0x279", - "0x2a38", - "0x27a", - "0x2a47", - "0x27b", - "0x2a56", - "0x27c", - "0x2a65", - "0x27d", - "0x2a74", - "0x27e", - "0x2a83", - "0x27f", - "0x2a92", - "0x2aa1", - "0x280", - "0x2ab0", - "0x281", - "0x2abf", - "0x2acc", - "0x282", - "0x2bb5", - "0x2ba9", - "0x284", - "0x2b99", - "0x2b8b", - "0x285", - "0x2b77", - "0x2b08", - "0x2b0e", - "0x2b16", - "0x2b28", - "0x2b20", - "0x2b62", - "0x286", - "0x2b57", - "0x2b4d", - "0x287", - "0x2b44", - "0x288", - "0x289", - "0x28a", - "0x28b", - "0x28d", - "0x2ba1", - "0x28e", - "0x28f", - "0x2c25", - "0x290", - "0x291", - "0x292", - "0x293", - "0x294", - "0x296", - "0x297", - "0x2c15", - "0x2c0d", - "0x2c07", - "0x298", - "0x299", - "0x29a", - "0x29b", - "0x2c1c", - "0x29c", - "0x29d", - "0x29e", - "0x29f", - "0x2c41", - "0x2c46", - "0x2c50", - "0x2c55", - "0x2c5c", - "0x2c61", - "0x2c68", - "0x2c6b", - "0x2c72", - "0x2c77", - "0x2c7c", - "0x2c7f", - "0x2c84", - "0x2c87", - "0x2c8e", - "0x2c93", - "0x2c98", - "0x2c9b", - "0x2a0", - "0x2a1", - "0x2a2", - "0x2a3", - "0x2ce2", - "0x2cb3", - "0x2cb8", - "0x2cd7", - "0x2a4", - "0x2cce", - "0x2d37", - "0x2d2c", - "0x2d1c", - "0x2d12", - "0x2d25", - "0x2d41", - "0x32e", - "0x3aa", - "0x4ae", - "0x599", - "0x69a", - "0x713", - "0x7d0", - "0x81c", - "0x943", - "0x993", - "0x9e3", - "0xa39", - "0xa89", - "0xb27", - "0xbbf", - "0xc01", - "0xc75", - "0xce9", - "0xdc5", - "0xe8b", - "0xeff", - "0xfa9", - "0xfff", - "0x107b", - "0x10f7", - "0x117d", - "0x123e", - "0x12dd", - "0x1325", - "0x137e", - "0x13ee", - "0x1667", - "0x1a69", - "0x1aa9", - "0x1ab0", - "0x1b6f", - "0x1bc7", - "0x1d08", - "0x1e49", - "0x1f67", - "0x1f92", - "0x1fb8", - "0x2037", - "0x20a6", - "0x215d", - "0x2202", - "0x22df", - "0x2347", - "0x2380", - "0x23e9", - "0x2478", - "0x24bd", - "0x2588", - "0x263c", - "0x2680", - "0x2783", - "0x28f5", - "0x295b", - "0x29a9", - "0x29e7", - "0x2ad3", - "0x2bc1", - "0x2c31", - "0x2ca7", - "0x2cf1", - "0x17660", - "0x280c01202c05009012024048090120240480800e0180280400600800800", - "0xa81401204c090020220400481001203c0380d00a024048090120380380d", - "0x481c02a0780481d0120400481c02a06c0481a0120580a81903005c04816", - "0xc0090120580a8220300240481602a0840c0090120580a82001207c04810", - "0x481602a0800c0170120580a81f03005c0481602a0900c0090120580a823", - "0xa82803005c0481602a09c0c0170120580a82603005c0481602a0940c017", - "0xc0170120580a80c03005c0481602a0500c0170120580a82903005c04816", - "0xa82e0120b4048100120700a82c0120ac0481602a0a80c0170120580a810", - "0x48100120700a8310300240481602a0c00c0090120580a82f03002404816", - "0x481a0120580a8360300240481602a0d40c0090120580a8020680cc04832", - "0x481602a0ec0c0170120580a83a0120e4048100120700a81001202c1c037", - "0x484100e1000280407e0f80c0170120580a83d0300240481602a0f00c009", - "0x484801203c0384700a05c0484608a1100384300a1080480f00e10002817", - "0x485001213c0380d09403c0384300a0102704d0121300484b00e11c25049", - "0x48550120400481c02a1340485401214c038470941480480f00e10002851", - "0x481602a1680c0090120580a8510121640485800e0342505701202c05056", - "0x485e0121780485e0121780485e0121780480f00e174028040b816c0c009", - "0x481602a1780485e0121780485e0121780485e0121780485e0121780485e", - "0xa8620121840481602a1800c0170120580a85f0301780481602a0a00c05e", - "0xc05e0120580a86503005c0481602a1900c0170120580a86303017804816", - "0x481602a1a40c05e0120580a8680121840481602a19c0c05e0120580a866", - "0xa86d0301780481602a1b00c05e0120580a86b0121840481602a1a80c05e", - "0x480b070010388600301780481602a1c00c06f0120580a86e01218404816", - "0x481602a19c0c06f0120580a86a0301bc0481602a1b40c06f0120580a86f", - "0xa8750301bc0481602a1d00c06f0120580a8730301bc0481602a1c80c06f", - "0xc05e0120580a8140301780481602a0a40c05e0120580a87603005c04816", - "0x480b0701dc048610120580a8180301780481602a0400c05e0120580a80c", - "0x480b0141440487a0121e40380d0940400480b0141e00c05e0120580a85e", - "0x380d0940240486f01205c0487f00e1f8028510121f40487c00e0342507b", - "0xc0170120580a8090301780481602a2040c0170120580a8510121ec04880", - "0xa88701202c1c00410c2140c0170120580a88403005c0481602a01041882", - "0x380d0940240480901203c0380d00a2240c0170120580a88803005c04816", - "0x289001223c0384000a0104700411a0240c08c0120580a85101222c0488a", - "0xc0170120580a89303005c0481602a2480c0170120580a81701224403840", - "0x380d0940a80c05e0120580a89603005c0481602a2540c0170120580a894", - "0x481c02a1340486c012264038470942600480f00e1000285101214404897", - "0x481602a2780c0090120580a89d012270048100120700a89b01226804810", - "0x48a20120400481c02a2840c0090120580a8a00300240481602a27c0c009", - "0xa8a70300240481602a2980c0090120580a8a5012290048100120700a8a3", - "0x481c02a2ac048aa0120400481c02a2a40c0090120580a8a803002404816", - "0xc0090120580a8af0300240481602a2b80c0090120580a8ad0122b004810", - "0x48b40120400481c02a2cc048b20120400481c02a2c40c0090120580a8b0", - "0x481602a2e00c0090120580a8b70300240481602a2d80c0090120580a8b5", - "0x481602a2f40c0090120580a8041782ec048ba0120400481c02a2e40c009", - "0x384000a05c048510123040380d094144048c00122fc0380d0942f80c009", - "0xa898012040048100123140387e00a134048c401230c038470943080480f", - "0xa8ca0300240481602a324048c80120400481c02a31c048c60120400481c", - "0x48100120700a8cd0300240481602a3300c0090120580a8cb03002404816", - "0xa8d20300240481602a3440c0090120580a8d003005c0481602a33c048ce", - "0x48d40120400481c02a1c80c0090120580a80901202c1c0d30120ac04816", - "0x481c02a3600c0090120580a8d70300240481602a3580c0170120580a8d5", - "0x481602a3740c0090120580a8dc01236c048100120700a8da01236404810", - "0xa8e103005c0481602a3800c0090120580a8df0300240481602a3780c009", - "0x481602a3940c0090120580a8e403005c0481602a38c048e20120400481c", - "0x481602a3a0048e80120400481c02a3a0048e70120400481c02a3980c009", - "0x485e0121780485e0121780485e0121780485e01203c038ea00a3a40c05e", - "0x480f00e1f8028041de3b8048ed00e100028ec01202c7585e0121182285e", - "0x48f70123d8048f50123d00a84d0123cc048f200e11c250510123c4048f0", - "0xa8fe0301780481602a3d40480b0143f4048fc0123ec048fa0123e4048f8", - "0xc05e0120580a9010301780481602a4000c05e0120580a8ff03017804816", - "0x384700a4140c05e0120580a9040301780481602a40c0c05e0120580a902", - "0x481602a4200c05e0120580a84d01241c0490600e11c250510123b00480f", - "0xa90c03005c0481602a42c0c0170120580a90a03005c0481602a4240c017", - "0x7586f0121182290f0300240481602a4380c0170120580a90d03002404816", - "0x491300e11c250510124400480f00e11c029120124440384000a4400480b", - "0x480f00e460029170124580384000a4540480b1d60400484608a13404914", - "0x481602a01c0c0090120580a84d01246c0491a00e11c2505101244004919", - "0xa91d03005c0481602a4700c0170120580a81803005c0481602a0240c009", - "0x7587b0121182292003005c0481602a47c0c0170120580a91e03005c04816", - "0x3847094260049240124900480f00e1f8029230124880384000a4840480b", - "0x492901203c0387e00a4a00492700e1000284901202c7584d01249804925", - "0x280425c4b40480b0144b00480b0141340492b0124a80384709426004929", - "0x493600e4d40293401202c050170124cc049330124c8049310124c00392f", - "0x485e0124a4048090124900481701205c048170124a4048090124cc04817", - "0x493900e0342513301204c0913801204c0900226e4b0048130244a40485e", - "0x38470944ec0492901203c0384700a144049210124e80384709414404924", - "0x2513f0124a40480f00e034028510124a40493e00e0342504d0124f40493c", - "0xc06f0120580a94203005c0481602a4a4048130241340494101250003847", - "0x294403005c0481602a008a181e03005c0481602a0cc0c0170120580a809", - "0xc0170120580a802290144049470125180380d09422c048170125140380d", - "0xa84d0125340494c00e11c2501701252c0480f00e0340294a00e10c02949", - "0x38470941440494b01203c0395000a53c0c0170120580a94e03005c04816", - "0xa8042ae008ab017012554aa017012118a981701202c1c04d01254804951", - "0x495b00e11c2505101203c0395a00a5640c0170120580a95803005c04816", - "0x38470945780492901203c0380d00a1440492c0125740380d0941340495c", - "0x492d0125880380d0944cc0486f0121bc0496100e1f80284d0125800495f", - "0xa84d0125900496300e11c250510121bc0480f00e0340292d01204c09051", - "0x4849012598038470945940c0170120580a84901204c090070301bc04816", - "0x2501701202c0504d0125a40496800e11c251670124a40480f00e11c02851", - "0xc0170120580a96c03005c0481602a05c048130241440496b0125a80380d", - "0x481602a5b40c0170120580a81d03005c0481602a01c0c0170120580a809", - "0xb80070301780481602a4a40480f00e1000296f03005c0481602a5b80c017", - "0x497500e034250042e85cc0c0170120580a84d0125c80497100e11c25004", - "0x38090125f40397c2520240497b00e5e80397900e5e0bb8022ec14404817", - "0x940090125f4038183040240c18102e0240498002e0240497f02e0240497e", - "0x398630402404985012060c100903060428809012610039833040240497d", - "0xb8090126280b809012620c4809012620b58090126209400901262003987", - "0xc18109a024049840900240498402e0240498d02e0240497d3180240498b", - "0xc88090125f40399031c0240497d2700240497d31e0240497d012060c7009", - "0x399600e6542f0090125f4c48090126502f009012650c980901262c03992", - "0x381831c0240c1812e402404984252024049840920240498809202404997", - "0x498b3320240498b0a2024049883300240498b0bc024049880920240497d", - "0xcf00901262cce80901262cce00901262ccd80901262c94809012620cd009", - "0xd18090125f4038183460240c18100e6880b809012684039a002e0240499f", - "0xd28090126141682a012690948090125f4d1809012614048183460240c181", - "0xb3809012614048182ce0240c181266024049882ce0240497d2d20240497b", - "0x49880de0240498800e6a42480901267cd4009012620d380901262c039a6", - "0x2f82a012690378090125f43780901265cd580901262c24809012684d5009", - "0xd7809012614d702a0126909680901267c039ad2c80240498835802404985", - "0x49882bc024049852c00240497b360024049850660a8049a425a024049a1", - "0x968090125f4a5809012620a580901265ca58090126109680901262096009", - "0x498b3640240498b2b802404988362024049850640a8049a42580240497d", - "0xdc02a012690db0090125f4039b736c0240498800e6d4da009012620d9809", - "0x49880340a8049a437a0240497d02e024049bc3760240497d00e6e8039b9", - "0x4c009030604e00090126204c0090125f4048181300240c18100e6fcdf009", - "0xa9009012620e18090126141b82a012690039c200e7044c00901262003818", - "0xe300901262c039c50720a8049a40740a8049a40280240497d3880a8049a4", - "0x49a43940240498b29a0240497b392024049853900a8049a438e0240498b", - "0x49a43980240497d00e72c998090126500b8090126502102a0126900b82a", - "0x2482a012690a38090125f4a3809012620e68090126142402a0126902602a", - "0x49801160240497b1160240498828e0240497b28e0240499428e02404997", - "0x498b3a20a8049a409a0a8049a43a00240497d39e0240498b00e73804809", - "0xb3809030604c48090125f4039d700e758ea818012750e980901262ce9009", - "0x481834a0240c18134a0240497d00e060d2809030604b480901261003818", - "0x39db3b40240498b00e76494009012650039d80de024049800de02404994", - "0xd6009030604b2009012610d60090125f4048183580240c1813b80240498b", - "0x481835e0240c18135e0240497d00e060d78090306049680901261003818", - "0x9f809012614a08090125ecef0090126142802a012690039dd2520240499f", - "0x497b3be024049850a20a8049a42420240497d0f60240498a252024049a1", - "0xf000903060492009012610908090126209080901265c9d8090126149e809", - "0x48183600240c18101202404988012060f0009030604f00090125f403818", - "0x498400e060af00903060496009012610039e13c0024049853600240497d", - "0xf1009012620048182bc0240c1812480240498800e060d8009030604b0009", - "0x9a0090125fcf20090125f4039e32580240499f2700240499f2660240499f", - "0x497b25a0240499425a0240499725a0240497f2620240497d2680240497b", - "0x99009012620f280901262099809012684990090125f49c00901268496809", - "0x497b2580240499425802404997258024049a12580240497f26602404980", - "0x2902a012690039e802e024049e7252024049942520240498000e79896009", - "0x498031e0240498000e02404980130024049852560240497b3d202404985", - "0x2a02a012690920090125f43d80901279c920090125ec9200901265092009", - "0x38183620240c1812b8024049840bc0240498024c0240497b3d402404985", - "0xf680901262cf600901262c048183620240c1813d60240498b3620240497d", - "0x49940da024049883e0024049883de0240498b3dc0240498b09a0240497d", - "0x498b0200240498a37c0240497d02e024049f33e40240498b00e7c4db009", - "0x3780901262808009012634080090125f4080090126107400901262c73809", - "0x49a42200240497d2320240497d2320240498422a0240498822a02404997", - "0xfb0090126140d82a0126908c8090126208d8090125ecfa809012614fa02a", - "0x80090125ec039f83ee0240498422002404988220024049972280240497b", - "0xe18090125f4048183860240c1813f40240498b0120240497d3f20240498b", - "0x49fd3f80240498b020024049883ee0240497d0de0240498d3f60240498b", - "0x498b00e060e1809030604a9009012610ff00901262cb58090125f40b809", - "0x10080901262c2f00901262824009012620268090125ed0000901262cff809", - "0x38184080240c203404024049850b20a8049a41d80240497d0bc0240498d", - "0x780090125f478009012610760090126207600901265c838090125ec03a05", - "0x3a081e0024049881e60240497b40e0240498540c0a8049a41e20240497d", - "0x498b4160240498b4140240498b1ea0240497b1ea0240497f4120240497d", - "0x49880a4024049850a40240497d0a4024049880a40240499700e83506009", - "0x10900901262d0880901262d0800901262d0780901262d0700901262c28009", - "0x10b00901262d0a80901262d0a00901262c0800901265c03a1302002404994", - "0x498b4360240498b4340240498b00e8650c00901262c03a170560240497d", - "0x2b02a012690210090125f50e8090125f4210090126110e8090126110e009", - "0x1100090126211000901265c03a1f184024049851880240497b43c02404985", - "0x498b4440240498b4420240498b18002404988440024049854400240497d", - "0x498b4500240498b44e0240498b44c0240498b44a0240498b00e89111809", - "0x36009012621158090126142a82a012690600090125f51500901262d14809", - "0x498b3920240497d012060e48090306040b8090128b803a2d4580240498b", - "0x498b00e060e4809030604a68090126109c0090126011800901262d17809", - "0x11a0090126211a00901265d1a0090126111980901262d1900901262d18809", - "0x497b46e0240498846e0240499746e0240498400e8d803a354680240497b", - "0x49841200240498800e8e51c00901262c48009012650480090126011b809", - "0x11d009012614048184740240c1814740240497d00e0611d00903060445809", - "0x3a3b012060e6809030604e68090125f40381839a0240c18128e02404984", - "0x12080901262c438090129011f8090125f403a3e47a0240498b4780240498b", - "0x498b00e91043809012620438090125f403a4310e024049944840240498b", - "0x49d400e92c03a4a47e0240498800e92403a4848e0240497d00e91922809", - "0x9f8090306040b8090129392680901262c98809012620480090125f526018", - "0x48183bc0240c1813bc0240497d00e060ef009030604a080901261003818", - "0xc18127a0240498400e0609d8090306040481827e0240c18149e0240498b", - "0xc1810f60240498d4a0024049850bc0a8049a43be0240497d00e060ef809", - "0x497d00e060f480903060495809012610048183be0240c1810120609d809", - "0x918090125f4038184a20240c1810f60240497e012060f4809030604f4809", - "0x3d8090125f43d8090125fd28809012614048184a20240c1814a20240497d", - "0x38183d40240c18124c024049840f6024049880f60240497b0f602404994", - "0x80090125f88c8090125ec048183d40240c181246024049883d40240497d", - "0x498501206129009030605290090125f48b8090125f4038184a40240c181", - "0x497d012060fa8090306042b82a01269008009012600080090125fd29009", - "0x497d4a60240498b0de024049e700e060fa8090306048d809012610fa809", - "0x498b4b00240498b4ae0240498b4ac0240498b4aa0240498b00e95030809", - "0x498b4b60240498b3ec0240497d012060fb0090306052d00901262d2c809", - "0x13080901262d3000901262d2f80901262d2f00901262d2e80901262d2e009", - "0xc181228024049844ca0240498b4c80a8049a40c40240498b00e98c03a62", - "0x498b4ce0240498b0d00240498b4cc0240498b0bc024049e700e060fb009", - "0x3700901262d3500901262c308090126013480901262c3580901262d34009", - "0x1010090306053780901262c03a6e0bc024378090309b403a6c4d60240498b", - "0x498b00e9cd3900901262d3880901262d3800901262d010090125f404818", - "0x101009030604838090126113200901262d3a80901262d3a82a0126913a009", - "0x497d1dc0240497d00e061030090306042b8090129d8780090125ec03818", - "0x10380903060403a770b20240498040c024049850120610300903060503009", - "0x49941e20240498800e0610380903060479809012611038090125f404818", - "0x49880840240498800e9e0048090126500d80901262d0e8090125ed0e809", - "0x13902a012690280090125f42a0090125ecfa0090126153a02a0126910e809", - "0x38181840240c1810840240497b084024049970980240497b3a202404985", - "0x61009030604e400901262d0f0090125f40381843c0240c18118802404984", - "0x49943700240498b06e0240498b3880240498b0120610f00903060404818", - "0x2f80901262d3882a0126900800901290003a7a00e9e40d0090125f40d009", - "0x1158090125f4038184560240c1810d80240498400e9f403a7c4f60240498b", - "0x497d00e061280090306043d8090126100d009012620048184560240c181", - "0x13f80901262c378090120240c26d4fc0240498b0120612800903060528009", - "0x498b5080240498b5060240498b5040240498b5020240498b5000240498b", - "0x498b00ea203000901262c3c00901262d4380901262d4300901262d42809", - "0x498400e0602900903060403a8a00ea241380901262c1300901262c12809", - "0x1400901262c048183e80240c1813e80240497d00e060fa0090306042a009", - "0x60090126200600901265c060090126100a00901267c048180a40240c181", - "0x3a8d028024049a14e00a8049a401802404a8c01802404a8b0180240497d", - "0x4988012060e8809030604e88090125f4038183a20240c18109802404984", - "0x49a40300240498800ea400c0090125f40c00901261003a8f00ea3814809", - "0xa0184380300801852406004807030024038075240240380700ea453782a", - "0x38075240240381000e0a004a920120a80482a00e01d4900900e06003829", - "0x381800e0940481f04c09c0c2920300a00481400e04004a920120400480c", - "0x482700e08004a920120780482800e07804a920120980482900e01d49009", - "0x3860012a480481f0120940381d012a48048270120980381f012a4804820", - "0x3c00903e01c3c0095240240382000e01d4900900e0600380750c0240381e", - "0xe8070c00254900950e0241280703a0254900904a0241300750e02549009", - "0x14901850c0400c06000e01d4900900e06003a850122b14300952406030009", - "0xa007508025490095080240600700ea480480703001d4100944ca0d42018", - "0x1490095000241480700ea480480703001d3f8090bea01408185240600e809", - "0x14080904c01c160095240253d80904e01d3d8095240253f00905001d3f009", - "0x480703001c0381a01201c0f00705a025490090580241280705c02549009", - "0x4a7f012098039ae012a480485f01207c0385f012a480480704001c03a92", - "0x1900945e0cc04a920300b40481d00e0b404a920126b80482500e0b804a92", - "0x480703001c1b8090ac068dc0185240601700902801c03a9201201c0c007", - "0x3a9201206804a8600e01d490093700254380700ea48048070f001c03a92", - "0x39c4012a480480750601c03a920120cc04a8400e01d4900950602542807", - "0x4a920120e8e201850001c1d0095240241d00950201c1d00952402403a82", - "0x48170129ec03817012a48048393900613f0073900254900900e9fc03839", - "0x482e00e03004a920120300482c00ea1004a92012a100480c00e10804a92", - "0x381800e1080c00c50804004842012a48048420120b403818012a4804818", - "0x484c0126b80384c012a48048070be01c03a920120dc04a8700e01d49009", - "0x480703001ce884d03090424848030a480c04c018a101503300e13004a92", - "0x14180903401c28850030a48048500126e003850012a480480706401c03a92", - "0x3848012a480484801203003851012a48048510120dc0385250606149009", - "0x14900900e06003a060b206c152553e81500c2920300cc29051030124061c4", - "0xfa0540200e803850012a48048500120dc03854012a48048540120b003807", - "0x387800e01d4900900e06003a754c815c1525a0bc1542b02a52406141850", - "0x13a01850001c2f0095240242f00950201d3a00952402403a8300e01d49009", - "0x38075240253880939001d38271030a4804a720120e403a72012a480485e", - "0x4a920129ac0484c00e9ac04a920129bc0484200e9bc04a920129c004817", - "0x48550120b803856012a48048560120b003848012a48048480120300386e", - "0x14900900e0600386e0aa158240100121b804a920121b80482d00e15404a92", - "0x4a7501212003a69012a4804a640120b803a6a012a48048570120b003807", - "0x3a92012a0c04a8500e01d4900900e060038070fa0240381e00e1ac04a92", - "0x4a920121640482e00e9a804a9201206c0482c00e01d490090a002424807", - "0x13400952402403a7f00e01d4900900e1e00386b012a4804a0601212003a69", - "0x484801203003868012a4804a670129ec03a67012a480486b4d00613f007", - "0x482d00e9a404a920129a40482e00e9a804a920129a80482c00e12004a92", - "0x14900900e1e0038075240240381800e1a134a6a09004004868012a4804868", - "0x13300952402403a8300e01d490090660254200700ea4804a83012a1403807", - "0x1490094ca9980c28000e99404a9201299404a8100e99404a9201201c26807", - "0x1498094f601d498095240243106f0309f80386f012a48048074fe01c31009", - "0x170073a2025490093a20241600709a0254900909a024060074c202549009", - "0xc0074c2060e884d020025308095240253080905a01c0c0095240240c009", - "0x4a83012a1403807524024190093a201c03a9201201c3c00700ea4804807", - "0x4a9201201c280074c00254900900ea0c038075240241700950e01c03a92", - "0x48074fe01d2f0095240252fa60030a0003a5f012a4804a5f012a0403a5f", - "0x60074b6025490094b80253d8074b8025490094bc9740c27e00e97404a92", - "0xc0095240240c00905c01c060095240240600905801d4200952402542009", - "0x14380700ea480480703001d2d818018a10080094b6025490094b602416807", - "0x381800e01c5980900e07803a5a012a4804a82012030038075240240e809", - "0x4810012030038075240240e80950e01c03a92012a14049d100e01d49009", - "0x4a9201201c288074b20254900900ea0c038075240240387800e96804a92", - "0x48074fe01d2b8095240252c259030a0003a58012a4804a58012a0403a58", - "0x60074a6025490094aa0253d8074aa025490094ae9580c27e00e95804a92", - "0xc0095240240c00905c01c060095240240600905801d2d0095240252d009", - "0x2900700ea480480703001d29818018968080094a6025490094a602416807", - "0x4a8100e1dc04a9201201c268070c20254900900ea0c0380752402415009", - "0x3a52012a48048074fe01c3d0095240243b861030a0003877012a4804877", - "0x149009028024060074a2025490090fa0253d8070fa025490090f49480c27e", - "0x12880905a01c0c0095240240c00905c01c148095240241480905801c0a009", - "0xc00900e0600480700ea480480700e01d28818052050080094a202549009", - "0x140095240241500905401c03a9201201c0c0070520500c1c90180400c292", - "0xc00704a0247882604e061490180500240a0070200254900902002406007", - "0x480750601c03a9201209804a8600e01d4900904e0254380700ea4804807", - "0xf01850001c100095240241000950201c1000952402403a8200e07804a92", - "0x3860012a480481f03a0613f00703a0254900900e9fc0381f012a4804820", - "0x4a920120300482c00e04004a920120400480c00e1e004a9201218004a7b", - "0xc00c02004004878012a48048780120b403818012a48048180120b80380c", - "0x3a87012a48048070be01c03a9201209404a8700e01d4900900e06003878", - "0x141a8403078942a86030a480c2870180401503300ea1c04a92012a1c049ae", - "0x3a82012a4804a82012a0403a82012a48048070a801c03a9201201c0c007", - "0x480706401c03a9201201c0c0074fe0249928050206149018504a180c060", - "0x481a00e0b13f0185240253f00937001d3d809524024039f400e9f804a92", - "0x13d8095240253d80950201c160095240241600906e01c17280030a4804a80", - "0x9185f05a061490184f60b81601850a030e20075020254900950202406007", - "0x482d0120b0039b8012a480480703601c03a9201201c0c0070640ccd702a", - "0x61c400e6e004a920126e004a8100e9f804a920129f80483700e0b404a92", - "0x38075240240381800e0e41d1c40547bc1b81a030a480c1b85009f82f82d", - "0x3a9201205c049c800e1080b818524024e400907201ce400952402403a83", - "0x149009090024260070900254900909802421007098025490090840240b807", - "0x1b80905c01c0d0095240240d00905801d408095240254080901801c24809", - "0x480703001c24837034a0408009092025490090920241680706e02549009", - "0x1d00905c01ce8809524024e200905801c268095240254080901801c03a92", - "0x480703001c039f001201c0f0070a202549009072024240070a002549009", - "0x1490095020240600700ea4804a80012a14038075240253f00909201c03a92", - "0x1900909001c280095240241980905c01ce8809524024d700905801c26809", - "0x4a9201201d4180700ea480480703001c039f001201c0f0070a202549009", - "0x48540a4061400070a8025490090a8025408070a80254900900e16403852", - "0x482e00e74404a92012a140482c00e13404a920129fc0480c00e7d004a92", - "0x13f0070360254900900e9fc03851012a48049f401212003850012a4804818", - "0x4a920121340480c00e81804a9201216404a7b00e16404a920121440d818", - "0x4a060120b403850012a48048500120b8039d1012a48049d10120b00384d", - "0x2b00952402403a8300e01d4900900e06003a060a07442681001281804a92", - "0x1490090aa1580c28000e15404a9201215404a8100e15404a9201201c26807", - "0x1320094f601d320095240242f0570309f803857012a48048074fe01c2f009", - "0x17007506025490095060241600750802549009508024060074ea02549009", - "0xc0074ea06141a840200253a8095240253a80905a01c0c0095240240c009", - "0x480709a01d3a00952402403a8300e01d490090540242900700ea4804807", - "0x13f8074e2025490094e49d00c28000e9c804a920129c804a8100e9c804a92", - "0x135809524025378094f601d3780952402538a700309f803a70012a4804807", - "0x1490090300241700705202549009052024160070280254900902802406007", - "0x4a9201201d030074d606014814020025358095240253580905a01c0c009", - "0x480700ea480480700e01c03a9201201c2b0070520254900900e8180380c", - "0x1500905401c03a9201201c0c00704a0980c29404e0a00c29203002403818", - "0xf00902801c140095240241400901801c03a9201201c0800703c02549009", - "0x300095240240f80905201c03a9201201c0c00703a024cf01f04006149018", - "0x1490090400241300750e025490090f0024138070f0025490090c002414007", - "0x3a9201201c0c00700e6640480703c01d428095240254380904a01d43009", - "0x4a920120740482600ea0c04a92012a100481f00ea1004a9201201c10007", - "0xc0075040254a814012a480c28501207403a85012a4804a8301209403a86", - "0x1408185240600a02803017803814012a48048140520602a80700ea4804807", - "0x14300902801d408095240254080901801c03a9201201c0c0074fe0254b280", - "0x170095240253d80905201c03a9201201c0c0070580254ba7b4fc06149018", - "0x1490094fc024130070be0254900905a0241380705a0254900905c02414007", - "0x3a9201201c0c00700ea600480703c01c198095240242f80904a01cd7009", - "0x4a920120b00482600e6e004a920120c80481f00e0c804a9201201c10007", - "0xc0070340254c810012a480c03301207403833012a48049b8012094039ae", - "0xe2037030a480c1ae01205003810012a48048100180602a80700ea4804807", - "0x483701209803839012a48049c401215c038075240240381800e0e804a9a", - "0x14900900e060038075360240381e00e05c04a920120e404a6400e72004a92", - "0x14900907402413007098025490090840253a8070840254900900e08003807", - "0x3849012a70240095240600b8094e801c0b809524024260094c801ce4009", - "0x3a8300e13404a920121200482900e01d4900900e1e00380752402403818", - "0x60070a20254900909a024140070a0025490093900240b8073a202549009", - "0x28009524024280094e401c138095240241380905801d4080952402540809", - "0x28027502031388070a2025490090a2025408073a2025490093a202424007", - "0x381800e16404a9d036025490183e8025380073e81502902a524024289d1", - "0x60070aa0254900940c024150070ac8180c29201206c04a6f00e01d49009", - "0x1320095240242a80904c01c2b8095240242a00905801c2f00952402429009", - "0x3700700ea480480703001c03a9e01201c0f0074ea025490090ac02535807", - "0x60074e8025490090b20253d80700ea4804810012a100380752402540009", - "0xc0095240240c00905c01c2a0095240242a00905801c2900952402429009", - "0x3c00700ea480480703001d3a0180a8148080094e8025490094e802416807", - "0x1390094d401d390095240240382000e01d49009092024e880700ea4804807", - "0x130070ae0254900904e024160070bc02549009502024060074e202549009", - "0x1380095240613a8094d201d3a809524025388094d601d32009524024e4009", - "0x3a6a012a803726b030a480c264012050038075240240381800e9bc04a9f", - "0x49c800e01d490090dc0254300700ea4804a6b012a1c0380752402403818", - "0x480750601c03a92012a000486e00e01d490090200254200700ea4804a70", - "0x13481850001c358095240243580950201c3580952402403a8200e9a404a92", - "0x3868012a4804a684ce0613f0074ce0254900900e9fc03a68012a480486b", - "0x4a9201215c0482c00e17804a920121780480c00e99804a920121a004a7b", - "0xc0570bc04004a66012a4804a660120b403818012a48048180120b803857", - "0x3a65012a48048070be01c03a920129a804a8700e01d4900900e06003a66", - "0x130a93030a8437862030a480c2650ae1781503300e99404a92012994049ae", - "0x3a92012980049c800e97d300185240253800907201c03a9201201c0c007", - "0x1400180de030358070c4025490090c4024060074bc025490094be0240b807", - "0x484200e01d4900900e06003a584b2968152a24b69712e82a5240612f010", - "0x3862012a480486201203003a56012a4804a5701213003a57012a4804a5b", - "0x4a920129580482d00e97004a920129700482e00e97404a920129740482c", - "0x13f0074aa0254900900e9fc038075240240381800e9592e25d0c404004a56", - "0x4a920121880480c00e18404a9201294c04a7b00e94c04a920129612a818", - "0x48610120b403a59012a4804a590120b803a5a012a4804a5a0120b003862", - "0x3a920129c0049c800e01d4900900e060038614b29683101001218404a92", - "0x3877012a480480750601c03a92012a000486e00e01d4900902002542007", - "0x4a920121e83b81850001c3d0095240243d00950201c3d0095240240384d", - "0x4a510129ec03a51012a4804a520fa0613f0070fa0254900900e9fc03a52", - "0x482e00e98404a920129840482c00ea4c04a92012a4c0480c00e1ec04a92", - "0x381800e1ec0c2615260400487b012a480487b0120b403818012a4804818", - "0x4810012a10038075240253200950e01c03a920129bc049d100e01d49009", - "0x4a9201201d340074a00254900900ea0c03807524025400090dc01c03a92", - "0x48074fe01d2680952402527a50030a0003a4f012a4804a4f012a0403a4f", - "0x60074840254900948e0253d80748e0254900949a9140c27e00e91404a92", - "0xc0095240240c00905c01c2b8095240242b80905801c2f0095240242f009", - "0x3c00700ea480480703001d210180ae178080094840254900948402416807", - "0x1400090dc01c03a920126b804a8700e01d49009034024e880700ea4804807", - "0x14900900e14003a41012a480480750601c03a9201203004a6700e01d49009", - "0x3a7f00e8fc04a9201221d2081850001c438095240244380950201c43809", - "0x388b012a4804a3c0129ec03a3c012a4804a3f47a0613f00747a02549009", - "0x4a920120600482e00e09c04a9201209c0482c00ea0404a92012a040480c", - "0x38075240240381800e22c0c0275020400488b012a480488b0120b403818", - "0x3a3a012a4804a7f012030038075240254300950e01c03a9201203004a67", - "0x60094ce01c03a92012a08049d100e01d4900900e060038075460240381e", - "0x482801203003807524024148094ce01c03a92012a1804a8700e01d49009", - "0x4a9201201c288074700254900900ea0c038075240240387800e8e804a92", - "0x48074fe01c4800952402446238030a000388c012a480488c012a040388c", - "0x6007466025490094680253d807468025490091208dc0c27e00e8dc04a92", - "0xc0095240240c00905c01c138095240241380905801d1d0095240251d009", - "0x13380700ea480480703001d1981804e8e8080094660254900946602416807", - "0x3a8300e01d490090520253380700ea480482a0121480380752402406009", - "0xc28000e8c404a920128c404a8100e8c404a9201201c2680746402549009", - "0x1160095240251822f0309f803a2f012a48048074fe01d1800952402518a32", - "0x14900904a0241600704c0254900904c02406007130025490094580253d807", - "0x128260200244c0095240244c00905a01c0c0095240240c00905c01c12809", - "0x3a9201201c2b0070520254900900e1a00380c012a480480740c01c4c018", - "0xc00704a0980c2a404e0a00c2920300240381801201c03a9201201c03807", - "0x1400901801c03a9201201c0800703c025490090540241500700ea4804807", - "0x3a9201201c0c00703a0255281f0400614901803c0240a00705002549009", - "0x1490090c0025320070f002549009040024130070c00254900903e0242b807", - "0x3a86012a480480704001c03a9201201c0c00700ea980480703c01d43809", - "0x4a92012a1404a6400e1e004a920120740482600ea1404a92012a1804a75", - "0x14200905201c03a9201201c0c00750602553a84012a480c2870129d003a87", - "0x3a82012a48048100120a003810012a48048100180602a80702002549009", - "0x14080901801c03a9201201c0c0074fe02554280502061490185040a00c266", - "0x3a9201201c0c00705802554a7b4fc061490180f00240a00750202549009", - "0x14900905c0253200705a025490094fc0241300705c025490094f60242b807", - "0x39ae012a480480704001c03a9201201c0c00700eaa80480703c01c2f809", - "0x4a920120cc04a6400e0b404a920120b00482600e0cc04a920126b804a75", - "0x48070f001c03a9201201c0c00737002555832012a480c05f0129d00385f", - "0x482d01205c03837012a480480750601c0d0095240241900905201c03a92", - "0x482c00ea0404a92012a040480c00e0e804a920120680482800e71004a92", - "0x3837012a4804837012120039c4012a48049c40129c803827012a4804827", - "0x38173900e4152920120e81b9c404ea040627100e0e804a920120e804a81", - "0x1490090840253780700ea480480703001c2600955810804a9203005c04a70", - "0x482c00e74404a920120e40480c00e13404a920121200482a00e12424018", - "0x3852012a48048490129ac03851012a480484d01209803850012a48049c8", - "0x148090c401c03a92012a0004a6500e01d4900900e0600380755a0240381e", - "0x482c00e0e404a920120e40480c00e15004a9201213004a7b00e01d49009", - "0x4854012a48048540120b403818012a48048180120b8039c8012a48049c8", - "0x49b8012744038075240240387800e01d4900900e060038540307201c810", - "0x4a810120300381b012a48049f40129a8039f4012a480480704001c03a92", - "0x4a6b00e14404a920120b40482600e14004a9201209c0482c00e74404a92", - "0x3a9201201c0c0070b202557014012a480c0520129a403852012a480481b", - "0xc2920301440481400e05004a92012050148180de01c03a9201201c08007", - "0x482600e17804a920121580485700e01d4900900e06003855012abc2b206", - "0x381800e01d5800900e07803a64012a480485e01299003857012a4804a06", - "0x2a80904c01d3a0095240253a8094ea01d3a8095240240382000e01d49009", - "0x4ab14e4025490184c80253a0074c8025490094e8025320070ae02549009", - "0x3a70012a4804a720120a4038075240240387800e01d4900900e06003a71", - "0x370095240253800905001d358095240242b80902e01d3780952402403a83", - "0x1490094d6025390070a0025490090a0024160073a2025490093a202406007", - "0xe880c4e201c370095240243700950201d378095240253780909001d35809", - "0x3a67012ac934009524060358094e001c35a694d40a9490090dc9bd35850", - "0x1328095240243400905401d33068030a4804a680129bc0380752402403818", - "0x1490094ca024130070de025490094d2024160070c4025490094d402406007", - "0x3a9201201c0c00700eacc0480703c01d30809524025330094d601d49809", - "0x130009524025338094f601c03a92012a0004a6500e01d49009028024e4007", - "0x149009030024170074d2025490094d2024160074d4025490094d402406007", - "0x3a9201201c0c0074c006134a6a020025300095240253000905a01c0c009", - "0x1350074be0254900900e08003807524025388093a201c03a9201201c3c007", - "0x378095240242800905801c31009524024e880901801d2f0095240252f809", - "0x1490184c2025348074c2025490094bc02535807526025490090ae02413007", - "0x4ab54b496c0c292030a4c0481400e01d4900900e06003a5c012ad12e809", - "0x38075240252d00950c01c03a9201296c04a8700e01d4900900e06003a59", - "0x14180700ea4804a5d01272003807524025400094ca01c03a92012050049c8", - "0x1400074ae025490094ae025408074ae0254900900ea0803a58012a4804807", - "0x4a920129592a8184fc01d2a80952402403a7f00e95804a9201295d2c018", - "0x486f0120b003862012a480486201203003861012a4804a530129ec03a53", - "0x3101001218404a920121840482d00e06004a920120600482e00e1bc04a92", - "0x4a9201201c2f80700ea4804a59012a1c038075240240381800e1840c06f", - "0xc2b64a41e80c2920301dc378620540cc03877012a48048770126b803877", - "0xc2920129740483900e1ec04a9201201d4980700ea480480703001d2887d", - "0x1268094ca01d22a4d030a4804a80012984038075240252800939001d27a50", - "0x480c00e01d4900948e024e400748491c0c2920120500483900e01d49009", - "0x3818012a48048180120b803a52012a4804a520120b00387a012a480487a", - "0x4a9201291404a6000e93c04a9201293c0482600e1ec04a920121ec04a60", - "0x829201290922a4f0f60612907a05297c03a42012a4804a4201209803a45", - "0x38075240240381800e22c04ab74780254901847a0252f00747a8fc43a41", - "0x46238030a4804a3a0120e403a3a012a480480750601c03a920128f004a5d", - "0x4a920122400484200e24004a920122300481700e01d49009470024e4007", - "0x48870120b003a41012a4804a4101203003a34012a4804a3701213003a37", - "0x1208100128d004a920128d00482d00e8fc04a920128fc0482e00e21c04a92", - "0x4a4101203003a33012a480488b0129ec038075240240381800e8d11f887", - "0x482d00e8fc04a920128fc0482e00e21c04a9201221c0482c00e90404a92", - "0x4814012720038075240240381800e8cd1f88748204004a33012a4804a33", - "0x4a9201201d4180700ea4804a5d01272003807524025400094ca01c03a92", - "0x4a314640614000746202549009462025408074620254900900e13403a32", - "0x4a7b00e8b004a920128c1178184fc01d1780952402403a7f00e8c004a92", - "0x3a51012a4804a510120b00387d012a480487d01203003898012a4804a2c", - "0x38980309443e81001226004a920122600482d00e06004a920120600482e", - "0x4a6500e01d49009028024e400700ea4804a5c0127440380752402403818", - "0x48074d001c3600952402403a8300e01d490095260254380700ea4804a80", - "0x13f807454025490094561b00c28000e8ac04a920128ac04a8100e8ac04a92", - "0x4e8095240244d8094f601c4d809524025152290309f803a29012a4804807", - "0x149009030024170070de025490090de024160070c4025490090c402406007", - "0x3a9201201c0c00713a060378620200244e8095240244e80905a01c0c009", - "0x38075240242880950e01c03a92012a0004a6500e01d490090b2024e8807", - "0x1408071340254900900e1400389c012a480480750601c03a920120a404862", - "0x11380952402403a7f00e8a004a920122684e01850001c4d0095240244d009", - "0x49d1012030038a5012a48048a30129ec038a3012a4804a2844e0613f007", - "0x482d00e06004a920120600482e00e14004a920121400482c00e74404a92", - "0x4829012188038075240240381800e2940c0503a2040048a5012a48048a5", - "0x15c00900e078038a4012a4804a7f012030038075240243c00950e01c03a92", - "0x3807524024148090c401c03a92012a0c049d100e01d4900900e06003807", - "0x38a4012a480482801203003807524024060094ce01c03a920121e004a87", - "0x4a8100e89804a9201201c288071440254900900ea0c0380752402403878", - "0x38ab012a48048074fe01d12809524025130a2030a0003a26012a4804a26", - "0x149009148024060071580254900915a0253d80715a0254900944a2ac0c27e", - "0x5600905a01c0c0095240240c00905c01c138095240241380905801c52009", - "0x1490090540242900700ea480480703001c5601804e2900800915802549009", - "0x5500952402403a8300e01d490090180253380700ea480482901218803807", - "0x1490094462a80c28000e88c04a9201288c04a8100e88c04a9201201c26807", - "0x5a8094f601c5a809524025110b30309f8038b3012a48048074fe01d11009", - "0x1700704a0254900904a0241600704c0254900904c0240600716802549009", - "0x3807168060128260200245a0095240245a00905a01c0c0095240240c009", - "0x480703001c14814030ae406010030a480c00900e0600480700ea4804807", - "0x1490090200240600700ea480480702001c140095240241500905401c03a92", - "0x2b80700ea480480703001c12809574098138185240601400902801c08009", - "0xf8095240240f0094c801c100095240241380904c01c0f00952402413009", - "0x4a7500e07404a9201201c1000700ea480480703001c03abb01201c0f007", - "0x381f012a480486001299003820012a480482501209803860012a480481d", - "0x1490090f00241480700ea480480703001d438095781e004a9203007c04a74", - "0x80184cc01d428095240254280950201d428095240254300905001d43009", - "0x4a92012a100480c00e01d4900900e06003a82012af541a84030a480c285", - "0x387800e01d4900900e06003a7f012af940281030a480c02001205003a84", - "0x4a83012994038075240254000950c01c03a92012a0404a8700e01d49009", - "0x1490094f6025408074f60254900900ea0803a7e012a480480750601c03a92", - "0x170184fc01c1700952402403a7f00e0b004a920129ed3f01850001d3d809", - "0x3a84012a4804a840120300385f012a480482d0129ec0382d012a480482c", - "0x4a9201217c0482d00e06004a920120600482e00e03004a920120300482c", - "0x4a8700e01d4900900e1e0038075240240381800e17c0c00c5080400485f", - "0x1503300e6b804a920126b8049ae00e6b804a9201201c2f80700ea4804a7f", - "0x1980901801c03a9201201c0c0070346e00c2bf0640cc0c2920306b806284", - "0x38173900e4152c00747101b82a524061418180640a92e00706602549009", - "0x14000707402549009074025408070840254900900ea0c0380752402403818", - "0x149009090024e40070921200c2920121300483900e13004a920120e821018", - "0x49d1012130039d1012a480484d0121080384d012a480484901205c03807", - "0x482e00e0dc04a920120dc0482c00e0cc04a920120cc0480c00e14004a92", - "0x381800e140e203706604004850012a48048500120b4039c4012a48049c4", - "0x4a7b00e14804a9201205c288184fc01c2880952402403a7f00e01d49009", - "0x3839012a48048390120b003833012a480483301203003854012a4804852", - "0x38543900e41981001215004a920121500482d00e72004a920127200482e", - "0x384d00e7d004a9201201d4180700ea4804a830129940380752402403818", - "0x3859012a480481b3e806140007036025490090360254080703602549009", - "0x4a9201215804a7b00e15804a92012165030184fc01d0300952402403a7f", - "0x48180120b80381a012a480481a0120b0039b8012a48049b801203003855", - "0x14900900e06003855030068dc01001215404a920121540482d00e06004a92", - "0x3ac101201c0f0070bc025490095040240600700ea4804820012a1c03807", - "0x600700ea4804820012a1c03807524025438093a201c03a9201201c0c007", - "0x385100e15c04a9201201d4180700ea48048070f001c2f00952402408009", - "0x3a75012a4804a640ae061400074c8025490094c8025408074c802549009", - "0x4a920129c804a7b00e9c804a920129d53a0184fc01d3a00952402403a7f", - "0x48180120b80380c012a480480c0120b00385e012a480485e01203003a71", - "0x14900900e06003a710300302f0100129c404a920129c40482d00e06004a92", - "0x1378095240240384d00e9c004a9201201d4180700ea480482a01214803807", - "0x14900900e9fc03a6b012a4804a6f4e0061400074de025490094de02540807", - "0x480c00e9a404a920129a804a7b00e9a804a920129ac370184fc01c37009", - "0x3818012a48048180120b803829012a48048290120b003814012a4804814", - "0x2b0070180254900900e96c03a690300a40a0100129a404a920129a40482d", - "0xc2c20520500c2920300240381801201c03a9201201c0380700ea4804807", - "0x14900905402539007028025490090280240600700ea480480703001c13828", - "0x161810012a480c01e0129640381e04a098152920120a80a0184b401c15009", - "0x1490090520241600704c0254900904c0240600700ea480480703001c10009", - "0x1525700e04004a92012040060184b001c12809524024128094e401c14809", - "0xc00750e02562078012a480c0600129580386003a07c1529201209414826", - "0x162a84012a480c28501294c03a8550c061490090f00252a80700ea4804807", - "0x3a9201201c080075040254900950c0241500700ea480480703001d41809", - "0x14000905201c03a9201201c0c0074fe02563280502061490185040240a007", - "0x13007058025490094f6024138074f6025490094fc024140074fc02549009", - "0xc00700eb1c0480703c01c168095240241600904a01c1700952402540809", - "0x482600e6b804a9201217c0481f00e17c04a9201201c1000700ea4804807", - "0x164033012a480c02d0120740382d012a48049ae0120940382e012a4804a7f", - "0xc00706e0256481a3700614901805c0240a00700ea480480703001c19009", - "0x138070740254900938802414007388025490090340241480700ea4804807", - "0xb8095240241c80904a01ce4009524024dc00904c01c1c8095240241d009", - "0x481f00e10804a9201201c1000700ea480480703001c03aca01201c0f007", - "0x3817012a480484c012094039c8012a48048370120980384c012a4804842", - "0x1490183900240a00700ea480480703001c2480959612004a9203005c0481d", - "0x140070a2025490093a20241480700ea480480703001c2800959874426818", - "0xfa0095240242680904c01c2a0095240242900904e01c2900952402428809", - "0x1000700ea480480703001c03acd01201c0f007036025490090a802412807", - "0x39f4012a480485001209803a06012a480485901207c03859012a4804807", - "0x480703001c2a80959c15804a9203006c0481d00e06c04a9201281804825", - "0x3c00700ea480480703001d3200959e15c2f018524060fa00902801c03a92", - "0x2b00950801c03a9201215c04a8600e01d490090bc0254380700ea4804807", - "0x4a84012184038075240241980950801c03a9201212004a8400e01d49009", - "0x4a9201201d410074ea0254900900ea0c03807524024080090ee01c03a92", - "0x48074fe01d390095240253a275030a0003a74012a4804a74012a0403a74", - "0x60074de025490094e00253d8074e0025490094e49c40c27e00e9c404a92", - "0xc0095240240c00905c01c0e8095240240e80905801c0f8095240240f809", - "0x14380700ea480480703001d3781803a07c080094de025490094de02416807", - "0x198074d6025490094d6024d70074d60254900900e17c0380752402532009", - "0x387800e01d4900900e0600386b4d20616826a0dc061490184d60740f82a", - "0x487d00e1a133818524025340094a401d340095240240387a00e01d49009", - "0x170074d4025490094d4024160070dc025490090dc0240600700ea4804a67", - "0x142009524025420090f601c08009524024080094a201c0c0095240240c009", - "0x1490090ac0254080709002549009090025408070660254900906602540807", - "0x386f0c4995330105240242b048066a10080680309a8370274a001c2b009", - "0x1490095260252680700ea480480703001d308095a2a4c04a920301bc04a4f", - "0x4a5f01272003a5e4be061490094c00241c8074c00254900900ea0c03807", - "0x12e00909801d2e0095240252e80908401d2e8095240252f00902e01c03a92", - "0x170074ca025490094ca024160074cc025490094cc024060074b602549009", - "0xc0074b618932a660200252d8095240252d80905a01c3100952402431009", - "0x160074cc025490094cc024060074b4025490094c20253d80700ea4804807", - "0x12d0095240252d00905a01c310095240243100905c01d3280952402532809", - "0x2b00950801c03a9201201c3c00700ea480480703001d2d0624ca99808009", - "0x4a84012184038075240241980950801c03a9201212004a8400e01d49009", - "0x4a9201201c268074b20254900900ea0c03807524024080090ee01c03a92", - "0x48074fe01d2b8095240252c259030a0003a58012a4804a58012a0403a58", - "0x60074a6025490094aa0253d8074aa025490094ae9580c27e00e95804a92", - "0xc0095240240c00905c01c358095240243580905801d3480952402534809", - "0x3c00700ea480480703001d298180d69a4080094a6025490094a602416807", - "0x2400950801c03a920127d004a8700e01d490090aa024e880700ea4804807", - "0x48100121dc03807524025420090c201c03a920120cc04a8400e01d49009", - "0x1490090ee025408070ee0254900900e91403861012a480480750601c03a92", - "0x1290184fc01d2900952402403a7f00e1e804a920121dc3081850001c3b809", - "0x381f012a480481f01203003a51012a480487d0129ec0387d012a480487a", - "0x4a920129440482d00e06004a920120600482e00e07404a920120740482c", - "0x49d100e01d4900900e1e0038075240240381800e9440c01d03e04004a51", - "0x1980950801c03a9201272004a8700e01d490090200243b80700ea4804849", - "0x14900900e91c0387b012a480480750601c03a92012a100486100e01d49009", - "0x3a7f00e93c04a920129403d81850001d280095240252800950201d28009", - "0x3a47012a4804a450129ec03a45012a4804a4f49a0613f00749a02549009", - "0x4a920120600482e00e07404a920120740482c00e07c04a9201207c0480c", - "0x38075240240381800e91c0c01d03e04004a47012a4804a470120b403818", - "0x486100e01d490090200243b80700ea48048320127440380752402403878", - "0x48074d001d2100952402403a8300e01d4900905c0254380700ea4804a84", - "0x13f80710e025490094829080c28000e90404a9201290404a8100e90404a92", - "0x11e0095240251e8094f601d1e80952402443a3f0309f803a3f012a4804807", - "0x1490090300241700703a0254900903a0241600703e0254900903e02406007", - "0x3a9201201c0c0074780600e81f0200251e0095240251e00905a01c0c009", - "0x3807524025430090a401c03a920120400487700e01d49009506024e8807", - "0x3a3a012a4804a3a012a0403a3a012a48048070a001c4580952402403a83", - "0x1490094702300c27e00e23004a9201201d3f8074700254900947422c0c280", - "0xe80905801c0f8095240240f80901801d1b809524024480094f601c48009", - "0x800946e0254900946e02416807030025490090300241700703a02549009", - "0x4a870129ec03807524024080090ee01c03a9201201c0c00746e0600e81f", - "0x482e00e07404a920120740482c00e07c04a9201207c0480c00e8d004a92", - "0x381800e8d00c01d03e04004a34012a4804a340120b403818012a4804818", - "0x480c01290803807524024128090a401c03a92012080049d100e01d49009", - "0x149009464025408074640254900900e14403a33012a480480750601c03a92", - "0x1180184fc01d1800952402403a7f00e8c404a920128c91981850001d19009", - "0x3826012a480482601203003a2c012a4804a2f0129ec03a2f012a4804a31", - "0x4a920128b00482d00e06004a920120600482e00e0a404a920120a40482c", - "0x12100700ea480482a012148038075240240381800e8b00c02904c04004a2c", - "0x4a8100e1b004a9201201c268071300254900900ea0c0380752402406009", - "0x3a2a012a48048074fe01d1580952402436098030a000386c012a480486c", - "0x14900905002406007136025490094520253d807452025490094568a80c27e", - "0x4d80905a01c0c0095240240c00905c01c138095240241380905801c14009", - "0x14900900e8180380c012a480480740c01c4d81804e0a00800913602549009", - "0xc2920300240381801201c03a9201201c0380700ea48048070ac01c14809", - "0x800703c025490090540241500700ea480480703001c12826030b4813828", - "0x16981f0400614901803c0240a007050025490090500240600700ea4804807", - "0x1490090c0024140070c00254900903e0241480700ea480480703001c0e809", - "0x14380904a01d430095240241000904c01d438095240243c00904e01c3c009", - "0x4a9201201c1000700ea480480703001c03ad401201c0f00750a02549009", - "0x4a8301209403a86012a480481d01209803a83012a4804a8401207c03a84", - "0x2a80700ea480480703001d410095aa05004a92030a140481d00ea1404a92", - "0xc0074fe0256b280502061490180280a00c24100e05004a9201205014818", - "0x16ba7b4fc0614901850c0240a007502025490095020240600700ea4804807", - "0x14900905c0241400705c025490094f60241480700ea480480703001c16009", - "0x2f80904a01cd70095240253f00904c01c2f8095240241680904e01c16809", - "0x4a9201201c1000700ea480480703001c03ad801201c0f00706602549009", - "0x49b8012094039ae012a480482c012098039b8012a480483201207c03832", - "0x2a80700ea480480703001c0d0095b204004a920300cc0481d00e0cc04a92", - "0x381800e0e804ada3880dc0c2920306b80481400e04004a9201204006018", - "0x4a6400e72004a920120dc0482600e0e404a920127100485700e01d49009", - "0x14900900e080038075240240381800e01d6d80900e07803817012a4804839", - "0x260094c801ce40095240241d00904c01c26009524024210094ea01c21009", - "0x38075240240381800e12404adc0900254901802e0253a00702e02549009", - "0xb8073a20254900900ea0c0384d012a48048480120a40380752402403878", - "0x1408095240254080901801c288095240242680905001c28009524024e4009", - "0x1490093a2024240070a0025490090a00253900704e0254900904e02416007", - "0x2902a524024289d10a009d4080c4e201c288095240242880950201ce8809", - "0x4a6f00e01d4900900e06003859012b740d809524060fa0094e001cfa054", - "0x2f0095240242900901801c2a8095240250300905401c2b206030a480481b", - "0x1490090ac025358074c8025490090aa024130070ae025490090a802416007", - "0x38075240254000910e01c03a9201201c0c00700eb780480703c01d3a809", - "0x290095240242900901801d3a0095240242c8094f601c03a9201204004a84", - "0x1490094e80241680703002549009030024170070a8025490090a802416007", - "0xe880700ea48048070f001c03a9201201c0c0074e80602a0520200253a009", - "0x60074e2025490094e4025350074e40254900900e0800380752402424809", - "0x132009524024e400904c01c2b8095240241380905801c2f00952402540809", - "0x381800e9bc04adf4e0025490184ea025348074ea025490094e202535807", - "0x38075240240381800e9a804ae00dc9ac0c2920309900481400e01d49009", - "0x14200700ea4804a70012720038075240243700950c01c03a920129ac04a87", - "0x3a8200e9a404a9201201d4180700ea4804a8001221c0380752402408009", - "0x3a68012a480486b4d2061400070d6025490090d6025408070d602549009", - "0x4a920121a004a7b00e1a004a920129a1338184fc01d3380952402403a7f", - "0x48180120b803857012a48048570120b00385e012a480485e01203003a66", - "0x14900900e06003a6603015c2f01001299804a920129980482d00e06004a92", - "0x4a92012994049ae00e99404a9201201c2f80700ea4804a6a012a1c03807", - "0x3a9201201c0c0074c2a4c0c2e10de1880c2920309942b85e0540cc03a65", - "0x1490094be0240b80700ea4804a6001272003a5f4c0061490094e00241c807", - "0x12e82a5240612f0105000603780c47e01c310095240243100901801d2f009", - "0x3a57012a4804a5b012108038075240240381800e9612ca5a054b892da5c", - "0x4a920129740482c00e18804a920121880480c00e95804a9201295c0484c", - "0x12e25d0c404004a56012a4804a560120b403a5c012a4804a5c0120b803a5d", - "0x4a920129612a8184fc01d2a80952402403a7f00e01d4900900e06003a56", - "0x4a5a0120b003862012a480486201203003861012a4804a530129ec03a53", - "0x3101001218404a920121840482d00e96404a920129640482e00e96804a92", - "0x1490090200254200700ea4804a70012720038075240240381800e1852ca5a", - "0x3d0095240240384d00e1dc04a9201201d4180700ea4804a8001221c03807", - "0x14900900e9fc03a52012a480487a0ee061400070f4025490090f402540807", - "0x480c00e1ec04a9201294404a7b00e94404a920129483e8184fc01c3e809", - "0x3818012a48048180120b803a61012a4804a610120b003a93012a4804a93", - "0x49d100e01d4900900e0600387b030985498100121ec04a920121ec0482d", - "0x14000910e01c03a9201204004a8400e01d490094c80254380700ea4804a6f", - "0x4a4f012a0403a4f012a48048074d001d2800952402403a8300e01d49009", - "0xc27e00e91404a9201201d3f80749a0254900949e9400c28000e93c04a92", - "0x2f0095240242f00901801d21009524025238094f601d2380952402526a45", - "0x1490094840241680703002549009030024170070ae025490090ae02416007", - "0xe880700ea48048070f001c03a9201201c0c0074840602b85e02002521009", - "0x4a6700e01d490095000244380700ea48049ae012a1c038075240240d009", - "0x4380950201c438095240240385000e90404a9201201d4180700ea480480c", - "0x13f00747a0254900900e9fc03a3f012a48048874820614000710e02549009", - "0x4a92012a040480c00e22c04a920128f004a7b00e8f004a920128fd1e818", - "0x488b0120b403818012a48048180120b803827012a48048270120b003a81", - "0x3a9201203004a6700e01d4900900e0600388b03009d4081001222c04a92", - "0x38075c60240381e00e8e804a920129fc0480c00e01d4900950c02543807", - "0x4a8700e01d490090180253380700ea4804a820127440380752402403818", - "0x387800e8e804a920120a00480c00e01d490090520253380700ea4804a86", - "0x488c012a040388c012a48048070a201d1c00952402403a8300e01d49009", - "0xc27e00e8dc04a9201201d3f807120025490091188e00c28000e23004a92", - "0x11d0095240251d00901801d198095240251a0094f601d1a00952402448237", - "0x14900946602416807030025490090300241700704e0254900904e02416007", - "0x3807524024060094ce01c03a9201201c0c00746606013a3a02002519809", - "0x268074640254900900ea0c03807524024148094ce01c03a920120a804852", - "0x11800952402518a32030a0003a31012a4804a31012a0403a31012a4804807", - "0x1490094580253d807458025490094608bc0c27e00e8bc04a9201201d3f807", - "0xc00905c01c128095240241280905801c130095240241300901801c4c009", - "0x480700e01c4c01804a09808009130025490091300241680703002549009", - "0x3a9201201c0c0070520500c2e40180400c2920300240381801201c03a92", - "0x80095240240800901801c03a9201201c080070500254900905402415007", - "0x1300905201c03a9201201c0c00704a0257282604e061490180500240a007", - "0x1300703e02549009040024138070400254900903c0241400703c02549009", - "0xc00700eb980480703c01c300095240240f80904a01c0e80952402413809", - "0x482600ea1c04a920121e00481f00e1e004a9201201c1000700ea4804807", - "0x173a86012a480c06001207403860012a4804a870120940381d012a4804825", - "0x3a82012ba141a84030a480c2860200612080700ea480480703001d42809", - "0x140281030a480c01d01205003a84012a4804a840120300380752402403818", - "0x4a7e0120a003a7e012a4804a800120a4038075240240381800e9fc04ae9", - "0x482500e0b804a92012a040482600e0b004a920129ec0482700e9ec04a92", - "0x14900900e080038075240240381800e01d7500900e0780382d012a480482c", - "0xd700904a01c170095240253f80904c01cd70095240242f80903e01c2f809", - "0x38075240240381800e0c804aeb0660254901805a0240e80705a02549009", - "0x481a0120a4038075240240381800e0dc04aec0346e00c2920300b804814", - "0x482600e0e404a920120e80482700e0e804a920127100482800e71004a92", - "0x381800e01d7680900e07803817012a4804839012094039c8012a48049b8", - "0x1b80904c01c260095240242100903e01c210095240240382000e01d49009", - "0x4aee0900254901802e0240e80702e025490090980241280739002549009", - "0x381800e14004aef3a21340c2920307200481400e01d4900900e06003849", - "0x482700e14804a920121440482800e14404a920127440482900e01d49009", - "0x381b012a4804854012094039f4012a480484d01209803854012a4804852", - "0x2c80903e01c2c8095240240382000e01d4900900e060038075e00240381e", - "0xe8070360254900940c024128073e8025490090a00241300740c02549009", - "0xc2920307d00481400e01d4900900e06003855012bc42b0095240600d809", - "0x482800e9d404a9201215c0482900e01d4900900e06003a64012bc82b85e", - "0x3a71012a480485e01209803a72012a4804a7401209c03a74012a4804a75", - "0x382000e01d4900900e060038075e60240381e00e9c004a920129c804825", - "0x128074e2025490094c8024130074d6025490094de0240f8074de02549009", - "0x14900900e06003a6a012bd0370095240613800903a01d3800952402535809", - "0x387800e01d4900900e06003a68012bd435a69030a480c27101205003807", - "0x486e012a10038075240243580950c01c03a920129a404a8700e01d49009", - "0x1490090660254200700ea4804848012a10038075240242b00950801c03a92", - "0x3400952402403a8200e99c04a9201201d4180700ea4804a8301221c03807", - "0x14900900e9fc03a66012a48048684ce061400070d0025490090d002540807", - "0x480c00e1bc04a9201218804a7b00e18804a92012999328184fc01d32809", - "0x3818012a48048180120b80380c012a480480c0120b003a84012a4804a84", - "0x4a8700e01d4900900e0600386f030031420100121bc04a920121bc0482d", - "0x1503300ea4c04a92012a4c049ae00ea4c04a9201201c2f80700ea4804a68", - "0x48070f001c03a9201201c0c0074bc97c0c2f64c09840c292030a4c06284", - "0x12e0090fa01d2da5c030a4804a5d01294803a5d012a48048070f401c03a92", - "0x4a3d00e06004a920120600482e00e98004a920129800482c00e01d49009", - "0x3848012a4804848012a0403833012a4804833012a0403a83012a4804a83", - "0x141a5b0309801423c00e1b804a920121b804a8100e15804a9201215804a81", - "0x12d00905801d308095240253080901801d2c2594b40a9490090dc15824033", - "0x80094b0025490094b0024168074b2025490094b2024170074b402549009", - "0x1490090dc0254200700ea48048070f001c03a9201201c0c0074b09652d261", - "0x3a920120cc04a8400e01d490090900254200700ea4804856012a1003807", - "0x3a56012a480480709a01d2b80952402403a8300e01d4900950602443807", - "0x4a9201201d3f8074aa025490094ac95c0c28000e95804a9201295804a81", - "0x12f80901801c3b809524024308094f601c308095240252aa530309f803a53", - "0x1680703002549009030024170074bc025490094bc024160074be02549009", - "0x48070f001c03a9201201c0c0070ee0612f25f0200243b8095240243b809", - "0x1490090ac0254200700ea4804a71012a1c03807524025350093a201c03a92", - "0x3a92012a0c0488700e01d490090660254200700ea4804848012a1003807", - "0x1290095240252900950201d2900952402403a4500e1e804a9201201d41807", - "0x487d4a20613f0074a20254900900e9fc0387d012a4804a520f406140007", - "0x482c00ea1004a92012a100480c00e94004a920121ec04a7b00e1ec04a92", - "0x4a50012a4804a500120b403818012a48048180120b80380c012a480480c", - "0x4855012744038075240240387800e01d4900900e06003a5003003142010", - "0x1490090900254200700ea48049f4012a1c038075240254180910e01c03a92", - "0x12680952402403a4700e93c04a9201201d4180700ea4804833012a1003807", - "0x14900900e9fc03a45012a4804a4d49e0614000749a0254900949a02540807", - "0x480c00e90404a9201290804a7b00e90804a92012915238184fc01d23809", - "0x3818012a48048180120b80380c012a480480c0120b003a84012a4804a84", - "0x387800e01d4900900e06003a410300314201001290404a920129040482d", - "0x4833012a10038075240254180910e01c03a92012124049d100e01d49009", - "0x4a9201201d3400710e0254900900ea0c03807524024e400950e01c03a92", - "0x48074fe01d1e8095240251f887030a0003a3f012a4804a3f012a0403a3f", - "0x6007474025490091160253d8071160254900947a8f00c27e00e8f004a92", - "0xc0095240240c00905c01c060095240240600905801d4200952402542009", - "0x3c00700ea480480703001d1d018018a10080094740254900947402416807", - "0x1700950e01c03a92012a0c0488700e01d49009064024e880700ea4804807", - "0x488c012a040388c012a48048070a001d1c00952402403a8300e01d49009", - "0xc27e00e8dc04a9201201d3f807120025490091188e00c28000e23004a92", - "0x1420095240254200901801d198095240251a0094f601d1a00952402448237", - "0x1490094660241680703002549009030024170070180254900901802416007", - "0x38075240240e80950e01c03a9201201c0c0074660600628402002519809", - "0x49d100e01d4900900e060038075ee0240381e00e8c804a92012a080480c", - "0x387800e8c804a920120400480c00e01d4900903a0254380700ea4804a85", - "0x4a30012a0403a30012a48048070a201d1880952402403a8300e01d49009", - "0xc27e00e8b004a9201201d3f80745e025490094608c40c28000e8c004a92", - "0x1190095240251900901801c360095240244c0094f601c4c00952402517a2c", - "0x1490090d80241680703002549009030024170070180254900901802416007", - "0x3807524024150090a401c03a9201201c0c0070d80600623202002436009", - "0x3a2a012a4804a2a012a0403a2a012a480480709a01d1580952402403a83", - "0x14900945226c0c27e00e26c04a9201201d3f807452025490094548ac0c280", - "0x1480905801c0a0095240240a00901801c4e0095240244e8094f601c4e809", - "0x80091380254900913802416807030025490090300241700705202549009", - "0xc2f80180400c2920300240381801201c03a9201201c0380713806014814", - "0x3a9201201c08007050025490090540241500700ea480480703001c14814", - "0xc00704a0257c82604e061490180500240a0070200254900902002406007", - "0x138070400254900903c0241400703c0254900904c0241480700ea4804807", - "0x300095240240f80904a01c0e8095240241380904c01c0f80952402410009", - "0x481f00e1e004a9201201c1000700ea480480703001c03afa01201c0f007", - "0x3860012a4804a870120940381d012a480482501209803a87012a4804878", - "0xc2860200612080700ea480480703001d428095f6a1804a920301800481d", - "0x3a84012a4804a84012030038075240240381800ea0804afc506a100c292", - "0x14900900e1e0038075240240381800e9fc04afd500a040c29203007404814", - "0x3a92012a0c0488700e01d490095000254300700ea4804a81012a1c03807", - "0x13d8095240253d80950201d3d80952402403a8200e9f804a9201201d41807", - "0x482c05c0613f00705c0254900900e9fc0382c012a4804a7b4fc06140007", - "0x482c00ea1004a92012a100480c00e17c04a920120b404a7b00e0b404a92", - "0x485f012a480485f0120b403818012a48048180120b80380c012a480480c", - "0x4a7f012a1c038075240240387800e01d4900900e0600385f03003142010", - "0x62840540cc039ae012a48049ae0126b8039ae012a48048070be01c03a92", - "0x1490090660240600700ea480480703001c0d1b8030bf819033030a480c1ae", - "0x480703001ce40390740a97f9c406e061490185060601902a11601c19809", - "0x2100939001c26042030a48048170120e403817012a480480750601c03a92", - "0x484c00e12404a920121200484200e12004a920121300481700e01d49009", - "0x3837012a48048370120b003833012a48048330120300384d012a4804849", - "0x384d3880dc1981001213404a920121340482d00e71004a920127100482e", - "0x3850012a48049c83a20613f0073a20254900900e9fc0380752402403818", - "0x4a920120e80482c00e0cc04a920120cc0480c00e14404a9201214004a7b", - "0x1c83a06604004851012a48048510120b403839012a48048390120b80383a", - "0x3852012a480480750601c03a92012a0c0488700e01d4900900e06003851", - "0x4a920121502901850001c2a0095240242a00950201c2a0095240240384d", - "0x48590129ec03859012a48049f40360613f0070360254900900e9fc039f4", - "0x482e00e06804a920120680482c00e6e004a920126e00480c00e81804a92", - "0x381800e8180c01a37004004a06012a4804a060120b403818012a4804818", - "0x480703c01c2b0095240254100901801c03a9201207404a8700e01d49009", - "0x3a9201207404a8700e01d4900950a024e880700ea480480703001c03b00", - "0x3855012a480480750601c03a9201201c3c0070ac0254900902002406007", - "0x4a920121782a81850001c2f0095240242f00950201c2f00952402403851", - "0x4a750129ec03a75012a48048574c80613f0074c80254900900e9fc03857", - "0x482e00e03004a920120300482c00e15804a920121580480c00e9d004a92", - "0x381800e9d00c00c0ac04004a74012a4804a740120b403818012a4804818", - "0x14900900e13403a72012a480480750601c03a920120a80485200e01d49009", - "0x3a7f00e9c004a920129c53901850001d388095240253880950201d38809", - "0x386e012a4804a6b0129ec03a6b012a4804a704de0613f0074de02549009", - "0x4a920120600482e00e0a404a920120a40482c00e05004a920120500480c", - "0x600952402403a0600e1b80c0290280400486e012a480486e0120b403818", - "0x14814030a480c00900e0600480700ea480480700e01c03a9201201c2b007", - "0x480702001c130095240241500905401c03a9201201c0c00704e0a00c301", - "0x10009604078128185240601300902801c0a0095240240a00901801c03a92", - "0xe8095240240f80905001c0f8095240240f00905201c03a9201201c0c007", - "0x1490090c0024128070f00254900904a024130070c00254900903a02413807", - "0x3a86012a480480704001c03a9201201c0c00700ec0c0480703c01d43809", - "0x4a92012a140482500e1e004a920120800482600ea1404a92012a180481f", - "0x60180aa01c03a9201201c0c00750802582010012a480c28701207403a87", - "0x14900900e06003a81012c1541283030a480c07801205003810012a4804810", - "0x4a8001299003a7f012a4804a8301209803a80012a4804a8201215c03807", - "0x13d8095240240382000e01d4900900e0600380760c0240381e00e9f804a92", - "0x149009058025320074fe0254900950202413007058025490094f60253a807", - "0x387800e01d4900900e0600382d012c1c170095240613f0094e801d3f009", - "0x13f80902e01cd700952402403a8300e17c04a920120b80482900e01d49009", - "0x160070280254900902802406007064025490090be0241400706602549009", - "0xd7009524024d700909001c19809524024198094e401c1480952402414809", - "0x1b81a3700a9490090646b819829028031388070640254900906402540807", - "0x49c40129bc038075240240381800e0e804b083880254901806e02538007", - "0x16007084025490093700240600702e02549009072024150073900e40c292", - "0x24809524024e40094d601c240095240240b80904c01c260095240240d009", - "0x4a7b00e01d490090200254200700ea480480703001c03b0901201c0f007", - "0x381a012a480481a0120b0039b8012a48049b80120300384d012a480483a", - "0x384d030068dc01001213404a920121340482d00e06004a920120600482e", - "0x480704001c03a920120b4049d100e01d4900900e1e00380752402403818", - "0x482c00e10804a920120500480c00e14004a9201274404a6a00e74404a92", - "0x3849012a48048500129ac03848012a4804a7f0120980384c012a4804829", - "0x1490180900240a00700ea480480703001c2900961414404a9203012404a69", - "0x4a8600e01d490090a80254380700ea480480703001c0d8096167d02a018", - "0x480750601c03a9201204004a8400e01d490090a2024e400700ea48049f4", - "0x2c81850001d030095240250300950201d0300952402403a8200e16404a92", - "0x385e012a48048560aa0613f0070aa0254900900e9fc03856012a4804a06", - "0x4a920121300482c00e10804a920121080480c00e15c04a9201217804a7b", - "0xc04c08404004857012a48048570120b403818012a48048180120b80384c", - "0x3a64012a48048070be01c03a9201206c04a8700e01d4900900e06003857", - "0x138a72030c313a275030a480c2640981081503300e99004a92012990049ae", - "0x3a920129c0049c800e9bd380185240242880907201c03a9201201c0c007", - "0x80184e80411d0074ea025490094ea024060074d6025490094de0240b807", - "0x14900900ea0c038075240240381800e9a035a69054c353506e030a480c26b", - "0x13300902e01c03a920121a0049c800e998340185240253380907201d33809", - "0x60070de025490090c4024260070c4025490094ca024210074ca02549009", - "0x1350095240253500905c01c370095240243700905801d3a8095240253a809", - "0x13f80700ea480480703001c37a6a0dc9d4080090de025490090de02416807", - "0x130009524025308094f601d30809524025342930309f803a93012a4804807", - "0x1490090d6024170074d2025490094d2024160074ea025490094ea02406007", - "0x3a9201201c0c0074c01ad34a75020025300095240253000905a01c35809", - "0x3a5f012a480480750601c03a9201204004a8400e01d490090a2024e4007", - "0x4a920129792f81850001d2f0095240252f00950201d2f0095240240384d", - "0x4a5b0129ec03a5b012a4804a5d4b80613f0074b80254900900e9fc03a5d", - "0x482e00e9c404a920129c40482c00e9c804a920129c80480c00e96804a92", - "0x381800e9680c2714e404004a5a012a4804a5a0120b403818012a4804818", - "0x4810012a10038075240242400950e01c03a92012148049d100e01d49009", - "0x1490094b0025408074b00254900900e14003a59012a480480750601c03a92", - "0x12b0184fc01d2b00952402403a7f00e95c04a920129612c81850001d2c009", - "0x3842012a480484201203003a53012a4804a550129ec03a55012a4804a57", - "0x4a9201294c0482d00e06004a920120600482e00e13004a920121300482c", - "0x49d100e01d4900900e1e0038075240240381800e94c0c04c08404004a53", - "0x480750601c03a9201203004a6700e01d490090f00254380700ea4804a84", - "0x3081850001c3b8095240243b80950201c3b8095240240385100e18404a92", - "0x387d012a480487a4a40613f0074a40254900900e9fc0387a012a4804877", - "0x4a920120a40482c00e05004a920120500480c00e94404a920121f404a7b", - "0xc02902804004a51012a4804a510120b403818012a48048180120b803829", - "0x3807524024150090a401c03a9201203004a6700e01d4900900e06003a51", - "0x3a50012a4804a50012a0403a50012a480480709a01c3d80952402403a83", - "0x14900949e9340c27e00e93404a9201201d3f80749e025490094a01ec0c280", - "0x1380905801c140095240241400901801d23809524025228094f601d22809", - "0x800948e0254900948e02416807030025490090300241700704e02549009", - "0xc30e0280300c2920300600381801201c03a9201201c0380748e06013828", - "0x1490090180240600704e025490090200241500700ea480480703001c14029", - "0x14380700ea480480703001c0f00961e094130185240601380902801c06009", - "0x3a8200e08004a9201201d4180700ea4804825012a180380752402413009", - "0x381d012a480481f0400614000703e0254900903e0254080703e02549009", - "0x4a920121e004a7b00e1e004a92012074300184fc01c3000952402403a7f", - "0x48140120b003809012a48048090128e00380c012a480480c01203003a87", - "0x600c012a1c04a92012a1c0482d00e0a804a920120a80482e00e05004a92", - "0x14900900e17c038075240240f00950e01c03a9201201c0c00750e0a80a009", - "0x18828450a0614901850c0500602a06601d430095240254300935c01d43009", - "0x14280901801d40281030a4804809012230038075240240381800ea0941818", - "0x480075080254900950802416007502025490095020251c00750a02549009", - "0x11a0070589ed3f27f020a4804a80508a054281046e01d4000952402540009", - "0x385f05a0614900905c0241c80705c0254900900ea0c0380752402416009", - "0x19809524024d700908401cd70095240242f80902e01c03a920120b4049c8", - "0x1490094fc0251c0074fe025490094fe024060070640254900906602426007", - "0x1900905a01c150095240241500905c01d3d8095240253d80905801d3f009", - "0x14900900ea0c038075240240381800e0c81527b4fc9fc0600906402549009", - "0xd1b8030a000381a012a480481a012a040381a012a480480709a01cdc009", - "0x13d8070740254900906e7100c27e00e71004a9201201d3f80706e02549009", - "0x48095240240480947001d418095240254180901801c1c8095240241d009", - "0x1490090720241680705402549009054024170075040254900950402416007", - "0x3a920120400485200e01d4900900e06003839054a0804a830180241c809", - "0xb8095240240b80950201c0b8095240240384d00e72004a9201201d41807", - "0x48420980613f0070980254900900e9fc03842012a480481739006140007", - "0x4a3800e0a404a920120a40480c00e12404a9201212004a7b00e12004a92", - "0x382a012a480482a0120b803828012a48048280120b003809012a4804809", - "0x380c012a480480740c01c2482a0500241480c01212404a920121240482d", - "0x381801201c03a9201201c0380700ea48048070ac01c1480952402403a06", - "0x1490090540241500700ea480480703001c12826030c4413828030a480c009", - "0x14901803c0240a007050025490090500240600700ea480480702001c0f009", - "0x140070c00254900903e0241480700ea480480703001c0e80962407c10018", - "0x1430095240241000904c01d438095240243c00904e01c3c00952402430009", - "0x1000700ea480480703001c03b1301201c0f00750a0254900950e02412807", - "0x3a86012a480481d01209803a83012a4804a8401207c03a84012a4804807", - "0x480703001d4100962805004a92030a140481d00ea1404a92012a0c04825", - "0x18aa80502061490180280a00c24100e05004a92012050148180aa01c03a92", - "0x14901850c0240a007502025490095020240600700ea480480703001d3f809", - "0x1400705c025490094f60241480700ea480480703001c1600962c9ed3f018", - "0xd70095240253f00904c01c2f8095240241680904e01c1680952402417009", - "0x1000700ea480480703001c03b1701201c0f007066025490090be02412807", - "0x39ae012a480482c012098039b8012a480483201207c03832012a4804807", - "0x480703001c0d00963004004a920300cc0481d00e0cc04a920126e004825", - "0x4b193880dc0c2920306b80481400e04004a92012040060180aa01c03a92", - "0x4a920120dc0482600e0e404a920127100485700e01d4900900e0600383a", - "0x38075240240381800e01d8d00900e07803817012a4804839012990039c8", - "0xe40095240241d00904c01c26009524024210094ea01c2100952402403820", - "0x381800e12404b1b0900254901802e0253a00702e0254900909802532007", - "0x14900900ea0c0384d012a48048480120a4038075240240387800e01d49009", - "0x14080901801c288095240242680905001c28009524024e400902e01ce8809", - "0x240070a0025490090a00253900704e0254900904e0241600750202549009", - "0x289d10a009d4080c4e201c288095240242880950201ce8809524024e8809", - "0x14900900e06003859012c700d809524060fa0094e001cfa0540a40a949009", - "0x2900901801c2a8095240250300905401c2b206030a480481b0129bc03807", - "0x1358074c8025490090aa024130070ae025490090a8024160070bc02549009", - "0x14000910e01c03a9201201c0c00700ec740480703c01d3a8095240242b009", - "0x2900901801d3a0095240242c8094f601c03a9201204004a8400e01d49009", - "0x1680703002549009030024170070a8025490090a8024160070a402549009", - "0x48070f001c03a9201201c0c0074e80602a0520200253a0095240253a009", - "0x1490094e4025350074e40254900900e08003807524024248093a201c03a92", - "0xe400904c01c2b8095240241380905801c2f0095240254080901801d38809", - "0x4b1e4e0025490184ea025348074ea025490094e2025358074c802549009", - "0x3726b030a480c264012050038075240240381000e01d4900900e06003a6f", - "0x4a6b01209803a69012a480486e01215c038075240240381800e9a804b1f", - "0x14900900e060038076400240381e00e9a004a920129a404a6400e1ac04a92", - "0x1490094d4024130070d0025490094ce0253a8074ce0254900900e08003807", - "0x3a65012c8533009524061340094e801d34009524024340094c801c35809", - "0x386f012a48048620120a003862012a4804a660120a40380752402403818", - "0x14900900e06003a93012c8803a920301bc04a3300e1bc04a920121bc04a81", - "0x1490094c0025188074c0025490094c2025190074c20254900900e08003807", - "0x38075240254980946001c03a9201201c0c00700ec8c0480703c01d2f809", - "0x12f8095240252e80946201d2e8095240252f00945e01d2f00952402403820", - "0x48070f001c03a9201201c0c0074b40259225b4b8061490180d60240a007", - "0x1490094be0251600700ea4804a5b012a18038075240252e00950e01c03a92", - "0x3a92012a000488700e01d490090200254200700ea4804a7001272003807", - "0x12c0095240252c00950201d2c00952402403a8200e96404a9201201d41807", - "0x4a574ac0613f0074ac0254900900e9fc03a57012a4804a584b206140007", - "0x482c00e17804a920121780480c00e94c04a9201295404a7b00e95404a92", - "0x4a53012a4804a530120b403818012a48048180120b803857012a4804857", - "0x48070be01c03a9201296804a8700e01d4900900e06003a5303015c2f010", - "0x3d077030a480c0610ae1781503300e18404a92012184049ae00e18404a92", - "0x1490094be0244c00700ea48048070f001c03a9201201c0c0070fa9480c325", - "0x12800902e01c03a920121ec049c800e9403d8185240253800907201d28809", - "0x360070ee025490090ee024060074a2025490094a20251880749e02549009", - "0x381800e8fc43a41054c992124748a93408292030945278105000603d014", - "0x14900900ea0c03807524025210090a401c03a9201291c0486e00e01d49009", - "0x4580902e01c03a920128f0049c800e22d1e0185240251e80907201d1e809", - "0x60071180254900947002426007470025490094740242100747402549009", - "0x1228095240252280905c01d268095240252680905801c3b8095240243b809", - "0x13f80700ea480480703001c4624549a1dc080091180254900911802416807", - "0x11a0095240251b8094f601d1b8095240251f8900309f803890012a4804807", - "0x14900910e0241700748202549009482024160070ee025490090ee02406007", - "0x3a9201201c0c00746821d208770200251a0095240251a00905a01c43809", - "0x14200700ea4804a70012720038075240252f80945801c03a9201201c3c007", - "0x384d00e8cc04a9201201d4180700ea4804a8001221c0380752402408009", - "0x3a31012a4804a3246606140007464025490094640254080746402549009", - "0x4a920128bc04a7b00e8bc04a920128c5180184fc01d1800952402403a7f", - "0x48180120b80387d012a480487d0120b003a52012a4804a5201203003a2c", - "0x14900900e06003a2c0301f5290100128b004a920128b00482d00e06004a92", - "0x38075240243580950e01c03a92012994049d100e01d4900900e1e003807", - "0x14180700ea4804a8001221c038075240240800950801c03a920129c0049c8", - "0x1400070d8025490090d8025408070d80254900900e91c03898012a4804807", - "0x4a920128ad150184fc01d1500952402403a7f00e8ac04a920121b04c018", - "0x48570120b00385e012a480485e0120300389b012a4804a290129ec03a29", - "0x2f01001226c04a9201226c0482d00e06004a920120600482e00e15c04a92", - "0x1490095000244380700ea4804a6f012744038075240240381800e26c0c057", - "0x4e80952402403a8300e01d490090200254200700ea4804a64012a1c03807", - "0x1490091382740c28000e27004a9201227004a8100e27004a9201201d34007", - "0x1138094f601d138095240244d2280309f803a28012a48048074fe01c4d009", - "0x170070ae025490090ae024160070bc025490090bc0240600714602549009", - "0xc0071460602b85e020024518095240245180905a01c0c0095240240c009", - "0x49ae012a1c038075240240d0093a201c03a9201201c3c00700ea4804807", - "0x4a9201201d4180700ea480480c01299c038075240254000910e01c03a92", - "0x48a414a0614000714802549009148025408071480254900900e140038a5", - "0x4a7b00e89404a92012289130184fc01d1300952402403a7f00e28804a92", - "0x3827012a48048270120b003a81012a4804a81012030038ab012a4804a25", - "0x38ab03009d408100122ac04a920122ac0482d00e06004a920120600482e", - "0x480c00e01d4900950c0254380700ea480480c01299c0380752402403818", - "0x4a82012744038075240240381800e01d9380900e078038ad012a4804a7f", - "0x1490090520253380700ea4804a86012a1c03807524024060094ce01c03a92", - "0x5600952402403a8300e01d4900900e1e0038ad012a480482801203003807", - "0x1490091542b00c28000e2a804a920122a804a8100e2a804a9201201c28807", - "0x598094f601c5980952402511a220309f803a22012a48048074fe01d11809", - "0x1700704e0254900904e0241600715a0254900915a0240600716a02549009", - "0xc00716a060138ad0200245a8095240245a80905a01c0c0095240240c009", - "0x148094ce01c03a920120a80485200e01d490090180253380700ea4804807", - "0x48b2012a04038b2012a480480709a01c5a00952402403a8300e01d49009", - "0xc27e00e30004a9201201d3f807442025490091642d00c28000e2c804a92", - "0x130095240241300901801c5d0095240245d8094f601c5d809524025108c0", - "0x14900917402416807030025490090300241700704a0254900904a02416007", - "0xc2920300240381801201c03a9201201c03807174060128260200245d009", - "0x6007050025490090540241500700ea480480703001c14814030ca006010", - "0x480703001c12809652098138185240601400902801c0800952402408009", - "0x4a9201201d4180700ea4804826012a18038075240241380950e01c03a92", - "0x482003c0614000704002549009040025408070400254900900ea080381e", - "0x4a7b00e18004a9201207c0e8184fc01c0e80952402403a7f00e07c04a92", - "0x380c012a480480c0120b003810012a480481001203003878012a4804860", - "0x3878030030080100121e004a920121e00482d00e06004a920120600482e", - "0x49ae00ea1c04a9201201c2f80700ea4804825012a1c0380752402403818", - "0xc007506a100c32a50aa180c292030a1c060100540cc03a87012a4804a87", - "0x482c00ea1804a92012a180480c00ea0804a9201201c3d00700ea4804807", - "0x14900950406142a860208ac03818012a48048180120b803a85012a4804a85", - "0x3a9201201c0c00705802595a7b012a480c27e0128a803a7e4fea0140810", - "0x168185240241700907201c1700952402403a8300e01d490094f602514807", - "0x14900935c0242100735c025490090be0240b80700ea480482d0127200385f", - "0x14000905801d408095240254080901801c190095240241980909801c19809", - "0x800906402549009064024168074fe025490094fe0241700750002549009", - "0x14080901801cdc009524024160094f601c03a9201201c0c0070649fd40281", - "0x168074fe025490094fe02417007500025490095000241600750202549009", - "0x480750601c03a9201201c0c0073709fd40281020024dc009524024dc009", - "0xd01850001c1b8095240241b80950201c1b8095240240384d00e06804a92", - "0x3839012a48049c40740613f0070740254900900e9fc039c4012a4804837", - "0x4a92012a0c0482c00ea1004a92012a100480c00e72004a920120e404a7b", - "0xc283508040049c8012a48049c80120b403818012a48048180120b803a83", - "0x3817012a480480750601c03a920120a80485200e01d4900900e060039c8", - "0x4a920121080b81850001c210095240242100950201c210095240240384d", - "0x48490129ec03849012a480484c0900613f0070900254900900e9fc0384c", - "0x482e00e0a404a920120a40482c00e05004a920120500480c00e13404a92", - "0x380700e1340c0290280400484d012a480484d0120b403818012a4804818", - "0x14900900e060038290280619600c0200614901801201c0c00900e01d49009", - "0xc02801205003810012a480481001203003828012a480482a0120a803807", - "0x14300700ea4804827012a1c038075240240381800e09404b2d04c09c0c292", - "0x4a8100e08004a9201201d4100703c0254900900ea0c0380752402413009", - "0x381d012a48048074fe01c0f8095240241001e030a0003820012a4804820", - "0x149009020024060070f0025490090c00253d8070c00254900903e0740c27e", - "0x3c00905a01c0c0095240240c00905c01c060095240240600905801c08009", - "0x14900904a0254380700ea480480703001c3c018018040080090f002549009", - "0x14380c0200a81980750e0254900950e024d700750e0254900900e17c03807", - "0x1410095240240387a00e01d4900900e06003a835080619728550c06149018", - "0x1490090300241700750a0254900950a0241600750c0254900950c02406007", - "0x1490184fc025150074fc9fd40281020a4804a82030a154301013601c0c009", - "0x480750601c03a920129ec04a2900e01d4900900e0600382c012cbd3d809", - "0x481700e01d4900905a024e40070be0b40c2920120b80483900e0b804a92", - "0x3832012a480483301213003833012a48049ae012108039ae012a480485f", - "0x4a920129fc0482e00ea0004a92012a000482c00ea0404a92012a040480c", - "0x38075240240381800e0c93fa8050204004832012a48048320120b403a7f", - "0x4a92012a000482c00ea0404a92012a040480c00e6e004a920120b004a7b", - "0x13fa80502040049b8012a48049b80120b403a7f012a4804a7f0120b803a80", - "0x3837012a480480709a01c0d00952402403a8300e01d4900900e060039b8", - "0x4a9201201d3f8073880254900906e0680c28000e0dc04a920120dc04a81", - "0x14200901801ce40095240241c8094f601c1c809524024e203a0309f80383a", - "0x168070300254900903002417007506025490095060241600750802549009", - "0x150090a401c03a9201201c0c00739006141a84020024e4009524024e4009", - "0x4842012a0403842012a480480709a01c0b80952402403a8300e01d49009", - "0xc27e00e12004a9201201d3f8070980254900908405c0c28000e10804a92", - "0xa0095240240a00901801c26809524024248094f601c2480952402426048", - "0x14900909a0241680703002549009030024170070520254900905202416007", - "0xc2920300600381801201c03a9201201c0380709a0601481402002426809", - "0x600704e025490090200241500700ea480480703001c14029030cc00a00c", - "0x480703001c0f009662094130185240601380902801c0600952402406009", - "0x4a9201201d4180700ea4804825012a18038075240241300950e01c03a92", - "0x481f0400614000703e0254900903e0254080703e0254900900ea0803820", - "0x4a7b00e1e004a92012074300184fc01c3000952402403a7f00e07404a92", - "0x3809012a48048090122740380c012a480480c01203003a87012a4804878", - "0x4a92012a1c0482d00e0a804a920120a80482e00e05004a920120500482c", - "0x38075240240f00950e01c03a9201201c0c00750e0a80a00901803004a87", - "0x14901850c0500602a06601d430095240254300935c01d430095240240385f", - "0x60075020254900900e1e8038075240240381800ea0941818664a1142818", - "0x48095240240480913a01d420095240254200905801d4280952402542809", - "0x13f27f500031490095020a804a8450a0304e0070540254900905402417007", - "0x4a2900e01d4900900e0600382d012ccc170095240601600945401c1627b", - "0xe40070666b80c29201217c0483900e17c04a9201201d4180700ea480482e", - "0x39b8012a480483201210803832012a480483301205c03807524024d7009", - "0x4a920129f80489d00ea0004a92012a000480c00e06804a920126e00484c", - "0x481a0120b403a7b012a4804a7b0120b803a7f012a4804a7f0120b003a7e", - "0x14900905a0253d80700ea480480703001c0d27b4fe9f94000c01206804a92", - "0x13f80905801d3f0095240253f00913a01d400095240254000901801c1b809", - "0x600906e0254900906e024168074f6025490094f6024170074fe02549009", - "0x480709a01ce200952402403a8300e01d4900900e060038374f69fd3f280", - "0x13f807072025490090747100c28000e0e804a920120e804a8100e0e804a92", - "0x210095240240b8094f601c0b8095240241c9c80309f8039c8012a4804807", - "0x14900950402416007012025490090120244e8075060254900950602406007", - "0x4a83018024210095240242100905a01c150095240241500905c01d41009", - "0x4a9201201d4180700ea4804810012148038075240240381800e10815282", - "0x48480980614000709002549009090025408070900254900900e1340384c", - "0x4a7b00e74404a92012124268184fc01c2680952402403a7f00e12404a92", - "0x3809012a480480901227403829012a480482901203003850012a48049d1", - "0x4a920121400482d00e0a804a920120a80482e00e0a004a920120a00482c", - "0xc2920300240381801201c03a9201201c038070a00a81400905203004850", - "0x6007050025490090540241500700ea480480703001c14814030cd006010", - "0x480703001c1280966a098138185240601400902801c0800952402408009", - "0x4a9201201d4180700ea4804826012a18038075240241380950e01c03a92", - "0x482003c0614000704002549009040025408070400254900900ea080381e", - "0x4a7b00e18004a9201207c0e8184fc01c0e80952402403a7f00e07c04a92", - "0x380c012a480480c0120b003810012a480481001203003878012a4804860", - "0x3878030030080100121e004a920121e00482d00e06004a920120600482e", - "0x49ae00ea1c04a9201201c2f80700ea4804825012a1c0380752402403818", - "0xc007506a100c33650aa180c292030a1c060100540cc03a87012a4804a87", - "0x482c00ea1804a92012a180480c00ea0804a9201201c3d00700ea4804807", - "0x14900950406142a8602026803818012a48048180120b803a85012a4804a85", - "0x3a9201201c0c0070580259ba7b012a480c27e0128a803a7e4fea0140810", - "0x168185240241700907201c1700952402403a8300e01d490094f602514807", - "0x14900935c0242100735c025490090be0240b80700ea480482d0127200385f", - "0x14000905801d408095240254080901801c190095240241980909801c19809", - "0x800906402549009064024168074fe025490094fe0241700750002549009", - "0x14080901801cdc009524024160094f601c03a9201201c0c0070649fd40281", - "0x168074fe025490094fe02417007500025490095000241600750202549009", - "0x480750601c03a9201201c0c0073709fd40281020024dc009524024dc009", - "0xd01850001c1b8095240241b80950201c1b8095240240384d00e06804a92", - "0x3839012a48049c40740613f0070740254900900e9fc039c4012a4804837", - "0x4a92012a0c0482c00ea1004a92012a100480c00e72004a920120e404a7b", - "0xc283508040049c8012a48049c80120b403818012a48048180120b803a83", - "0x3817012a480480750601c03a920120a80485200e01d4900900e060039c8", - "0x4a920121080b81850001c210095240242100950201c210095240240384d", - "0x48490129ec03849012a480484c0900613f0070900254900900e9fc0384c", - "0x482e00e0a404a920120a40482c00e05004a920120500480c00e13404a92", - "0x380700e1340c0290280400484d012a480484d0120b403818012a4804818", - "0x14900900e060038290280619c00c0200614901801201c0c00900e01d49009", - "0x4a920120400480c00e01d4900900e04003828012a480482a0120a803807", - "0x482900e01d4900900e06003825012ce413027030a480c02801205003810", - "0x381f012a480482001209c03820012a480481e0120a00381e012a4804826", - "0x38076740240381e00e18004a9201207c0482500e07404a9201209c04826", - "0x1300750e025490090f00240f8070f00254900900e0800380752402403818", - "0x1430095240603000903a01c300095240254380904a01c0e80952402412809", - "0x3a82012cf141a84030a480c01d012050038075240240381800ea1404b3b", - "0x3a80012a4804a810120a003a81012a4804a830120a40380752402403818", - "0x4a920129fc0482500e9f804a92012a100482600e9fc04a92012a0004827", - "0xf8070580254900900e080038075240240381800e01d9e80900e07803a7b", - "0x13d8095240241700904a01d3f0095240254100904c01c1700952402416009", - "0xc27e012050038075240240381800e17c04b3e05a025490184f60240e807", - "0x4a8700e01d4900900e1e0038075240240381800e0c804b3f0666b80c292", - "0x1680950801c03a92012a1804a8400e01d490090660254300700ea48049ae", - "0x481a012a040381a012a480480750401cdc00952402403a8300e01d49009", - "0xc27e00e71004a9201201d3f80706e025490090346e00c28000e06804a92", - "0x80095240240800901801c1c8095240241d0094f601c1d0095240241b9c4", - "0x1490090720241680703002549009030024170070180254900901802416007", - "0x38075240241900950e01c03a9201201c0c007072060060100200241c809", - "0x1490183900300802a06601ce4009524024e400935c01ce40095240240385f", - "0xc22800e01d4900900e1e0038075240240381800e120260186801080b818", - "0xb8095240240b80901801c248095240242480950201c2480952402416a86", - "0x4a9201201d4180700ea480480703001c2680968201d4901809202519807", - "0x48503a2061400070a0025490090a0025408070a00254900900e89c039d1", - "0x481700e01d490090a4024e40070a81480c2920121440483900e14404a92", - "0x3859012a480481b0121300381b012a48049f4012108039f4012a4804854", - "0x4a920120600482e00e10804a920121080482c00e05c04a9201205c0480c", - "0x38075240240381800e1640c04202e04004859012a48048590120b403818", - "0x1408070ac0254900900e28c03a06012a480480750601c03a9201213404a30", - "0x2f00952402403a7f00e15404a920121590301850001c2b0095240242b009", - "0x481701203003a64012a48048570129ec03857012a48048550bc0613f007", - "0x482d00e06004a920120600482e00e10804a920121080482c00e05c04a92", - "0x14900900e1e0038075240240381800e9900c04202e04004a64012a4804a64", - "0x13a80952402403a8300e01d4900905a0254200700ea4804a86012a1003807", - "0x1490094e89d40c28000e9d004a920129d004a8100e9d004a9201201c26807", - "0x1380094f601d38009524025392710309f803a71012a48048074fe01d39009", - "0x17007090025490090900241600709802549009098024060074de02549009", - "0xc0074de0602404c020025378095240253780905a01c0c0095240240c009", - "0x4a86012a10038075240242f8093a201c03a9201201c3c00700ea4804807", - "0x4a9201201c280074d60254900900ea0c038075240253f00950e01c03a92", - "0x48074fe01d350095240243726b030a000386e012a480486e012a040386e", - "0x60074d0025490090d60253d8070d6025490094d49a40c27e00e9a404a92", - "0xc0095240240c00905c01c060095240240600905801c0800952402408009", - "0x3c00700ea480480703001d34018018040080094d0025490094d002416807", - "0x480750601c03a9201207404a8700e01d4900950a024e880700ea4804807", - "0x13381850001c340095240243400950201c340095240240385100e99c04a92", - "0x3862012a4804a664ca0613f0074ca0254900900e9fc03a66012a4804868", - "0x4a920120300482c00e04004a920120400480c00e1bc04a9201218804a7b", - "0xc00c0200400486f012a480486f0120b403818012a48048180120b80380c", - "0x3a93012a480480750601c03a920120a80485200e01d4900900e0600386f", - "0x4a920129854981850001d308095240253080950201d308095240240384d", - "0x4a5e0129ec03a5e012a4804a604be0613f0074be0254900900e9fc03a60", - "0x482e00e0a404a920120a40482c00e05004a920120500480c00e97404a92", - "0x380700e9740c02902804004a5d012a4804a5d0120b403818012a4804818", - "0x14900900e06003829028061a100c0200614901801201c0c00900e01d49009", - "0x4a920120400480c00e01d4900900e04003828012a480482a0120a803807", - "0x485700e01d4900900e06003825012d0c13027030a480c02801205003810", - "0x381f012a480481e01299003820012a48048270120980381e012a4804826", - "0xe8094ea01c0e8095240240382000e01d4900900e060038076880240381e", - "0x13a00703e025490090c0025320070400254900904a024130070c002549009", - "0x38075240240387800e01d4900900e06003a87012d143c0095240600f809", - "0x1420095240241000902e01d4280952402403a8300ea1804a920121e004829", - "0x1490090180241600702002549009020024060075060254900950c02414007", - "0x14180950201d428095240254280909001d42009524025420094e401c06009", - "0x1400094e001d402815040a949009506a154200c0200313880750602549009", - "0x1627b030a4804a7f0129bc038075240240381800e9f804b464fe02549018", - "0x1490095020241600705a025490095040240600705c025490094f602415007", - "0x480703c01c19809524024160094d601cd70095240241700904c01c2f809", - "0x14900950402406007064025490094fc0253d80700ea480480703001c03b47", - "0x1900905a01c0c0095240240c00905c01d408095240254080905801d41009", - "0x3a9201201c3c00700ea480480703001c19018502a080800906402549009", - "0xd009524024dc0094d401cdc0095240240382000e01d4900950e024e8807", - "0x149009040024130070be025490090180241600705a0254900902002406007", - "0x39c4012d201b809524060198094d201c198095240240d0094d601cd7009", - "0x14900900e060039c8012d241c83a030a480c1ae0120500380752402403818", - "0x3a920120dc049c800e01d490090720254300700ea480483a012a1c03807", - "0x210095240242100950201c2100952402403a8200e05c04a9201201d41807", - "0x484c0900613f0070900254900900e9fc0384c012a480484202e06140007", - "0x482c00e0b404a920120b40480c00e13404a9201212404a7b00e12404a92", - "0x484d012a480484d0120b403818012a48048180120b80385f012a480485f", - "0x48070be01c03a9201272004a8700e01d4900900e0600384d03017c16810", - "0x28850030a480c1d10be0b41503300e74404a92012744049ae00e74404a92", - "0x4850012030039f4012a48048070f401c03a9201201c0c0070a81480c34a", - "0x484800e06004a920120600482e00e14404a920121440482c00e14004a92", - "0x520070ac8182c81b020a48048373e80602885001829403837012a4804837", - "0x2b80952402403a8300e01d4900900e0600385e012d2c2a8095240602b009", - "0x4a750ae0614000700ea4804a640121f403a754c8061490090aa02451007", - "0x481700e01d490094e4024e40074e29c80c2920129d00483900e9d004a92", - "0x3a6b012a4804a6f01213003a6f012a4804a7001210803a70012a4804a71", - "0x4a920128180482e00e16404a920121640482c00e06c04a9201206c0480c", - "0x38075240240381800e9ad0305903604004a6b012a4804a6b0120b403a06", - "0x4a920121640482c00e06c04a9201206c0480c00e1b804a9201217804a7b", - "0x1030590360400486e012a480486e0120b403a06012a4804a060120b803859", - "0x3a6a012a480480750601c03a920120dc049c800e01d4900900e0600386e", - "0x4a920129a53501850001d348095240253480950201d348095240240384d", - "0x4a670129ec03a67012a480486b4d00613f0074d00254900900e9fc0386b", - "0x482e00e15004a920121500482c00e14804a920121480480c00e1a004a92", - "0x381800e1a00c0540a404004868012a48048680120b403818012a4804818", - "0x14900900ea0c03807524024d700950e01c03a92012710049d100e01d49009", - "0x132a66030a0003a65012a4804a65012a0403a65012a48048070a201d33009", - "0x13d807526025490090c41bc0c27e00e1bc04a9201201d3f8070c402549009", - "0x2f8095240242f80905801c168095240241680901801d3080952402549809", - "0x1308180be0b4080094c2025490094c2024168070300254900903002417007", - "0x268074c00254900900ea0c03807524024150090a401c03a9201201c0c007", - "0x12f0095240252fa60030a0003a5f012a4804a5f012a0403a5f012a4804807", - "0x1490094b80253d8074b8025490094bc9740c27e00e97404a9201201d3f807", - "0xc00905c01c148095240241480905801c0a0095240240a00901801d2d809", - "0x480700e01d2d818052050080094b6025490094b60241680703002549009", - "0x3a9201201c0c0070520500c34c0180400c2920300240381801201c03a92", - "0x1490180500240a00702002549009020024060070500254900905402415007", - "0x4a8600e01d4900904e0254380700ea480480703001c1280969a09813818", - "0x1000950201c1000952402403a8200e07804a9201201d4180700ea4804826", - "0x13f00703a0254900900e9fc0381f012a480482003c0614000704002549009", - "0x4a920120400480c00e1e004a9201218004a7b00e18004a9201207c0e818", - "0x48780120b403818012a48048180120b80380c012a480480c0120b003810", - "0x3a9201209404a8700e01d4900900e06003878030030080100121e004a92", - "0xc2870180401503300ea1c04a92012a1c049ae00ea1c04a9201201c2f807", - "0x3a82012a480480750601c03a9201201c0c007506a100c34e50aa180c292", - "0x4a92012a054101850001d408095240254080950201d4080952402403a26", - "0x4a7e0129ec03a7e012a4804a804fe0613f0074fe0254900900e9fc03a80", - "0x482e00ea1404a92012a140482c00ea1804a92012a180480c00e9ec04a92", - "0x381800e9ec0c28550c04004a7b012a4804a7b0120b403818012a4804818", - "0x482e012a040382e012a480480709a01c1600952402403a8300e01d49009", - "0xc27e00e17c04a9201201d3f80705a0254900905c0b00c28000e0b804a92", - "0x1420095240254200901801c19809524024d70094f601cd70095240241685f", - "0x1490090660241680703002549009030024170075060254900950602416007", - "0x3807524024150090a401c03a9201201c0c00706606141a8402002419809", - "0x39b8012a48049b8012a04039b8012a480480709a01c1900952402403a83", - "0x1490090340dc0c27e00e0dc04a9201201d3f807034025490093700c80c280", - "0x1480905801c0a0095240240a00901801c1d009524024e20094f601ce2009", - "0x80090740254900907402416807030025490090300241700705202549009", - "0xc34f0180400c2920300240381801201c03a9201201c0380707406014814", - "0x3a9201201c08007050025490090540241500700ea480480703001c14814", - "0xc00704a025a802604e061490180500240a0070200254900902002406007", - "0x138070400254900903c0241400703c0254900904c0241480700ea4804807", - "0x300095240240f80904a01c0e8095240241380904c01c0f80952402410009", - "0x481f00e1e004a9201201c1000700ea480480703001c03b5101201c0f007", - "0x3860012a4804a870120940381d012a480482501209803a87012a4804878", - "0x14901803a0240a00700ea480480703001d428096a4a1804a920301800481d", - "0x14200950e01c03a9201201c3c00700ea480480703001d410096a6a0d42018", - "0x14900900ea0c038075240254300950801c03a92012a0c04a8600e01d49009", - "0x140281030a0003a80012a4804a80012a0403a80012a480480750401d40809", - "0x13d8074f6025490094fe9f80c27e00e9f804a9201201d3f8074fe02549009", - "0x60095240240600905801c080095240240800901801c160095240253d809", - "0x160180180400800905802549009058024168070300254900903002417007", - "0x385f00e01d490095040254380700ea48048070f001c03a9201201c0c007", - "0x168185240601700c0200a81980705c0254900905c024d700705c02549009", - "0x1680901801c190095240240387a00e01d4900900e0600383335c061aa05f", - "0x11280750c0254900950c025408070be025490090be0241600705a02549009", - "0x1d0096aa71004a920300dc04a2a00e0dc0d1b8054a4804a8606417c16810", - "0x1c8070720254900900ea0c03807524024e200945201c03a9201201c0c007", - "0x210095240240b80902e01c03a92012720049c800e05ce40185240241c809", - "0x1490093700240600709002549009098024260070980254900908402421007", - "0x2400905a01c0c0095240240c00905c01c0d0095240240d00905801cdc009", - "0x1490090740253d80700ea480480703001c240180346e00800909002549009", - "0xc00905c01c0d0095240240d00905801cdc009524024dc00901801c24809", - "0x480703001c248180346e008009092025490090920241680703002549009", - "0x4a9201201c2680709a0254900900ea0c038075240254300950801c03a92", - "0x48074fe01c28009524024e884d030a00039d1012a48049d1012a04039d1", - "0x60070a8025490090a40253d8070a4025490090a01440c27e00e14404a92", - "0xc0095240240c00905c01c198095240241980905801cd7009524024d7009", - "0x3c00700ea480480703001c2a0180666b8080090a8025490090a802416807", - "0x480750601c03a9201207404a8700e01d4900950a024e880700ea4804807", - "0xfa01850001c0d8095240240d80950201c0d8095240240385100e7d004a92", - "0x3856012a480485940c0613f00740c0254900900e9fc03859012a480481b", - "0x4a920120300482c00e04004a920120400480c00e15404a9201215804a7b", - "0xc00c02004004855012a48048550120b403818012a48048180120b80380c", - "0x385e012a480480750601c03a920120a80485200e01d4900900e06003855", - "0x4a9201215c2f01850001c2b8095240242b80950201c2b8095240240384d", - "0x4a740129ec03a74012a4804a644ea0613f0074ea0254900900e9fc03a64", - "0x482e00e0a404a920120a40482c00e05004a920120500480c00e9c804a92", - "0x380700e9c80c02902804004a72012a4804a720120b403818012a4804818", - "0x14900900e06003829028061ab00c0200614901801201c0c00900e01d49009", - "0x4a920120400480c00e01d4900900e04003828012a480482a0120a803807", - "0x482900e01d4900900e06003825012d5c13027030a480c02801205003810", - "0x381f012a480482001209c03820012a480481e0120a00381e012a4804826", - "0x38076b00240381e00e18004a9201207c0482500e07404a9201209c04826", - "0x1300750e025490090f00240f8070f00254900900e0800380752402403818", - "0x1430095240603000903a01c300095240254380904a01c0e80952402412809", - "0x3a82012d6941a84030a480c01d012050038075240240381800ea1404b59", - "0x14180950c01c03a92012a1004a8700e01d4900900e1e00380752402403818", - "0x14900900ea0803a81012a480480750601c03a92012a1804a8400e01d49009", - "0x3a7f00e9fc04a92012a014081850001d400095240254000950201d40009", - "0x382c012a4804a7b0129ec03a7b012a4804a7f4fc0613f0074fc02549009", - "0x4a920120600482e00e03004a920120300482c00e04004a920120400480c", - "0x38075240240381800e0b00c00c0200400482c012a480482c0120b403818", - "0x49ae00e0b804a9201201c2f80700ea4804a82012a1c0380752402403878", - "0xc0070666b80c35b0be0b40c2920300b8060100540cc0382e012a480482e", - "0x482c00e0b404a920120b40480c00e0c804a9201201c3d00700ea4804807", - "0x14900950c0c82f82d0202ac03a86012a4804a86012a040385f012a480485f", - "0x38075240240381800e0e804b5c3880254901806e0251500706e068dc02a", - "0xb9c8030a48048390120e403839012a480480750601c03a9201271004a29", - "0x4a920121080484200e10804a9201205c0481700e01d49009390024e4007", - "0x481a0120b0039b8012a48049b801203003848012a480484c0121300384c", - "0xdc01001212004a920121200482d00e06004a920120600482e00e06804a92", - "0x49b801203003849012a480483a0129ec038075240240381800e1200c01a", - "0x482d00e06004a920120600482e00e06804a920120680482c00e6e004a92", - "0x4a86012a10038075240240381800e1240c01a37004004849012a4804849", - "0x1490093a2025408073a20254900900e1340384d012a480480750601c03a92", - "0x288184fc01c2880952402403a7f00e14004a920127442681850001ce8809", - "0x39ae012a48049ae01203003854012a48048520129ec03852012a4804850", - "0x4a920121500482d00e06004a920120600482e00e0cc04a920120cc0482c", - "0x49d100e01d4900900e1e0038075240240381800e1500c03335c04004854", - "0x48070a201cfa00952402403a8300e01d4900903a0254380700ea4804a85", - "0x13f8070b2025490090367d00c28000e06c04a9201206c04a8100e06c04a92", - "0x2a8095240242b0094f601c2b0095240242ca060309f803a06012a4804807", - "0x1490090300241700701802549009018024160070200254900902002406007", - "0x3a9201201c0c0070aa060060100200242a8095240242a80905a01c0c009", - "0x3857012a480480709a01c2f00952402403a8300e01d4900905402429007", - "0x4a9201201d3f8074c8025490090ae1780c28000e15c04a9201215c04a81", - "0xa00901801d390095240253a0094f601d3a009524025322750309f803a75", - "0x168070300254900903002417007052025490090520241600702802549009", - "0x381801201c03a9201201c038074e4060148140200253900952402539009", - "0x1490090540241500700ea480480703001c14814030d7406010030a480c009", - "0x1490180500240a007020025490090200240600700ea480480702001c14009", - "0x1400703c0254900904c0241480700ea480480703001c128096bc09813818", - "0xe8095240241380904c01c0f8095240241000904e01c100095240240f009", - "0x1000700ea480480703001c03b5f01201c0f0070c00254900903e02412807", - "0x381d012a480482501209803a87012a480487801207c03878012a4804807", - "0x480703001d428096c0a1804a920301800481d00e18004a92012a1c04825", - "0x38075240240381800ea0804b61506a100c292030a18080180bc01c03a92", - "0x381800e9fc04b62500a040c2920300740481400ea1004a92012a100480c", - "0x482700e9ec04a920129f80482800e9f804a92012a000482900e01d49009", - "0x382d012a480482c0120940382e012a4804a810120980382c012a4804a7b", - "0x2f80903e01c2f8095240240382000e01d4900900e060038076c60240381e", - "0xe80705a0254900935c0241280705c025490094fe0241300735c02549009", - "0xc2920300b80481400e01d4900900e06003832012d901980952406016809", - "0x482800e71004a920120680482900e01d4900900e06003837012d940d1b8", - "0x39c8012a48049b801209803839012a480483a01209c0383a012a48049c4", - "0x382000e01d4900900e060038076cc0240381e00e05c04a920120e404825", - "0x128073900254900906e02413007098025490090840240f80708402549009", - "0x14900900e06003849012d9c240095240600b80903a01c0b80952402426009", - "0x387800e01d4900900e06003850012da0e884d030a480c1c801205003807", - "0x4848012a1003807524024e880950c01c03a9201213404a8700e01d49009", - "0x4a9201201d4180700ea4804833012a1003807524025418090dc01c03a92", - "0x48520a2061400070a4025490090a4025408070a40254900900ea0803851", - "0x4a7b00e06c04a92012150fa0184fc01cfa00952402403a7f00e15004a92", - "0x380c012a480480c0120b003a84012a4804a8401203003859012a480481b", - "0x38590300314201001216404a920121640482d00e06004a920120600482e", - "0x49ae00e81804a9201201c2f80700ea4804850012a1c0380752402403818", - "0xc0070ae1780c3690aa1580c292030818062840540cc03a06012a4804a06", - "0x3856012a480485601203003a64090061490090900245680700ea4804807", - "0x3a920120cc04a8400e01d4900900e06003a75012da803a9203099004a33", - "0x13a0095240242a80905801c03a9201212004a8400e01d4900950602437007", - "0x11800700ea480480703001c03b6b01201c0f0074e40254900903002417007", - "0x3a7050606149009506024560074e20254900900ea0c038075240253a809", - "0x149009066024568074d6025490094de9c40c28000e9bc04a920129c0048aa", - "0xc22800e9a404a9201201c0d8074d4025490090dc9ac0c28000e1b819818", - "0x4a920121ad3501850001c358095240243580950201c3580952402534848", - "0x486801205c038075240253380939001c34267030a4804a680120e403a68", - "0x1529203099819a830301540606b00e99804a9201299804a7200e99804a92", - "0x3807524024378090a401c03a9201201c0c0074c09854982a6d81bc31265", - "0x38075240240387800e9c804a920121880482e00e9d004a920129940482c", - "0x3a92012978049c800e9752f0185240252f80907201d2f80952402403a83", - "0x1490094b6024260074b6025490094b8024210074b8025490094ba0240b807", - "0x13900905c01d3a0095240253a00905801c2b0095240242b00901801d2d009", - "0x480703001d2d2724e8158080094b4025490094b4024168074e402549009", - "0x1490094c09640c27e00e96404a9201201d3f80700ea48048070f001c03a92", - "0x14980905801c2b0095240242b00901801d2b8095240252c0094f601d2c009", - "0x80094ae025490094ae024168074c2025490094c20241700752602549009", - "0x1490090900254200700ea48048070f001c03a9201201c0c0074ae98549856", - "0x12b00952402403a8300e01d490090660254200700ea4804a830121b803807", - "0x1490094aa9580c28000e95404a9201295404a8100e95404a9201201c26807", - "0x3b8094f601c3b809524025298610309f803861012a48048074fe01d29809", - "0x170070ae025490090ae024160070bc025490090bc024060070f402549009", - "0xc0070f40602b85e0200243d0095240243d00905a01c0c0095240240c009", - "0x49c8012a1c03807524024248093a201c03a9201201c3c00700ea4804807", - "0x4a9201201d4180700ea4804833012a1003807524025418090dc01c03a92", - "0x487d4a4061400070fa025490090fa025408070fa0254900900e9a003a52", - "0x4a7b00e94004a920129443d8184fc01c3d80952402403a7f00e94404a92", - "0x380c012a480480c0120b003a84012a4804a8401203003a4f012a4804a50", - "0x3a4f0300314201001293c04a9201293c0482d00e06004a920120600482e", - "0x1700950e01c03a920120c8049d100e01d4900900e1e00380752402403818", - "0x14900900e14003a4d012a480480750601c03a92012a0c0486e00e01d49009", - "0x3a7f00e91c04a920129152681850001d228095240252280950201d22809", - "0x3887012a4804a410129ec03a41012a4804a474840613f00748402549009", - "0x4a920120600482e00e03004a920120300482c00ea1004a92012a100480c", - "0x38075240240381800e21c0c00c50804004887012a48048870120b403818", - "0xc00700edb40480703c01d1f8095240254100901801c03a9201207404a87", - "0x800901801c03a9201207404a8700e01d4900950a024e880700ea4804807", - "0x14900900e14403a3d012a480480750601c03a9201201c3c00747e02549009", - "0x3a7f00e22c04a920128f11e81850001d1e0095240251e00950201d1e009", - "0x388c012a4804a380129ec03a38012a480488b4740613f00747402549009", - "0x4a920120600482e00e03004a920120300482c00e8fc04a920128fc0480c", - "0x38075240240381800e2300c00c47e0400488c012a480488c0120b403818", - "0x14080746e0254900900e13403890012a480480750601c03a920120a804852", - "0x11980952402403a7f00e8d004a920128dc4801850001d1b8095240251b809", - "0x481401203003a31012a4804a320129ec03a32012a4804a344660613f007", - "0x482d00e06004a920120600482e00e0a404a920120a40482c00e05004a92", - "0xc009030024038075240240380700e8c40c02902804004a31012a4804a31", - "0x4a920120400482a00e01d4900900e06003828052061b701401806149018", - "0xc29203009c0481400e03004a920120300480c00e01d4900900e04003827", - "0x482800e08004a920120940482900e01d4900900e0600381e012dbc12826", - "0x3860012a48048260120980381d012a480481f01209c0381f012a4804820", - "0x382000e01d4900900e060038076e00240381e00e1e004a9201207404825", - "0x128070c00254900903c0241300750c0254900950e0240f80750e02549009", - "0x14900900e06003a84012dc5428095240603c00903a01c3c00952402543009", - "0x482900e01d4900900e06003a81012dc941283030a480c06001205003807", - "0x3a7e012a4804a7f01209c03a7f012a4804a800120a003a80012a4804a82", - "0x38076e60240381e00e0b004a920129f80482500e9ec04a92012a0c04826", - "0x1300705a0254900905c0240f80705c0254900900e0800380752402403818", - "0x2f8095240601600903a01c160095240241680904a01d3d80952402540809", - "0x39b8012dd419033030a480c27b012050038075240240381800e6b804b74", - "0x3837012a480481a0120a00381a012a48048320120a40380752402403818", - "0x4a920127100482500e0e804a920120cc0482600e71004a920120dc04827", - "0xf8073900254900900e080038075240240381800e01dbb00900e07803839", - "0x1c8095240240b80904a01c1d009524024dc00904c01c0b809524024e4009", - "0xc03a012050038075240240381800e13004b77084025490180720240e807", - "0x4a8700e01d4900900e1e0038075240240381800e13404b780921200c292", - "0x2f80950801c03a9201210804a8400e01d490090920254300700ea4804848", - "0x14900900ea08039d1012a480480750601c03a92012a1404a8400e01d49009", - "0x3a7f00e14404a92012140e881850001c280095240242800950201c28009", - "0x39f4012a48048540129ec03854012a48048510a40613f0070a402549009", - "0x4a920120500482c00e03004a920120300480c00e01c04a9201201c04a23", - "0xa00c00e030049f4012a48049f40120b40382a012a480482a0120b803814", - "0xd8095240240385f00e01d4900909a0254380700ea480480703001cfa02a", - "0x2b0186f28182c8185240600d8140180a81980703602549009036024d7007", - "0x60070bc0254900900e1e8038075240240387800e01d4900900e06003855", - "0x38095240240380944601d030095240250300905801c2c8095240242c809", - "0x1490090be0254080750a0254900950a025408070540254900905402417007", - "0x48420bea142f02a00e8182c82844401c210095240242100950201c2f809", - "0x480703001d380096f49c404a920309c804a2a00e9c93a2754c815c06292", - "0x1490094de0241c8074de0254900900ea0c038075240253880945201c03a92", - "0x13500908401d350095240243700902e01c03a920129ac049c800e1b935818", - "0x60074ea025490094ea025118070d6025490094d2024260074d202549009", - "0x13a0095240253a00905c01d320095240253200905801c2b8095240242b809", - "0x38075240240381800e1ad3a2640ae9d4060090d6025490090d602416807", - "0x4a9201215c0480c00e9d404a920129d404a2300e9a004a920129c004a7b", - "0x4a680120b403a74012a4804a740120b803a64012a4804a640120b003857", - "0x3a9201201c3c00700ea480480703001d342744c815d3a80c0129a004a92", - "0x38075240254280950801c03a9201217c04a8400e01d4900908402542007", - "0x3868012a4804868012a0403868012a480480709a01d3380952402403a83", - "0x1490094cc9940c27e00e99404a9201201d3f8074cc025490090d099c0c280", - "0x2b00901801c038095240240380944601c37809524024310094f601c31009", - "0x1680705402549009054024170070aa025490090aa024160070ac02549009", - "0x387800e01d4900900e0600386f0541542b0070180243780952402437809", - "0x485f012a10038075240241d00950e01c03a92012130049d100e01d49009", - "0x4a9201201d340075260254900900ea0c038075240254280950801c03a92", - "0x48074fe01d3000952402530a93030a0003a61012a4804a61012a0403a61", - "0x1118074ba025490094bc0253d8074bc025490094c097c0c27e00e97c04a92", - "0xa0095240240a00905801c060095240240600901801c0380952402403809", - "0x1501401801c060094ba025490094ba024168070540254900905402417007", - "0x14200700ea48049ae012744038075240240387800e01d4900900e06003a5d", - "0x385000e97004a9201201d4180700ea4804a7b012a1c0380752402542809", - "0x3a5a012a4804a5b4b8061400074b6025490094b6025408074b602549009", - "0x4a9201296004a7b00e96004a920129692c8184fc01d2c80952402403a7f", - "0x48140120b00380c012a480480c01203003807012a480480701288c03a57", - "0x380c01295c04a9201295c0482d00e0a804a920120a80482e00e05004a92", - "0x149009508024e880700ea48048070f001c03a9201201c0c0074ae0a80a00c", - "0x12a8095240240385100e95804a9201201d4180700ea4804860012a1c03807", - "0x14900900e9fc03a53012a4804a554ac061400074aa025490094aa02540807", - "0x4a2300e1e804a920121dc04a7b00e1dc04a9201294c308184fc01c30809", - "0x3814012a48048140120b00380c012a480480c01203003807012a4804807", - "0x3d02a0280300380c0121e804a920121e80482d00e0a804a920120a80482e", - "0x268074a40254900900ea0c03807524024080090a401c03a9201201c0c007", - "0x1288095240243ea52030a000387d012a480487d012a040387d012a4804807", - "0x1490094a00253d8074a0025490094a21ec0c27e00e1ec04a9201201d3f807", - "0x1400905801c148095240241480901801c038095240240380944601d27809", - "0x600949e0254900949e02416807054025490090540241700705002549009", - "0x1bd829028061490180540240c00900e01d4900900e01c03a4f0540a014807", - "0x480c0129c803814012a4804814012030038075240240381800e09c14018", - "0x100095240600f00916a01c0f02504c0a9490090180500c0b300e03004a92", - "0xc01d0120500381d012a48048250120a8038075240240381800e07c04b7c", - "0x14300700ea4804860012a1c038075240240381800ea1c04b7d0f01800c292", - "0x3a8200ea1804a9201201d4180700ea48048200122d0038075240243c009", - "0x3a84012a4804a8550c0614000750a0254900950a0254080750a02549009", - "0x4a92012a0804a7b00ea0804a92012a11418184fc01d4180952402403a7f", - "0x481801227403826012a480482601203003807012a480480701288c03a81", - "0x482d00e04004a920120400482e00e0a404a920120a40482c00e06004a92", - "0x4a8700e01d4900900e06003a810200a40c02600e05004a81012a4804a81", - "0x1503300ea0004a92012a00049ae00ea0004a9201201c2f80700ea4804a87", - "0x48070f401c03a9201201c0c0070589ec0c37e4fc9fc0c292030a0014826", - "0x489d00e9f804a920129f80482c00e9fc04a920129fc0480c00e0b804a92", - "0x3810012a48048100120b803807012a480480701288c03818012a4804818", - "0x2f82d028a480482005c040038184fc9fc14a2100e08004a92012080048b2", - "0x38075240240381800e0dc04b7f03402549018370025150073700c8199ae", - "0x1c83a030a48049c40120e4039c4012a480480750601c03a9201206804a29", - "0x4a920127200484200e72004a920120e40481700e01d49009074024e4007", - "0x482d01203003833012a480483301288c03842012a480481701213003817", - "0x482e00e17c04a9201217c0482c00e6b804a920126b80489d00e0b404a92", - "0x384206417cd702d06605004842012a48048420120b403832012a4804832", - "0x3833012a480483301288c0384c012a48048370129ec0380752402403818", - "0x4a9201217c0482c00e6b804a920126b80489d00e0b404a920120b40480c", - "0xd702d0660500484c012a480484c0120b403832012a48048320120b80385f", - "0x4a9201201d4180700ea48048200122d0038075240240381800e1301905f", - "0x48490900614000709202549009092025408070920254900900e13403848", - "0x4a7b00e14004a92012134e88184fc01ce880952402403a7f00e13404a92", - "0x3a7b012a4804a7b01203003807012a480480701288c03851012a4804850", - "0x4a920120400482e00e0b004a920120b00482c00e06004a920120600489d", - "0x14900900e060038510200b00c27b00e05004851012a48048510120b403810", - "0x2900952402403a8300e01d4900904a0242900700ea480481f01274403807", - "0x1490090a81480c28000e15004a9201215004a8100e15004a9201201c28807", - "0x2c8094f601c2c809524024fa01b0309f80381b012a48048074fe01cfa009", - "0x4e80704c0254900904c0240600700e0254900900e0251180740c02549009", - "0x80095240240800905c01c148095240241480905801c0c0095240240c009", - "0x3a9201201c0c00740c0401481804c01c0a00940c0254900940c02416807", - "0x3855012a480480709a01c2b00952402403a8300e01d4900901802429007", - "0x4a9201201d3f8070bc025490090aa1580c28000e15404a9201215404a81", - "0x380944601d3a809524025320094f601d320095240242f0570309f803857", - "0x16007030025490090300244e807050025490090500240600700e02549009", - "0x13a8095240253a80905a01c080095240240800905c01c1380952402413809", - "0xc2920300240381801201c03a9201201c038074ea0401381805001c0a009", - "0x8007050025490090540241500700ea480480703001c14814030e0006010", - "0x1c082604e061490180500240a007020025490090200240600700ea4804807", - "0x14900903c0241400703c0254900904c0241480700ea480480703001c12809", - "0xf80904a01c0e8095240241380904c01c0f8095240241000904e01c10009", - "0x4a9201201c1000700ea480480703001c03b8201201c0f0070c002549009", - "0x4a870120940381d012a480482501209803a87012a480487801207c03878", - "0x2f00700ea480480703001d42809706a1804a920301800481d00e18004a92", - "0x481d01205c038075240240381800ea0804b84506a100c292030a1808018", - "0xc0b300ea0404a92012a0404a7200ea1004a92012a100480c00ea0404a92", - "0x381800e0b004b854f6025490184fc0245a8074fc9fd4002a52402540a84", - "0x4b860be0b40c2920300b80481400e0b804a920129fc0482a00e01d49009", - "0x14300700ea480482d012a1c038075240240387800e01d4900900e060039ae", - "0x3a8300e01d490095060243700700ea4804a7b0122d0038075240242f809", - "0xc28000e0c804a920120c804a8100e0c804a9201201d4100706602549009", - "0x1b809524024dc01a0309f80381a012a48048074fe01cdc00952402419033", - "0x1490090180241600750002549009500024060073880254900906e0253d807", - "0x6280020024e2009524024e200905a01c0c0095240240c00905c01c06009", - "0x3807524024d700950e01c03a9201201c3c00700ea480480703001ce2018", - "0x1490180740314002a06601c1d0095240241d00935c01c1d0095240240385f", - "0x600070980254900900ea0c038075240240381800e1080b81870e7201c818", - "0x248185240242480917601c03a92012120048b400e124240185240253d809", - "0x49d10120a0038075240242800944001c281d1030a480484d0122e80384d", - "0x39f40a8061490090920245d0070a4025490090a21300c28000e14404a92", - "0x4a9201206c048c400e1640d818524024fa00918401c03a9201215004a84", - "0x2c80918801c2a8095240242b052030a0003856012a4804a0601287803a06", - "0x3a64012a48048570aa061400070ae025490090bc0250f0070bc02549009", - "0x3a920129d0049c800e9c93a0185240253200907201d3a80952402403a1d", - "0x1490094e2025390074ea025490094ea025408074e2025490094e40240b807", - "0x13802a52406138a75506060e400c0d601c1c8095240241c80901801d38809", - "0x14180700ea4804a6b012148038075240240381800e9a53506e054e2135a6f", - "0x38075240253400939001d33a68030a480486b0120e40386b012a4804807", - "0x4a920129980484c00e99804a920121a00484200e1a004a9201299c04817", - "0x4a6f0120b803a70012a4804a700120b003839012a480483901203003a65", - "0x14900900e06003a654de9c01c81001299404a920129940482d00e9bc04a92", - "0x486f0129ec0386f012a4804a690c40613f0070c40254900900e9fc03807", - "0x482e00e1b804a920121b80482c00e0e404a920120e40480c00ea4c04a92", - "0x381800ea4d3506e07204004a93012a4804a930120b403a6a012a4804a6a", - "0x14900900ea0c03807524025418090dc01c03a920129ec048b400e01d49009", - "0x130261030a0003a60012a4804a60012a0403a60012a480480709a01d30809", - "0x13d8074ba025490094be9780c27e00e97804a9201201d3f8074be02549009", - "0x210095240242100905801c0b8095240240b80901801d2e0095240252e809", - "0x12e01808405c080094b8025490094b8024168070300254900903002417007", - "0x485200e01d49009058024e880700ea48048070f001c03a9201201c0c007", - "0x48070a001d2d80952402403a8300e01d490095060243700700ea4804a7f", - "0x13f8074b2025490094b496c0c28000e96804a9201296804a8100e96804a92", - "0x12b0095240252b8094f601d2b8095240252ca580309f803a58012a4804807", - "0x1490090300241700701802549009018024160075000254900950002406007", - "0x3a9201201c0c0074ac060062800200252b0095240252b00905a01c0c009", - "0x38077120240381e00e95404a92012a080480c00e01d4900903a02543807", - "0x480c00e01d4900903a0254380700ea4804a850127440380752402403818", - "0x48070a201d2980952402403a8300e01d4900900e1e003a55012a4804810", - "0x13f8070ee025490090c294c0c28000e18404a9201218404a8100e18404a92", - "0x3e809524025290094f601d290095240243b87a0309f80387a012a4804807", - "0x1490090300241700701802549009018024160074aa025490094aa02406007", - "0x3a9201201c0c0070fa060062550200243e8095240243e80905a01c0c009", - "0x387b012a480480709a01d2880952402403a8300e01d4900905402429007", - "0x4a9201201d3f8074a0025490090f69440c28000e1ec04a920121ec04a81", - "0xa00901801d22809524025268094f601d268095240252824f0309f803a4f", - "0x168070300254900903002417007052025490090520241600702802549009", - "0x381801201c03a9201201c0380748a060148140200252280952402522809", - "0x1490090200241500700ea480480703001c14029030e280a00c030a480c018", - "0xf009716094130185240601380902801c060095240240600901801c13809", - "0x14180700ea4804825012a18038075240241300950e01c03a9201201c0c007", - "0x14000703e0254900903e0254080703e0254900900ea0803820012a4804807", - "0x4a92012074300184fc01c3000952402403a7f00e07404a9201207c10018", - "0x48090128700380c012a480480c01203003a87012a48048780129ec03878", - "0x482d00e0a804a920120a80482e00e05004a920120500482c00e02404a92", - "0xf00950e01c03a9201201c0c00750e0a80a00901803004a87012a4804a87", - "0x602a06601d430095240254300935c01d430095240240385f00e01d49009", - "0x14900900e1e8038075240240381800ea0941818718a114281852406143014", - "0x14200905801c048095240240480943801d428095240254280901801d40809", - "0x1490095020a94200950a0310d807054025490090540241700750802549009", - "0x14900900e0600382d012e34170095240601600945401c1627b4fc9fd4000c", - "0xc29201217c0483900e17c04a9201201d4180700ea480482e0128a403807", - "0x483201210803832012a480483301205c03807524024d700939001c199ae", - "0x4a1c00ea0004a92012a000480c00e06804a920126e00484c00e6e004a92", - "0x3a7b012a4804a7b0120b803a7e012a4804a7e0120b003a7f012a4804a7f", - "0x13d80700ea480480703001c0d27b4fc9fd4000c01206804a920120680482d", - "0x13f8095240253f80943801d400095240254000901801c1b80952402416809", - "0x14900906e024168074f6025490094f6024170074fc025490094fc02416007", - "0xe200952402403a8300e01d4900900e060038374f69f93fa800180241b809", - "0x1490090747100c28000e0e804a920120e804a8100e0e804a9201201c26807", - "0xb8094f601c0b8095240241c9c80309f8039c8012a48048074fe01c1c809", - "0x16007012025490090120250e007506025490095060240600708402549009", - "0x210095240242100905a01c150095240241500905c01d4100952402541009", - "0x14180700ea4804810012148038075240240381800e10815282012a0c06009", - "0x14000709002549009090025408070900254900900e1340384c012a4804807", - "0x4a92012124268184fc01c2680952402403a7f00e12404a9201212026018", - "0x480901287003829012a480482901203003850012a48049d10129ec039d1", - "0x482d00e0a804a920120a80482e00e0a004a920120a00482c00e02404a92", - "0x481801201c03a9201201c038070a00a81400905203004850012a4804850", - "0x1490090200241500700ea480480703001c14029030e380a00c030a480c018", - "0x14901804e0240a007018025490090180240600700ea480480702001c13809", - "0x140070400254900904a0241480700ea480480703001c0f00971e09413018", - "0x300095240241300904c01c0e8095240240f80904e01c0f80952402410009", - "0x1000700ea480480703001c03b9001201c0f0070f00254900903a02412807", - "0x3860012a480481e01209803a86012a4804a8701207c03a87012a4804807", - "0x480703001d42009722a1404a920301e00481d00e1e004a92012a1804825", - "0x3c00700ea480480703001d40809724a09418185240603000902801c03a92", - "0x14280950801c03a92012a0804a8600e01d490095060254380700ea4804807", - "0x4a7f012a0403a7f012a480480750401d4000952402403a8300e01d49009", - "0xc27e00e9ec04a9201201d3f8074fc025490094fea000c28000e9fc04a92", - "0x38095240240380944601c17009524024160094f601c160095240253f27b", - "0x1490090540241700702802549009028024160070180254900901802406007", - "0x14900900e0600382e05405006007018024170095240241700905a01c15009", - "0x382d012a48048070be01c03a92012a0404a8700e01d4900900e1e003807", - "0x19033030e4cd705f030a480c02d0280301503300e0b404a920120b4049ae", - "0x385f012a480485f012030039b8012a48048070f401c03a9201201c0c007", - "0x4a920120a80482e00e01c04a9201201c04a2300e6b804a920126b80482c", - "0xd00c524025429b805401cd705f02831c03a85012a4804a85012a040382a", - "0x38075240240381800e05c04b9439002549018072025150070720e8e2037", - "0x2404c030a48048420120e403842012a480480750601c03a9201272004a29", - "0x4a920121240484200e12404a920121200481700e01d49009098024e4007", - "0x481a012030039c4012a48049c401288c039d1012a480484d0121300384d", - "0x482d00e0e804a920120e80482e00e0dc04a920120dc0482c00e06804a92", - "0xb8094f601c03a9201201c0c0073a20e81b81a388030049d1012a48049d1", - "0x16007034025490090340240600738802549009388025118070a002549009", - "0x280095240242800905a01c1d0095240241d00905c01c1b8095240241b809", - "0x14180700ea4804a85012a10038075240240381800e1401d03703471006009", - "0x1400070a4025490090a4025408070a40254900900e13403851012a4804807", - "0x4a92012150fa0184fc01cfa00952402403a7f00e15004a9201214828818", - "0x483301203003807012a480480701288c03859012a480481b0129ec0381b", - "0x482d00e0a804a920120a80482e00e0c804a920120c80482c00e0cc04a92", - "0x48070f001c03a9201201c0c0070b20a81903300e03004859012a4804859", - "0x4a9201201d4180700ea4804860012a1c03807524025420093a201c03a92", - "0x485640c061400070ac025490090ac025408070ac0254900900e14403a06", - "0x4a7b00e15c04a920121542f0184fc01c2f00952402403a7f00e15404a92", - "0x380c012a480480c01203003807012a480480701288c03a64012a4804857", - "0x4a920129900482d00e0a804a920120a80482e00e05004a920120500482c", - "0x3807524024080090a401c03a9201201c0c0074c80a80a00c00e03004a64", - "0x3a74012a4804a74012a0403a74012a480480709a01d3a80952402403a83", - "0x1490094e49c40c27e00e9c404a9201201d3f8074e4025490094e89d40c280", - "0x1480901801c038095240240380944601d37809524025380094f601d38009", - "0x168070540254900905402417007050025490090500241600705202549009", - "0xc00900e01d4900900e01c03a6f0540a0148070180253780952402537809", - "0x482a0120a8038075240240381800e0a40a01872a0300801852406004807", - "0xc02801205003810012a4804810012030038075240240381000e0a004a92", - "0x381e012a48048260120a4038075240240381800e09404b9604c09c0c292", - "0x4a9201209c0482600e07c04a920120800482700e08004a9201207804828", - "0x38075240240381800e01dcb80900e07803860012a480481f0120940381d", - "0xe8095240241280904c01d438095240243c00903e01c3c00952402403820", - "0x381800ea1404b9850c025490180c00240e8070c00254900950e02412807", - "0x38075240240381800ea0804b99506a100c2920300740481400e01d49009", - "0x4a8400e01d490095060254300700ea4804a84012a1c0380752402403878", - "0x14000950201d4000952402403a8200ea0404a9201201d4180700ea4804a86", - "0x13f0074fc0254900900e9fc03a7f012a4804a805020614000750002549009", - "0x4a920120400480c00e0b004a920129ec04a7b00e9ec04a920129fd3f018", - "0x482c0120b403818012a48048180120b80380c012a480480c0120b003810", - "0x38075240240387800e01d4900900e0600382c030030080100120b004a92", - "0x382e012a480482e0126b80382e012a48048070be01c03a92012a0804a87", - "0x14180700ea480480703001c199ae030e682f82d030a480c02e01804015033", - "0x14000737002549009370025408073700254900900e32403832012a4804807", - "0x1b8095240241b80950201c1b809524024038c800e06804a920126e019018", - "0x1d00939001c1c83a030a48049c40120e4039c4012a480483703406140007", - "0x480c00e72004a9201272004a7200e72004a920120e40481700e01d49009", - "0x248480980a9cd84202e06149018390a180c05f0208e80382d012a480482d", - "0x281d1030a480484d0120e40384d012a480480750601c03a9201201c0c007", - "0x4a920121440484200e14404a920121400481700e01d490093a2024e4007", - "0x48170120b00382d012a480482d01203003854012a480485201213003852", - "0x1681001215004a920121500482d00e10804a920121080482e00e05c04a92", - "0x48493e80613f0073e80254900900e9fc038075240240381800e15021017", - "0x482c00e0b404a920120b40480c00e16404a9201206c04a7b00e06c04a92", - "0x4859012a48048590120b403848012a48048480120b80384c012a480484c", - "0x480750601c03a92012a1804a8400e01d4900900e0600385909013016810", - "0x10301850001c2b0095240242b00950201c2b0095240240384d00e81804a92", - "0x3857012a48048550bc0613f0070bc0254900900e9fc03855012a4804856", - "0x4a920120cc0482c00e6b804a920126b80480c00e99004a9201215c04a7b", - "0xc03335c04004a64012a4804a640120b403818012a48048180120b803833", - "0x14380700ea4804a85012744038075240240387800e01d4900900e06003a64", - "0x4a8100e9d004a9201201c288074ea0254900900ea0c038075240240e809", - "0x3a71012a48048074fe01d390095240253a275030a0003a74012a4804a74", - "0x149009020024060074de025490094e00253d8074e0025490094e49c40c27e", - "0x13780905a01c0c0095240240c00905c01c060095240240600905801c08009", - "0x1490090540242900700ea480480703001d37818018040080094de02549009", - "0x4a920121b804a8100e1b804a9201201c268074d60254900900ea0c03807", - "0x1352690309f803a69012a48048074fe01d350095240243726b030a000386e", - "0x1600702802549009028024060074d0025490090d60253d8070d602549009", - "0x1340095240253400905a01c0c0095240240c00905c01c1480952402414809", - "0x6010030a480c00900e0600480700ea480480700e01d3401805205008009", - "0x480702001c140095240241500905401c03a9201201c0c0070520500c39c", - "0x1280973a098138185240601400902801c080095240240800901801c03a92", - "0x100095240240f00905001c0f0095240241300905201c03a9201201c0c007", - "0x14900903e0241280703a0254900904e0241300703e0254900904002413807", - "0x3878012a480480704001c03a9201201c0c00700ee780480703c01c30009", - "0x4a92012a1c0482500e07404a920120940482600ea1c04a920121e00481f", - "0x14300950801c03a9201201c0c00750a025cfa86012a480c06001207403860", - "0x38075240240381800ea0804ba0506a100c2920300740481400e01d49009", - "0x4a92012a000482700ea0004a92012a040482800ea0404a92012a0c04829", - "0x1d080900e07803a7b012a4804a7f01209403a7e012a4804a8401209803a7f", - "0x170095240241600903e01c160095240240382000e01d4900900e06003807", - "0x1490184f60240e8074f60254900905c024128074fc0254900950402413007", - "0x4ba30666b80c2920309f80481400e01d4900900e0600385f012e8816809", - "0x14300700ea48049ae012a1c038075240240387800e01d4900900e06003832", - "0x3a8200e6e004a9201201d4180700ea480482d012a100380752402419809", - "0x3837012a480481a37006140007034025490090340254080703402549009", - "0x4a920120e804a7b00e0e804a920120dce20184fc01ce200952402403a7f", - "0x48180120b80380c012a480480c0120b003810012a480481001203003839", - "0x14900900e06003839030030080100120e404a920120e40482d00e06004a92", - "0x39c8012a48048070be01c03a920120c804a8700e01d4900900e1e003807", - "0x2404c030e9021017030a480c1c80180401503300e72004a92012720049ae", - "0x2680952402416849030a0003849012a480480750601c03a9201201c0c007", - "0x1490090a00240b80700ea48049d1012720038503a20614900909a0241c807", - "0xb80901801c2a0095240242900909801c290095240242880908401c28809", - "0x168070300254900903002417007084025490090840241600702e02549009", - "0x1680950801c03a9201201c0c0070a8060210170200242a0095240242a009", - "0x481b012a040381b012a480480709a01cfa00952402403a8300e01d49009", - "0xc27e00e81804a9201201d3f8070b2025490090367d00c28000e06c04a92", - "0x260095240242600901801c2a8095240242b0094f601c2b0095240242ca06", - "0x1490090aa0241680703002549009030024170070900254900909002416007", - "0xe880700ea48048070f001c03a9201201c0c0070aa0602404c0200242a809", - "0x385000e17804a9201201d4180700ea4804a7e012a1c038075240242f809", - "0x3a64012a48048570bc061400070ae025490090ae025408070ae02549009", - "0x4a920129d004a7b00e9d004a920129913a8184fc01d3a80952402403a7f", - "0x48180120b80380c012a480480c0120b003810012a480481001203003a72", - "0x14900900e06003a72030030080100129c804a920129c80482d00e06004a92", - "0x38075240240e80950e01c03a92012a14049d100e01d4900900e1e003807", - "0x3a70012a4804a70012a0403a70012a48048070a201d3880952402403a83", - "0x1490094de9ac0c27e00e9ac04a9201201d3f8074de025490094e09c40c280", - "0x600905801c080095240240800901801d35009524024370094f601c37009", - "0x80094d4025490094d402416807030025490090300241700701802549009", - "0x14900900ea0c03807524024150090a401c03a9201201c0c0074d406006010", - "0x35a69030a000386b012a480486b012a040386b012a480480709a01d34809", - "0x13d8070d0025490094d099c0c27e00e99c04a9201201d3f8074d002549009", - "0x148095240241480905801c0a0095240240a00901801d3300952402434009", - "0x133018052050080094cc025490094cc024168070300254900903002417007", - "0xc0070520500c3a50180400c2920300240381801201c03a9201201c03807", - "0x800901801c03a9201201c08007050025490090540241500700ea4804807", - "0x3a9201201c0c00704a025d302604e061490180500240a00702002549009", - "0x149009040024138070400254900903c0241400703c0254900904c02414807", - "0x480703c01c300095240240f80904a01c0e8095240241380904c01c0f809", - "0x4a920121e00481f00e1e004a9201201c1000700ea480480703001c03ba7", - "0xc06001207403860012a4804a870120940381d012a480482501209803a87", - "0x481400e01d4900950c0254200700ea480480703001d42809750a1804a92", - "0x4a92012a0c0482900e01d4900900e06003a82012ea541a84030a480c01d", - "0x4a8401209803a7f012a4804a8001209c03a80012a4804a810120a003a81", - "0x14900900e060038077540240381e00e9ec04a920129fc0482500e9f804a92", - "0x1490095040241300705c025490090580240f8070580254900900e08003807", - "0x385f012eac168095240613d80903a01d3d8095240241700904a01d3f009", - "0x480703001c190097580ccd7018524060168100301800380752402403818", - "0x1b80975a068dc0185240613f00902801cd7009524024d700901801c03a92", - "0x1d009524024e200905001ce20095240240d00905201c03a9201201c0c007", - "0x1490090720241280739002549009370024130070720254900907402413807", - "0x3842012a480480704001c03a9201201c0c00700eeb80480703c01c0b809", - "0x4a920121300482500e72004a920120dc0482600e13004a920121080481f", - "0xe400902801c03a9201201c0c007092025d7848012a480c01701207403817", - "0x14380700ea48048070f001c03a9201201c0c0070a0025d81d109a06149018", - "0x4a8500e01d490090900254200700ea48049d1012a180380752402426809", - "0x2900950201c2900952402403a8200e14404a9201201d4180700ea4804833", - "0x13f0073e80254900900e9fc03854012a48048520a2061400070a402549009", - "0x4a920126b80480c00e16404a9201206c04a7b00e06c04a92012150fa018", - "0x48590120b403818012a48048180120b80380c012a480480c0120b0039ae", - "0x3a9201214004a8700e01d4900900e06003859030030d701001216404a92", - "0xc2060186b81503300e81804a92012818049ae00e81804a9201201c2f807", - "0x1900700ea48048070f001c03a9201201c0c0070ae1780c3b10aa1580c292", - "0x1320095240253200906e01d3a848030a48048480122b403a64012a4804807", - "0x1d92724e8061490184ea0cd320180aa030e20070ac025490090ac02406007", - "0x2426b030a0003a6b012a480480750601c03a9201201c0c0074de9c13882a", - "0xb80700ea4804a6a01272003a694d4061490090dc0241c8070dc02549009", - "0x1338095240253400909801d340095240243580908401c3580952402534809", - "0x1490094e4024170074e8025490094e8024160070ac025490090ac02406007", - "0x3a9201201c0c0074ce9c93a056020025338095240253380905a01d39009", - "0x4a920129bc340184fc01c3400952402403a7f00e01d4900909002542007", - "0x4a710120b003856012a480485601203003a65012a4804a660129ec03a66", - "0x2b01001299404a920129940482d00e9c004a920129c00482e00e9c404a92", - "0x3a9201212004a8400e01d4900900e1e0038075240240381800e99538271", - "0x386f012a480480709a01c3100952402403a8300e01d4900906602542807", - "0x4a9201201d3f807526025490090de1880c28000e1bc04a920121bc04a81", - "0x2f00901801d2f809524025300094f601d3000952402549a610309f803a61", - "0x1680703002549009030024170070ae025490090ae024160070bc02549009", - "0x48070f001c03a9201201c0c0074be0602b85e0200252f8095240252f809", - "0x1490090660254280700ea48049c8012a1c03807524024248093a201c03a92", - "0x4a9201297404a8100e97404a9201201d340074bc0254900900ea0c03807", - "0x12e25b0309f803a5b012a48048074fe01d2e0095240252ea5e030a0003a5d", - "0x1600735c0254900935c024060074b2025490094b40253d8074b402549009", - "0x12c8095240252c80905a01c0c0095240240c00905c01c0600952402406009", - "0x480c00e01d490094fc0254380700ea480480703001d2c8180186b808009", - "0x485f012744038075240240381800e01dd980900e07803a58012a4804832", - "0x14900900e1e003a58012a4804810012030038075240253f00950e01c03a92", - "0x4a9201295804a8100e95804a9201201c280074ae0254900900ea0c03807", - "0x12aa530309f803a53012a48048074fe01d2a8095240252b257030a0003a56", - "0x160074b0025490094b0024060070ee025490090c20253d8070c202549009", - "0x3b8095240243b80905a01c0c0095240240c00905c01c0600952402406009", - "0x1428093a201c03a9201201c3c00700ea480480703001c3b81801896008009", - "0x14900900e1440387a012a480480750601c03a9201207404a8700e01d49009", - "0x3a7f00e1f404a920129483d01850001d290095240252900950201d29009", - "0x3a50012a480487b0129ec0387b012a480487d4a20613f0074a202549009", - "0x4a920120600482e00e03004a920120300482c00e04004a920120400480c", - "0x38075240240381800e9400c00c02004004a50012a4804a500120b403818", - "0x14080749a0254900900e13403a4f012a480480750601c03a920120a804852", - "0x12380952402403a7f00e91404a920129352781850001d2680952402526809", - "0x481401203003a41012a4804a420129ec03a42012a4804a4548e0613f007", - "0x482d00e06004a920120600482e00e0a404a920120a40482c00e05004a92", - "0x4807030024038075240240380700e9040c02902804004a41012a4804a41", - "0x4a920120a80482a00e01d4900900e06003829028061da00c02006149018", - "0xc2920300a00481400e04004a920120400480c00e01d4900900e04003828", - "0x482800e07804a920120980482900e01d4900900e06003825012ed413027", - "0x381d012a48048270120980381f012a480482001209c03820012a480481e", - "0x382000e01d4900900e0600380776c0240381e00e18004a9201207c04825", - "0x1280703a0254900904a0241300750e025490090f00240f8070f002549009", - "0x14900900e06003a85012edd430095240603000903a01c3000952402543809", - "0x482900e01d4900900e06003a82012ee141a84030a480c01d01205003807", - "0x3a7f012a4804a8001209c03a80012a4804a810120a003a81012a4804a83", - "0x38077720240381e00e9ec04a920129fc0482500e9f804a92012a1004826", - "0x1300705c025490090580240f8070580254900900e0800380752402403818", - "0x168095240613d80903a01d3d8095240241700904a01d3f00952402541009", - "0x3832012eec199ae030a480c27e012050038075240240381800e17c04bba", - "0x1980950c01c03a920126b804a8700e01d4900900e1e00380752402403818", - "0x14900900ea0c038075240254300950801c03a920120b404a8400e01d49009", - "0xd1b8030a000381a012a480481a012a040381a012a480480750401cdc009", - "0x13d8070740254900906e7100c27e00e71004a9201201d3f80706e02549009", - "0x60095240240600905801c080095240240800901801c1c8095240241d009", - "0x1c8180180400800907202549009072024168070300254900903002417007", - "0xd70073900254900900e17c038075240241900950e01c03a9201201c0c007", - "0x3848098061de04202e061490183900300802a06601ce4009524024e4009", - "0x5680709a025490090920250d0070920254900900e3180380752402403818", - "0x4a9201201c190070a00254900905a7440c21800e7454301852402543009", - "0x4850012a040384d012a480484d01233c03851012a48048510120dc03851", - "0xc29203014026851030108061c400e05c04a9201205c0480c00e14004a92", - "0x3a8300e01d4900900e1e0038075240240381800e1640d9f4054ef42a052", - "0x2f055030a48048560120e403856012a4804a8640c0614000740c02549009", - "0x4a9201215c0484200e15c04a920121780481700e01d490090aa024e4007", - "0x48520120b003817012a480481701203003a75012a4804a6401213003a64", - "0xb8100129d404a920129d40482d00e15004a920121500482e00e14804a92", - "0x3a92012a1804a8400e01d4900900e1e0038075240240381800e9d42a052", - "0x1490094e40253d8074e4025490090b29d00c27e00e9d004a9201201d3f807", - "0xd80905c01cfa009524024fa00905801c0b8095240240b80901801d38809", - "0x480703001d3881b3e805c080094e2025490094e20241680703602549009", - "0x3a92012a1804a8400e01d4900905a0254200700ea48048070f001c03a92", - "0x1378095240253780950201d378095240240384d00e9c004a9201201d41807", - "0x4a6b0dc0613f0070dc0254900900e9fc03a6b012a4804a6f4e006140007", - "0x482c00e13004a920121300480c00e9a404a920129a804a7b00e9a804a92", - "0x4a69012a4804a690120b403818012a48048180120b803848012a4804848", - "0x485f012744038075240240387800e01d4900900e06003a6903012026010", - "0x4a9201201d4180700ea4804a86012a10038075240253f00950e01c03a92", - "0x4a680d6061400074d0025490094d0025408074d00254900900e1400386b", - "0x4a7b00e99804a9201299c340184fc01c3400952402403a7f00e99c04a92", - "0x380c012a480480c0120b003810012a480481001203003a65012a4804a66", - "0x3a650300300801001299404a920129940482d00e06004a920120600482e", - "0xe80950e01c03a92012a14049d100e01d4900900e1e00380752402403818", - "0x486f012a040386f012a48048070a201c3100952402403a8300e01d49009", - "0xc27e00e98404a9201201d3f807526025490090de1880c28000e1bc04a92", - "0x80095240240800901801d2f809524025300094f601d3000952402549a61", - "0x1490094be0241680703002549009030024170070180254900901802416007", - "0x3807524024150090a401c03a9201201c0c0074be060060100200252f809", - "0x3a5d012a4804a5d012a0403a5d012a480480709a01d2f00952402403a83", - "0x1490094b896c0c27e00e96c04a9201201d3f8074b8025490094ba9780c280", - "0x1480905801c0a0095240240a00901801d2c8095240252d0094f601d2d009", - "0x80094b2025490094b202416807030025490090300241700705202549009", - "0xc3be0280300c2920300240381801201c03a9201201c3c0074b206014814", - "0x480c01203003827020061490090200245680700ea480480703001c14029", - "0x4a8400e01d4900900e06003826012efc03a9203009c04a3300e03004a92", - "0x381e012a48048250300610b00704a025490090540246700700ea4804810", - "0x4a920120500482c00e03004a920120300480c00e08004a920120780482b", - "0x11800700ea480480703001c100140180a804820012a480482001234c03814", - "0x481400e01d4900900e0400381f012a48048180120a80380752402413009", - "0x4a920121800482900e01d4900900e06003878012f003001d030a480c01f", - "0x481d01209803a85012a4804a8601209c03a86012a4804a870120a003a87", - "0x14900900e060038077820240381e00ea0c04a92012a140482500ea1004a92", - "0x1490090f002413007502025490095040240f8075040254900900e08003807", - "0x14180903a01d400095240254200902e01d418095240254080904a01d42009", - "0xc28000e01d4900900e1e0038075240240381800e9f804bc24fe02549018", - "0x17009524024160100308a00382c012a480480703601d3d8095240253f82a", - "0x1490095000253900702802549009028024160070180254900901802406007", - "0x600c4e201c170095240241700950201d3d8095240253d80909001d40009", - "0x38075240240381800e6b82f82d054024d705f05a0a94900905c9ed40014", - "0x4a6a00e01d49009054024e400700ea4804810012a100380752402403878", - "0xdc0095240241900905601c1900952402419a8003085803833012a4804a7e", - "0x1490093700246980702802549009028024160070180254900901802406007", - "0xe400700ea4804810012a10038075240240381800e6e00a00c054024dc009", - "0x384d00e06804a9201201d4180700ea48048180121480380752402415009", - "0x39c4012a48048370340614000706e0254900906e0254080706e02549009", - "0x4a920120e404a1500e0e404a920127101d0184fc01c1d00952402403a7f", - "0x49c801234c03828012a48048280120b003829012a4804829012030039c8", - "0xc2920300240381801201c03a9201201c3c0073900a01482a01272004a92", - "0x3825018061490090180250a00700ea480480703001c13027030f0c14029", - "0x149009052024060070400a80c2920120a804a1400e07804a92012094048d5", - "0xa00942401c03a9201201c0c00700ef1003a92030078100181a801c14809", - "0x30010030a48048100128480381d012a480481f01205c0381f02806149009", - "0x153c550ca1c0c2920301e00e818050041088070f0025490090c00240b807", - "0x149009504025300075040254900900e368038075240240381800ea0d42285", - "0x1482a1b801d430095240254300905c01d438095240254380905801d41009", - "0x4a81012030038075240240381800e9f93f81878ca01408185240614102a", - "0x4a6000ea1804a92012a180482e00ea1c04a92012a1c0482c00ea0404a92", - "0x380c012a480480c01298003810012a480481001209803a80012a4804a80", - "0x1627b020a48048140180414028650ea0414a5f00e05004a9201205004826", - "0x38075240253f0094ca01c03a9201201c0c00705a0b81627b0200241682e", - "0x14180700ea4804810012a1c03807524024060094ca01c03a9201205004a87", - "0x14000735c0254900935c0254080735c0254900900e36c0385f012a4804807", - "0x4a920120cc190184fc01c1900952402403a7f00e0cc04a920126b82f818", - "0x4a870120b003a7f012a4804a7f0120300381a012a48049b8012364039b8", - "0x13f81001206804a9201206804a1000ea1804a92012a180482e00ea1c04a92", - "0x1490090180253280700ea4804814012a1c038075240240381800e06943287", - "0x1b80952402403a7f00e01d490090540253280700ea4804810012a1c03807", - "0x48290120300383a012a48049c4012364039c4012a4804a8306e0613f007", - "0x4a1000ea1004a92012a100482e00ea1404a92012a140482c00e0a404a92", - "0x4814012a1c038075240240381800e0e9422850520400483a012a480483a", - "0x4a9201201c1000700ea4804810012a1c03807524024060094ca01c03a92", - "0x1480901801c0b809524024e400941c01ce40095240241c82a03083c03839", - "0x1080070300254900903002417007050025490090500241600705202549009", - "0xa00950e01c03a9201201c0c00702e060140290200240b8095240240b809", - "0x482a012994038075240240800950e01c03a9201203004a6500e01d49009", - "0x149009098025408070980254900900e13403842012a480480750601c03a92", - "0x248184fc01c2480952402403a7f00e12004a920121302101850001c26009", - "0x3827012a4804827012030039d1012a480484d0123640384d012a4804848", - "0x4a9201274404a1000e06004a920120600482e00e09804a920120980482c", - "0xc2920300600481400e06004a920120240482a00e7440c02604e040049d1", - "0x482600e05004a920120400485700e01d4900900e0600380c012f1c0802a", - "0x381800e01de400900e07803828012a480481401299003829012a480482a", - "0x600904c01c13009524024138094ea01c138095240240382000e01d49009", - "0x382505206149009052025090070500254900904c0253200705202549009", - "0x480703001c0f80979208004a920300a004a7400e07804a9201209404817", - "0x3000950201c300095240240e80905001c0e8095240241000905201c03a92", - "0x14900900e06003a86012f2943878030a480c06000e061330070c002549009", - "0x1490180520240a0070f0025490090f00240600700ea480481e01214803807", - "0x13007504025490095080242b80700ea480480703001d41809796a1142818", - "0xc00700ef300480703c01d40009524025410094c801d4080952402542809", - "0x482600e9f804a920129fc04a7500e9fc04a9201201c1000700ea4804807", - "0x13da81030a4804a8101284803a80012a4804a7e01299003a81012a4804a83", - "0x381800e0b404bcd05c025490185000253a007058025490094f60240b807", - "0x4a8100e6b804a9201217c0482800e17c04a920120b80482900e01d49009", - "0x480703001cdc00979c0c819818524060d7078030998039ae012a48049ae", - "0xc28101205003833012a480483301203003807524024160090a401c03a92", - "0x383a012a48048370120a4038075240240381800e71004bcf06e0680c292", - "0x4a920120680482600e72004a920120e40482700e0e404a920120e804828", - "0x38075240240381800e01de800900e07803842012a48049c801209403817", - "0xb809524024e200904c01c240095240242600903e01c2600952402403820", - "0x1490180840240e8070920254900902e0240b8070840254900909002412807", - "0x1e90510a00614901809a0cc0c05e00e01d4900900e060039d1012f4426809", - "0x2a0091c401c2a0095240242883250e0a87180700ea480480703001c29009", - "0x10600709202549009092025390070a0025490090a0024060073e802549009", - "0x4a87012994038075240240381800e7d024850054024fa009524024fa009", - "0x1e980900e0780381b012a480485201203003807524024190094ca01c03a92", - "0x3807524025438094ca01c03a92012744049d100e01d4900900e06003807", - "0x3859012a480480704001c0d8095240241980901801c03a920120c804a65", - "0x4a9201281804a0c00e12404a9201212404a7200e81804a9201216404a0b", - "0x4a8700e01d4900950e0253280700ea480480703001d030490360a804a06", - "0x480703001c03bd401201c0f0070ac025490093700240600700ea4804a81", - "0x1490095020254380700ea4804a8701299403807524024168093a201c03a92", - "0x1490090aa025058070aa0254900900e08003856012a480487801203003807", - "0x160560540242f0095240242f00941801c16009524024160094e401c2f009", - "0x2b8095240254300901801c03a920120a404a8700e01d4900900e0600385e", - "0x4a8700e01d4900903e024e880700ea480480703001c03bd501201c0f007", - "0x4a0b00e99004a9201201c100070ae0254900900e0240600700ea4804829", - "0x4a75012a4804a750128300381e012a480481e0129c803a75012a4804a64", - "0x480740c01c0a00952402403a0600e04004a9201201d030074ea0782b82a", - "0x14900900e8280381e012a480480740c01c1300952402403a0600e0a004a92", - "0x38075240240387800e01d4900900e15803860012a480480740c01c0f809", - "0x381800ea1404bd650ca1c0c2920301e00481400e1e004a920120600482a", - "0x482700ea0c04a92012a100482800ea1004a92012a180482900e01d49009", - "0x3a80012a4804a8201209403a81012a4804a8701209803a82012a4804a83", - "0x13f80903e01d3f8095240240382000e01d4900900e060038077ae0240381e", - "0xe807500025490094fc024128075020254900950a024130074fc02549009", - "0x14900904e0980c05500e01d4900900e06003a7b012f601380952406140009", - "0x1480700ea480480703001c168097b20b8160185240614080902801c13809", - "0x19809524024d700904e01cd70095240242f80905001c2f80952402417009", - "0x3bda01201c0f00737002549009066024128070640254900905802413007", - "0x3837012a480481a01207c0381a012a480480704001c03a9201201c0c007", - "0xc2920120c804a1200e6e004a920120dc0482500e0c804a920120b404826", - "0x1490183700240e80700ea480480702001c1d009524024e200902e01ce2032", - "0x2f007052025490090520a00c05500e01d4900900e06003839012f6c14809", - "0x483a012148038075240240381800e10804bdc02e7200c2920300a403818", - "0x248097ba120260185240601900902801ce4009524024e400901801c03a92", - "0xe88095240242600904c01c26809524024240090ae01c03a9201201c0c007", - "0x1000700ea480480703001c03bde01201c0f0070a00254900909a02532007", - "0x39d1012a480484901209803852012a48048510129d403851012a4804807", - "0x4a9203014004a7400e15004a920127440481700e14004a9201214804a64", - "0x80180aa01c15009524024fa00905201c03a9201201c0c007036025ef9f4", - "0x1030185240602c9c80303d403859012a480482a0120a00382a012a480482a", - "0x13900740c0254900940c0240600700ea480480703001c2b85e0aa0a9f0056", - "0x1490184ea024770074ea9900c292012151030181d801c2a0095240242a009", - "0x788074e09c40c2920129d0048f000e01d4900900e06003a72012f853a009", - "0x4a920129c40482a00e01d4900900e06003a6f012f881000952406138009", - "0x1348097c69a8370185240613580902801c100095240241001f0303cc03a6b", - "0x1340095240243580905001c358095240253500905201c03a9201201c0c007", - "0x1490094ce024128070d0025490090dc024130074ce025490094d002413807", - "0x3a65012a480480704001c03a9201201c0c00700ef900480703c01d33009", - "0x4a920121880482500e1a004a920129a40482600e18804a920129940481f", - "0x300180aa01c03a9201201c0c0070de025f281d012a480c26601207403a66", - "0x14900900e06003a60012f9930a93030a480c0680120500381d012a480481d", - "0x4a5e01209c03a5e012a4804a5f0120a003a5f012a4804a610120a403807", - "0x381e00e96c04a920129740482500e97004a92012a4c0482600e97404a92", - "0x1490094b40240f8074b40254900900e080038075240240381800e01df3809", - "0x12d80903a01d2d8095240252c80904a01d2e0095240253000904c01d2c809", - "0x128095240241281e030154038075240240381800e96004be804a02549018", - "0x12b00905201c03a9201201c0c0074aa025f4a564ae061490184b80240a007", - "0x130070ee025490090c2024138070c2025490094a6024140074a602549009", - "0xc00700efa80480703c01d290095240243b80904a01c3d0095240252b809", - "0x482600e94404a920121f40481f00e1f404a9201201c1000700ea4804807", - "0x1f580c012a480c25201207403a52012a4804a510120940387a012a4804a55", - "0xc07a0120500380c012a480480c0280602a80700ea480480703001c3d809", - "0x3a45012a4804a4f01215c038075240240381800e93404bec49e9400c292", - "0x38077da0240381e00e90804a9201291404a6400e91c04a9201294004826", - "0x1300710e025490094820253a8074820254900900e0800380752402403818", - "0x11f809524061210094e801d21009524024438094c801d2380952402526809", - "0x4a920128fc0482900e01d4900900e1e0038075240240381800e8f404bee", - "0x149009478024140074740254900948e0240b8071160254900900e81c03a3c", - "0x11d0094e401c048095240240480905801d320095240253200901801d1c009", - "0x1048074700254900947002540807116025490091160250200747402549009", - "0x4bef4680254901846e0247e80746e2404602a5240251c08b4740253200c", - "0x1490184620247d8074628c80c2920128d0048fc00e01d4900900e06003a33", - "0x7c8071308b00c2920128c0048fa00e01d4900900e06003a2f012fc118009", - "0x3a2b012a480486c0123dc0386c012a48048980123e00380752402516009", - "0x4a920122400482c00e8a404a920122300480c00e8a804a920128c80482a", - "0x1f880900e0780389c012a4804a2b0123d80389d012a4804a2a0120980389b", - "0x4a920128c80482a00e26804a920128bc0490700e01d4900900e06003807", - "0x4a280120980389b012a48048900120b003a29012a480488c01203003a28", - "0x14900900e060038077e20240381e00e27004a92012268048f600e27404a92", - "0x3a9201209c04a8400e01d4900902e0243700700ea480485601280803807", - "0x38075240240e80950801c03a920120800485200e01d4900904a02542007", - "0x460095240244600901801d138095240251980940201c03a9201203004a84", - "0x3a271202301500944e0254900944e025000071200254900912002416007", - "0x480704001c03a920128f4049d100e01d4900900e1e00380752402403818", - "0x482c00e8a404a920129900480c00e29404a9201228c0490700e28c04a92", - "0x389c012a48048a50123d80389d012a4804a470120980389b012a4804809", - "0x3a9201201c0800700ea480480703001c510097e429004a92030270049ff", - "0x1128090ae01c03a9201201c0c007156025f9a2544c0614901813a0240a007", - "0xf0071540254900915a025320071580254900944c0241300715a02549009", - "0x4a230129d403a23012a480480704001c03a9201201c0c00700efd004807", - "0x481700e2a804a9201288804a6400e2b004a920122ac0482600e88804a92", - "0x3a9201201c0c007168025fa8b5012a480c0aa0129d0038b3012a48048ac", - "0x1490094420254080744202549009164024140071640254900916a02414807", - "0x14900900e060038c24402e8153f61763000c292030885148181ea01d10809", - "0x598c00303b0038b3012a48048b30129c8038c0012a48048c001203003807", - "0x3a9201201c0c007438025fba1d012a480c21e0123b803a1e18806149009", - "0xc007190025fc0c9012a480c0c70123c4038c74360614900943a02478007", - "0x1fca184340614901818c0240a00718c025490094360241500700ea4804807", - "0x1490094340241300719c025490094300242b80700ea480480703001c67809", - "0x3a9201201c0c00700efe80480703c01c15809524024670094c801d0b009", - "0x4a9201233c0482600e85404a9201234c04a7500e34c04a9201201c10007", - "0x10a00902e01d0a216030a4804a160128480382b012a4804a1501299003a16", - "0x38075240240381800e84804bfb1a8025490180560253a0071aa02549009", - "0x4a9201236804a8100e36804a920128440482800e84404a9201235004829", - "0x2900700ea480480703001c6c8097f836c6e0185240606d0c40307f8038da", - "0x107a10030a480c216012050038dc012a48048dc012030038075240246a809", - "0x4a10012098038e3012a4804a0f01215c038075240240381800e83804bfd", - "0x14900900e060038077fc0240381e00e83004a9201238c04a6400e38804a92", - "0x14900941c02413007414025490094160253a8074160254900900e08003807", - "0x1060094e801c7a8095240247100902e01d06009524025050094c801c71009", - "0x38f0012a48048ec0120a4038075240240381800e3b804bff1d802549018", - "0x1490181e23700c1fe00e3c404a920123c404a8100e3c404a920123c004828", - "0x1390071e6025490091e60240600700ea480480703001d0200980081c79818", - "0x1490181fa024770071fa8240c2920123d4798181d801c7a8095240247a809", - "0x788071f23e80c2920123f0048f000e01d4900900e060038fb0130047e009", - "0x38075240240387800e01d4900900e060038f70130087c0095240607c809", - "0x49fb00e3d804a920123e1038db1922ec5200c04a0741005602e09c101fc", - "0x100809524025010093f201d01009524024838fa0307e803907012a48048f6", - "0x1490094020250000713602549009136024160074120254900941202406007", - "0x4a8400e01d4900900e1e0038075240240381800e8044da0905402500809", - "0x648090a401c03a9201236c0484900e01d4900940e0242480700ea4804827", - "0x480c012a10038075240245200922001c03a920122ec04a0200e01d49009", - "0x1490090400242900700ea480481d012a10038075240241280950801c03a92", - "0x4a920123dc0491200e01d4900902e0243700700ea480485601280803807", - "0x10480901801cff009524024ff8093f201cff809524025000fa0307e803a00", - "0x150093fc025490093fc02500007136025490091360241600741202549009", - "0x3a9201205c0486e00e01d4900900e1e0038075240240381800e7f84da09", - "0x38075240246d80909201c03a9201281c0484900e01d4900904e02542007", - "0x14200700ea48048a4012440038075240245d80940401c03a9201232404852", - "0x485200e01d4900903a0254200700ea4804825012a100380752402406009", - "0x480c00e7f004a920123ec04a0100e01d490090ac0250100700ea4804820", - "0x49fc012a48049fc0128000389b012a480489b0120b003a09012a4804a09", - "0x48170121b8038075240242b00940401c03a9201201c0c0073f826d0482a", - "0x1490091920242900700ea48048db012124038075240241380950801c03a92", - "0x3a9201203004a8400e01d490091480248800700ea48048bb01280803807", - "0x3807524024100090a401c03a9201207404a8400e01d4900904a02542007", - "0x49d100e01d4900900e060038078060240381e00e7ec04a920128100480c", - "0x1380950801c03a9201205c0486e00e01d490090ac0250100700ea48048ee", - "0x48bb01280803807524024648090a401c03a9201236c0484900e01d49009", - "0x14900904a0254200700ea480480c012a10038075240245200922001c03a92", - "0x4a920123700480c00e01d490090400242900700ea480481d012a1003807", - "0xfc809524024fd00922401cfd0095240240382000e01d4900900e1e0039fb", - "0x489b0120b003912012a48049100127e403910012a48049f91ea060fd007", - "0x3a9201201c0c00722426cfd82a01244804a9201244804a0000e26c04a92", - "0x38075240241380950801c03a9201205c0486e00e01d490090ac02501007", - "0x10100700ea48048c901214803807524024100090a401c03a9201285804a87", - "0x4a8400e01d490090180254200700ea48048a4012440038075240245d809", - "0x381e00e7dc04a920123640480c00e01d4900903a0254200700ea4804825", - "0x1490090ac0250100700ea4804a12012744038075240240381800e01e02009", - "0x3a9201285804a8700e01d4900904e0254200700ea48048170121b803807", - "0x38075240245d80940401c03a920123240485200e01d4900904002429007", - "0x14200700ea4804825012a10038075240240600950801c03a9201229004910", - "0x382000e01d4900900e1e0039f7012a48048c4012030038075240240e809", - "0x3915012a48049f61aa060fd0073ec025490092280248900722802549009", - "0x4a9201245c04a0000e26c04a9201226c0482c00e45c04a92012454049f9", - "0x2b00940401c03a9201201c3c00700ea480480703001c8b89b3ee0a804917", - "0x4820012148038075240241380950801c03a9201205c0486e00e01d49009", - "0x1490090180254200700ea48048a4012440038075240245d80940401c03a92", - "0x4a920123200491200e01d4900903a0254200700ea4804825012a1003807", - "0x6200901801cfa8095240248d8093f201c8d8095240248ca1b0307e803919", - "0x150093ea025490093ea02500007136025490091360241600718802549009", - "0x3a9201215804a0200e01d4900900e1e0038075240240381800e7d44d8c4", - "0x3807524024100090a401c03a9201209c04a8400e01d4900902e02437007", - "0x14200700ea48048a4012440038075240245d80940401c03a9201207404a84", - "0x60071d0025490094380250080700ea4804825012a100380752402406009", - "0x740095240247400940001c4d8095240244d80905801c6200952402462009", - "0x6100940401c03a9201288004a0200e01d4900900e060038e813631015009", - "0x4827012a10038075240240b8090dc01c03a9201215804a0200e01d49009", - "0x14900903a0254200700ea4804820012148038075240241280950801c03a92", - "0x4a920122e80480c00e01d490090180254200700ea48048a401244003807", - "0x10100700ea48048b4012744038075240240381800e01e0280900e078038e7", - "0x4a8400e01d4900904e0254200700ea48048170121b8038075240242b009", - "0x5200922001c03a9201207404a8400e01d490090400242900700ea4804825", - "0x48070f001c738095240251480901801c03a9201203004a8400e01d49009", - "0xf78b30307e8039ef012a48049f2012448039f2012a480480704001c03a92", - "0x10000713602549009136024160073da025490093dc024fc8073dc02549009", - "0x4856012808038075240240381800e7b44d8e7054024f6809524024f6809", - "0x14900904a0254200700ea4804827012a10038075240240b8090dc01c03a92", - "0x3a9201203004a8400e01d4900903a0254200700ea480482001214803807", - "0x49eb3d8060fd0073d602549009144024890073d80254900913a0240b807", - "0x482c00e8a404a920128a40480c00e48c04a92012484049f900e48404a92", - "0x480703001c9189b4520a804923012a48049230128000389b012a480489b", - "0x3a9201205c0486e00e01d490090ac0250100700ea48048070f001c03a92", - "0x3807524024100090a401c03a9201209404a8400e01d4900904e02542007", - "0x3924012a480487a01205c038075240240a0094ce01c03a9201207404a84", - "0x1490093d4024fc8073d40254900924c4900c1fa00e49804a920121ec04912", - "0x9400940001c048095240240480905801d320095240253200901801c94009", - "0x38075240240387800e01d4900900e060039280129901500925002549009", - "0x14200700ea48048170121b8038075240240a0094ce01c03a9201215804a02", - "0x4a6700e01d4900903a0254200700ea48048200121480380752402413809", - "0xfd007256025490094b002489007252025490094b80240b80700ea480481e", - "0x4a920129900480c00e4c804a920127a4049f900e7a404a920124ac94818", - "0x990094c80a804932012a480493201280003809012a48048090120b003a64", - "0x4a6700e01d490090ac0250100700ea48048070f001c03a9201201c0c007", - "0xf0094ce01c03a9201209c04a8400e01d4900902e0243700700ea4804814", - "0x486801205c03807524024300094ce01c03a920120800485200e01d49009", - "0xfc807268025490092664c40c1fa00e4cc04a920121bc0491200e4c404a92", - "0x48095240240480905801d320095240253200901801cf20095240249a009", - "0x387800e01d4900900e060039e4012990150093c8025490093c802500007", - "0x48170121b8038075240240a0094ce01c03a9201215804a0200e01d49009", - "0x1490090c00253380700ea480481e01299c038075240241380950801c03a92", - "0x492c4e2060fd007258025490094de0248900700ea480481f0127dc03807", - "0x482c00e99004a920129900480c00e4e004a92012794049f900e79404a92", - "0x480703001c9c0094c80a804938012a480493801280003809012a4804809", - "0x3a9201205004a6700e01d490090ac0250100700ea48048070f001c03a92", - "0x38075240240f0094ce01c03a9201209c04a8400e01d4900902e02437007", - "0x386d012a4804a7201280403807524024300094ce01c03a9201207c049f7", - "0x4a920121b404a0000e02404a920120240482c00e99004a920129900480c", - "0x4a0200e01d490090bc0250100700ea480480703001c368094c80a80486d", - "0x1380950801c03a9201205c0486e00e01d490090280253380700ea4804857", - "0x486001299c038075240240f8093ee01c03a9201207804a6700e01d49009", - "0x3a9201201c0c00700f0180480703c01cf80095240242a80901801c03a92", - "0x38075240240b8090dc01c03a9201205004a6700e01d49009036024e8807", - "0x13380700ea480481f0127dc038075240240f0094ce01c03a9201209c04a84", - "0x3c0073e0025490093900240600700ea480481001299c0380752402430009", - "0xc1fa00e4ec04a920127800491200e78004a9201201c1000700ea4804807", - "0x48095240240480905801cef8095240249e8093f201c9e8095240249d854", - "0x4a6700e01d4900900e060039df0127c0150093be025490093be02500007", - "0x1380950801c03a920120c804a8700e01d490090280253380700ea4804810", - "0x486001299c038075240240f8093ee01c03a9201207804a6700e01d49009", - "0x3a9201201c0c00700f01c0480703c01c9f8095240242100901801c03a92", - "0x38075240240a0094ce01c03a9201204004a6700e01d49009072024e8807", - "0xfb80700ea480481e01299c038075240241380950801c03a920120c804a87", - "0x480c00e01d490090500253380700ea480486001299c038075240240f809", - "0xa080922401ca08095240240382000e01d4900900e1e00393f012a4804807", - "0x39dc012a48049e20127e4039e2012a48049de074060fd0073bc02549009", - "0xc0073b80249f82a01277004a9201277004a0000e02404a920120240482c", - "0xf0094ce01c03a9201205004a6700e01d490090200253380700ea4804807", - "0x482801299c03807524024300094ce01c03a9201207c049f700e01d49009", - "0x4a7b012448039da012a4804a8101205c03807524024130094ce01c03a92", - "0x60073a0025490093a4024fc8073a4025490093a67680c1fa00e74c04a92", - "0xe8009524024e800940001c048095240240480905801c0380952402403809", - "0x3a0600e07804a9201201cfb00704c0254900900e450039d001201c15009", - "0x48070ac01d438095240240391500e18004a9201201c8a00703e02549009", - "0x1490180300240c11700e01d490090540243e80700ea48048070f001c03a92", - "0x4a92012a140491900e01d4900900e06003a82506a101540850a0954302a", - "0x382003a09d3fa80018a4804a810127d403a81012a4804a8501246c03a85", - "0xc2920129f8049f200e9f804a92012a00048e700ea0004a92012a00048e8", - "0x170090ee01c1682e030a48048100127c8038075240253d8090ee01c1627b", - "0xf70070be0b00c2920120b0049ef00e0b004a920120b004a5100e01d49009", - "0x3a920120c80486e00e01d49009066025328070640ccd702a5240242f809", - "0x481a0127b80381a05a0614900905a024f78073700254900935c0246a807", - "0x48d500e01d490090740243700700ea48049c40129940383a3880dc15292", - "0xc1ed00ea1804a92012a180482c00e01d4900900e04003839012a4804837", - "0x4a9201209c130183d601d3f8095240253f8093d801c128095240241281e", - "0xc0d400e08004a920120800f8180aa01c0e8095240240e8600307ac03827", - "0x14200700ea4804820012a10038075240240381800e01e048075240601c9b8", - "0x486100e01d490090520254200700ea480481d0121b80380752402414009", - "0x14380924201c03a9201209c0486e00e01d490090280254200700ea480480c", - "0x482c0121dc03807524024168090ee01c03a920129fc0492300e01d49009", - "0x16018524024160093de01c03a9201201c0c00700f0280480703c01c03a92", - "0x260090dc01c03a9201205c04a6500e13021017054a48049c80127b8039c8", - "0xf70070920b40c2920120b4049ef00e12004a92012108048d500e01d49009", - "0x3a920121400486e00e01d4900909a025328070a07442682a52402424809", - "0x480703001c03c0b00ea480c0510900606a0070a2025490093a20246a807", - "0x14900903a0243700700ea4804828012a10038075240241000950801c03a92", - "0x3a9201205004a8400e01d490090180243080700ea4804829012a1003807", - "0x38075240253f80924601c03a92012a1c0492100e01d4900904e02437007", - "0x381800e01e0600900e07803807524024160090ee01c03a920120b404877", - "0x13280700ea4804852012994039f40a8148152920120b0049ee00e01d49009", - "0x3859012a480481b0122a80381b012a48049f4012490038075240242a009", - "0x1490090ac0253280700ea4804a06012994038550ac818152920120b4049ee", - "0x2b8590308a003857012a480485e0122a80385e012a480485501249003807", - "0x13a80981a01d490184c8025198074c8025490094c8025408074c802549009", - "0x4a920121e1438183d401c3c0095240253f80924c01c03a9201201c0c007", - "0x480c0124a0038075240253a0090c201d39274030a48048780124a003878", - "0x958074de9c80c2920129c80492900e01d490094e2024308074e09c40c292", - "0x370090dc01d4986f0c4995330684ce9a035a694d41b93582052402537809", - "0x486b012a1003807524025348090a401c03a920129a804a0200e01d49009", - "0x1490090d00248800700ea4804a67012a10038075240253400950801c03a92", - "0x3a920121880484900e01d490094ca0242900700ea4804a6601280803807", - "0x1308095240253580905001c03a92012a4c0485200e01d490090de02424807", - "0x12d25b4b89752f25f040a4804a600124ac03a604e0061490094e002494807", - "0x38075240252e80940401c03a920129780486e00e18529a554ac95d2c259", - "0x14200700ea4804a5a012a10038075240252d80950801c03a9201297004852", - "0x485200e01d490094ae0250100700ea4804a58012440038075240252c809", - "0x308090a401c03a9201294c0484900e01d490094aa0242480700ea4804a56", - "0x1408070f4025490090ee9840c22800e1dc04a9201297c0482800e01d49009", - "0x3a9201201c0c0074a4026070075240603d00946601c3d0095240243d009", - "0x122a4d49e9403da51040a480487d0124ac0387d4e4061490094e402494807", - "0x38075240252800940401c03a9201294404a8400e8f11ea3f10e90521247", - "0x14200700ea4804a45012a10038075240252680950801c03a9201293c04852", - "0x485200e01d490094820250100700ea4804a420124400380752402523809", - "0x11e0090a401c03a920128f40484900e01d4900947e0242480700ea4804887", - "0x492900e8e804a9201222c048aa00e22c04a920121ec0492400e01d49009", - "0x117a304628c919a3446e240460205240251c00925601d1c270030a4804a70", - "0x11a0090a401c03a920128dc04a0200e01d49009118025420074561b04c22c", - "0x4a31012a10038075240251900950801c03a920128cc04a8400e01d49009", - "0x1490094580242900700ea4804a2f012808038075240251800922001c03a92", - "0x3a920128ac0485200e01d490090d80242480700ea480489801212403807", - "0x4a294740611400745202549009454024550074540254900912002492007", - "0x389d01303c03a9203026c04a3300e26c04a9201226c04a8100e26c04a92", - "0x4d0205240244e00925601c4e272030a4804a720124a40380752402403818", - "0x486e00e01d49009134025420071542b0568ab44a898510a414a28d13a28", - "0x5200950801c03a9201229404a8400e01d490091460242900700ea4804a28", - "0x4a25012808038075240251300922001c03a9201228804a8400e01d49009", - "0x1490091580242480700ea48048ad01212403807524024558090a401c03a92", - "0x1490094e0024948074460254900944e0246200700ea48048aa01214803807", - "0x10f0c41848805d0bb180884590b416a2cc102920128880492b00e88938018", - "0x3a920122c80485200e01d4900916a0243700700ea48048b3012a1003a1d", - "0x38075240245d80950801c03a9201230004a8400e01d4900944202542007", - "0x2480700ea48048c2012148038075240251000940401c03a920122e804910", - "0x48c400e01d4900943a0242900700ea4804a1e0121240380752402462009", - "0x38075240240381800e01e080075240610e2230307a403a1c012a48048b4", - "0x14200700ea480481d0121b8038075240241400950801c03a9201208004a84", - "0x486e00e01d490094e00243080700ea4804a720121840380752402414809", - "0x14900900e060038078220240381e00e01d490090280254200700ea4804827", - "0x10d0c6190324638205240250d80925601d0da72030a4804a720124a403807", - "0x3a920123240486e00e01d4900918e025420074288546982b42c33867a18", - "0x38075240250c00950801c03a9201286804a8400e01d4900919002501007", - "0x2900700ea4804a16012808038075240246700922001c03a9201233c04a84", - "0x485200e01d4900942a0242480700ea48048d30121240380752402415809", - "0x38d41aa061490091aa024988071aa0254900918c0249900700ea4804a14", - "0xc2920129c00492900e84404a920128480493300e84804a920123500482a", - "0x760f541482d060e21c683907a101b236c6e0205240246d00925601c6d270", - "0x38075240246c80940401c03a9201236c0486e00e01d490091b802542007", - "0x8800700ea48048e3012a10038075240250700950801c03a9201283c04a84", - "0x484900e01d490094160242900700ea4804a0c0128080380752402471009", - "0x10800926401c03a920123b00485200e01d490091ea0242480700ea4804a0a", - "0x38f1012a48048f00120a8038f01dc061490091dc024988071dc02549009", - "0x4a920123cc0483700e84404a920128440483700e3cc04a920123c404933", - "0x14900900e1e0038075240240381800e01e0900752406079a110304d0038f3", - "0x3a920120740486e00e01d490090500254200700ea4804820012a1003807", - "0x3807524025380090c201c03a920129c80486100e01d4900905202542007", - "0x2900700ea48048ee012148038075240240a00950801c03a9201209c0486e", - "0x3a04012a4804a860120b003a07012a4804807012030038075240246a809", - "0x4807012030038075240240387800e01d4900900e060038078260240381e", - "0x4a7200e35404a9201235404a7200ea1804a92012a180482c00e01c04a92", - "0x7e00925801c7e0fd4120a9490091dc35543007020790038ee012a48048ee", - "0x7c0f9054a48048fb012794038075240240381800e3e804c141f602549018", - "0x4a920303dc0493800e01d490091f00242900700ea48048f9012148038f7", - "0x481d0121b8038075240247b0093a201c03a9201201c0c00720e0260a8f6", - "0x1490094e00243080700ea4804a72012184038075240241480950801c03a92", - "0x3a920120a004a8400e01d490090280254200700ea48048270121b803807", - "0x4a920123f40482c00e81c04a920128240480c00e01d4900904002542007", - "0x20b00900e07803a01012a4804a040127c003a02012a4804a070121b403a04", - "0x1390185240253900925201c03a9201241c049d100e01d4900900e06003807", - "0x391722a7d88a1f7224440fc9fa3f67f0ff1ff040a4804a000124ac03a00", - "0x2900700ea48049fc01280803807524024ff0090dc01c03a920127fc04a84", - "0x491000e01d490092200254200700ea48049f9012a1003807524024fd809", - "0xfb00909201c03a920124500485200e01d490093ee0250100700ea4804912", - "0x49fa0120a0038075240248b8090a401c03a920124540484900e01d49009", - "0x738e83ea08149009236024958072369c00c2920129c00492900e46404a92", - "0x48e80121b803807524024fa80950801c93124246484f59ec3da7b8f79f2", - "0x1490093dc0254200700ea48049f2012148038075240247380940401c03a92", - "0x3a920127ac04a0200e01d490093d80248800700ea48049ed012a1003807", - "0x38075240249200909201c03a9201248c0484900e01d4900924202429007", - "0x4a920127a88c81845001cf5009524024f780905001c03a9201249804852", - "0x381800e4a404c1700ea480c1280128cc03928012a4804928012a0403928", - "0x989323d208149009256024958072569c80c2920129c80492900e01d49009", - "0x49320121b803807524024f480950801c9d9e03e01b49c1e52587909a133", - "0x1490092680254200700ea4804933012148038075240249880940401c03a92", - "0x3a920124e004a0200e01d490093ca0248800700ea480492c012a1003807", - "0x3807524024f000909201c03a920127c00484900e01d490090da02429007", - "0x1380185240253800925201c9e809524024f200905001c03a920124ec04852", - "0x39cc39a51ce79d03a474ced1dc3c4778a093f040a48049df0124ac039df", - "0x2900700ea48049de01280803807524024a08090dc01c03a920124fc04a84", - "0x491000e01d490093a60254200700ea48049dc012a1003807524024f1009", - "0xa380909201c03a9201273c0485200e01d490093a00250100700ea48049d2", - "0x49da0120a003807524024e60090a401c03a920127340484900e01d49009", - "0x1198072960254900929602540807296025490093944f40c22800e72804a92", - "0x1390185240253900925201c03a9201201c0c00729a0260c007524060a5809", - "0x39b12b86c8d99b63766f4df1c0386548e31c7040a48049c90124ac039c9", - "0x2900700ea480495201280803807524024e30090dc01c03a9201271c04a84", - "0x491000e01d4900937c0254200700ea48049c0012a1003807524024e1809", - "0xd900909201c03a920126cc0485200e01d4900936c0250100700ea48049bb", - "0x49bd0120a003807524024d88090a401c03a920125700484900e01d49009", - "0xd792d360081490092c0024958072c09c00c2920129c00492900e57804a92", - "0x492d0121b803807524024d800950801cb59a52d259cd39aa3566b0b21b4", - "0x1490092c80254200700ea48049b401214803807524024d780940401c03a92", - "0x3a9201269c04a0200e01d490093540248800700ea48049ac012a1003807", - "0x3807524024d280909201c03a920125a40484900e01d490092ce02429007", - "0x4a9201268caf01845001cd1809524024d580905001c03a920125ac04852", - "0x381800e67804c1900ea480c1a80128cc039a8012a48049a8012a04039a8", - "0xcd19b3380814900933a0249580733a9c80c2920129c80492900e01d49009", - "0x499b0121b803807524024ce00950801cc7982312630c71913265c8cc199", - "0x1490093300254200700ea480499901214803807524024cd00940401c03a92", - "0x3a9201263804a0200e01d490093260254200700ea4804972012a1003807", - "0x3807524024c100909201c03a920126240484900e01d4900931802429007", - "0x185240240000927601c00009524024c88093c001c03a9201263c04852", - "0x4a700124a403c1c012a4804c1b01277c03c1b012a4804c1a0124f403c1a", - "0x21342584908e114215310820fc1e83a0814900952e0249580752e9c00c292", - "0x14900983e0250100700ea4804c1e0121b8038075240260e80950801e14427", - "0x3a9201308404a8400e01d490095300254200700ea4804c2001214803807", - "0x3807524026128090a401c03a9201309004a0200e01d4900984402542007", - "0xf000700ea4804c28012148038075240261380909201c03a9201309804849", - "0x4a920130a40493d00f0a54d0185240254d00927601d4d00952402611809", - "0x4c2b0120dc03c1c012a4804c1c0120dc03c2b012a4804c2a01277c03c2a", - "0x486e00e01d4900900e0600380785801d490188570700c13400f0ac04a92", - "0x1380090c201c03a920129c80486100e01d490090520254200700ea480481d", - "0x4828012a10038075240240a00950801c03a9201209c0486e00e01d49009", - "0x1490090000248800700ea4804a9a012440038075240241000950801c03a92", - "0x21700900e07803a9b012a48048fd0120b003c2d012a4804a0901203003807", - "0x4a920123f40482c00e82404a920128240480c00e01d4900900e06003807", - "0x7ea0902050403a9a012a4804a9a0124fc03800012a48048000124fc038fd", - "0x381800f0d004c3386402549018862024ef0078630c21782a5240254d000", - "0x8800700ea4804c3501244003c3786d0d4152920130c8049e200e01d49009", - "0x3a9201201c0c0078740261cc38012a480c4370124e0038075240261b009", - "0x3807524025380090c201c03a920129c80486100e01d49009870024e8807", - "0x14200700ea4804828012a10038075240240a00950801c03a9201209c0486e", - "0x480c00e01d4900903a0243700700ea4804829012a100380752402410009", - "0x3c3b012a4804c2d0121b403a9b012a4804c300120b003c2d012a4804c2f", - "0x49d100e01d4900900e0600380787a0240381e00f0f004a92012a6c049f0", - "0x22043f040a4804c3e0124ac03c3e4e4061490094e40249480700ea4804c3a", - "0x2200090dc01c03a920130fc04a8400f12a24c4888ea762344588910e21441", - "0x4c43012a1003807524026210090a401c03a9201310404a0200e01d49009", - "0x14900988c0248800700ea4804c45012a10038075240262200950801c03a92", - "0x3a920131240484900e01d490098900242480700ea4804c4701214803807", - "0xc2920129c00492900f12c04a92012a74048c400e01d4900989402429007", - "0x22ba9e8ad1562a4538a51462844f53913a268205240262600925601e26270", - "0x38075240254e00940401c03a920131380486e00e01d4900989a02542007", - "0x14200700ea4804c51012a10038075240262800950801c03a9201313c04852", - "0x484900e01d490098aa0242900700ea4804c530124400380752402629009", - "0x22a00918801c03a9201315c0485200e01d4900953c0242480700ea4804c56", - "0x3080700ea480480703001c03c5900ea480c458896060f48078b002549009", - "0x4a8400e01d4900904e0243700700ea4804a700121840380752402539009", - "0x1480950801c03a9201208004a8400e01d490090500254200700ea4804814", - "0x21800905801e2d0095240261780901801c03a920120740486e00e01d49009", - "0x1490094e40249480700ea480480703001c03c5c01201c0f0078b602549009", - "0x234c688cf19a32c648c718a30c608bf178102920131740492b00f17539018", - "0x3a9201318004a0200e01d490098be0243700700ea4804c5e012a1003c6a", - "0x38075240263180950801c03a9201318804a8400e01d490098c202429007", - "0x2480700ea4804c66012808038075240263280922001c03a9201319004a84", - "0x493200e01d490098d40242900700ea4804c690121240380752402634009", - "0x1500095240263600905401e3646b030a4804c6b0124c403c6b012a4804c67", - "0x4c6e0124ac03c6e4e0061490094e0024948078da0254900954002499807", - "0x3a920131bc04a8400f1ee3d4798f11de3b4758e91ce394718e11bc10292", - "0x3807524026390090a401c03a920131c404a0200e01d490098e002437007", - "0x8800700ea4804c75012a10038075240263a00950801c03a920131cc04a84", - "0x484900e01d490098f20242480700ea4804c77012808038075240263b009", - "0x493100f1f004a920131e00493200e01d490098f60242900700ea4804c7a", - "0x1510095240263f00926601e3f0095240263e80905401e3ec7c030a4804c7c", - "0xc2a28da0609a007544025490095440241b8078da025490098da0241b807", - "0x4a7001218403807524025390090c201c03a9201201c0c00700f1fc03a92", - "0x1490090500254200700ea4804814012a1003807524024138090dc01c03a92", - "0x3a920120740486e00e01d490090520254200700ea4804820012a1003807", - "0x2400095240261780901801c03a920131ac0485200e01d490098f802429007", - "0x600700ea480480703001c03c8201201c0f0079020254900986002416007", - "0x235809524026358094e401e180095240261800905801e1780952402617809", - "0x3c8590920c152920131f235c3085e040f20078f8025490098f802539007", - "0x14900990c024f280700ea480480703001e4400990f21804a920312140492c", - "0x24500927001c03a92012a840485200e01d4900991202429007914a864482a", - "0x3700700ea4804c8b012744038075240240381800f23404c8c91602549018", - "0x4a8400e01d490090500254200700ea4804814012a100380752402413809", - "0x1380090c201c03a920120740486e00e01d490090520254200700ea4804820", - "0x24200905801e400095240264180901801c03a920129c80486100e01d49009", - "0xf00791e02549009902024f800791c025490099000243680790202549009", - "0x4a720124a403807524026468093a201c03a9201201c0c00700f24004807", - "0x24da9f9352664c49792d2564a49392408149009922024958079229c80c292", - "0x1490099280250100700ea4804c930121b8038075240264900950801e4ec9c", - "0x3a9201325c04a8400e01d4900992c0254200700ea4804c9501214803807", - "0x38075240264d00940401c03a920132640491000e01d4900993002542007", - "0xee00700ea4804c9d012148038075240264e00909201c03a92012a7c04852", - "0x1029201327c0492b00f27d380185240253800925201e4f0095240264d809", - "0x3700700ea4804ca0012a1003cab5332aa54ca894f29a52ca494728a50ca0", - "0x4a8400e01d490099460242900700ea4804ca20128080380752402650809", - "0x25380922001c03a9201329804a8400e01d4900994a0254200700ea4804ca4", - "0x4a9901212403807524026548090a401c03a920132a004a0200e01d49009", - "0x25649e0304d003cac012a4804caa01277003807524026558090a401c03a92", - "0xa00950801c03a9201209c0486e00e01d4900900e0600380795a01d49018", - "0x4829012a10038075240241000950801c03a920120a004a8400e01d49009", - "0x1490094e40243080700ea4804a70012184038075240240e8090dc01c03a92", - "0x25800900e07803caf012a4804c840120b003cae012a4804c8301203003807", - "0x149009962024958079629c80c2920129c80492900e01d4900900e06003807", - "0x38075240265900950801d4b4bd9792ee5d4b99712de5b4b59692ce59020", - "0x14200700ea4804cb5012148038075240265a00940401c03a920132cc0486e", - "0x491000e01d490099700254200700ea4804cb7012a10038075240265b009", - "0x25e00909201c03a920132ec0485200e01d490099740250100700ea4804cb9", - "0x13800925201e5f0095240265e8093b801c03a92012a580485200e01d49009", - "0x263aa398d316624c3984a5660cc0040a4804cbf0124ac03cbf4e006149009", - "0x4a9501280803807524026608090dc01c03a9201330004a8400f32a64cc8", - "0x1490099880254200700ea4804cc3012a1003807524026610090a401c03a92", - "0x3a92012a8c04a0200e01d4900998c0248800700ea4804cc5012a1003807", - "0x3807524026650090a401c03a920133200484900e01d4900998e02429007", - "0x14900900e0600380799801d490189972f80c13400f32c04a92013324049dc", - "0x3a920120a004a8400e01d490090280254200700ea48048270121b803807", - "0x38075240240e8090dc01c03a920120a404a8400e01d4900904002542007", - "0x3ccd012a4804c8301203003807524025390090c201c03a920129c004861", - "0x492b00e01d4900900e0600380799e0240381e00f33804a920132100482c", - "0x4cd0012a1003cdb9b53666c4d79ad3554a4d49a734a68cd0040a4804a72", - "0x1490099a60242900700ea4804cd201280803807524026688090dc01c03a92", - "0x3a9201335404a8400e01d490095280254200700ea4804cd4012a1003807", - "0x38075240266c0090a401c03a9201335c04a0200e01d490099ac02488007", - "0x3cdc012a4804cdb0124c8038075240266d00909201c03a9201336404849", - "0x1490099bc024998079bc025490099ba024150079bb3700c29201337004931", - "0x2764eb9d53a6744e79cd396724e39c5386700205240253800925601e6f809", - "0x38075240267100940401c03a920133840486e00e01d490099c002542007", - "0x14200700ea4804ce5012a10038075240267200950801c03a9201338c04852", - "0x485200e01d490099d00250100700ea4804ce70124400380752402673009", - "0x27600926401c03a920133ac0484900e01d490099d40242480700ea4804ce9", - "0x3cef012a4804cee0120a803cee9da061490099da024988079da02549009", - "0x4a920133c00483700f37c04a9201337c0483700f3c004a920133bc04933", - "0x48270121b8038075240240381800e01e78807524062784df0304d003cf0", - "0x1490090400254200700ea4804828012a10038075240240a00950801c03a92", - "0x3a920133b40485200e01d4900903a0243700700ea4804829012a1003807", - "0x4a920132100482c00f3c804a9201320c0480c00e01d490099b802429007", - "0x3c83012a4804c83012030038075240240381800e01e7a00900e07803cf3", - "0x4a920133b404a7200f37004a9201337004a7200f21004a920132100482c", - "0x27b8095240627b00925801e7b4f554a0a9490099db3724248302079003ced", - "0x485200f3ee7d2a6054a4804cf7012794038075240240381800f3e404cf8", - "0x27f0099fb3f004a920313ec0493800e01d490099f40242900700ea4804aa6", - "0x14200700ea4804828012a10038075240267e0093a201c03a9201201c0c007", - "0x4a8400e01d4900903a0243700700ea4804829012a100380752402410009", - "0x482c00f3c804a92012a940480c00e01d4900904e0243700700ea4804814", - "0x4cfe012744038075240240381800e01e7a00900e07803cf3012a4804cf5", - "0x4a8100f40004a920120527f81845001e7f8095240241380915401c03a92", - "0x38075240240381800f40804d0100ea480c5000128cc03d00012a4804d00", - "0x149009a0802540807a080254900905340c0c22800f40c04a92012074048aa", - "0x1001845001c03a9201201c0c007a0c026828075240628200946601e82009", - "0x4d0800ea480c5070128cc03d07012a4804d07012a0403d07012a4804828", - "0x154809524026850093b401e850095240240382000e01d4900900e06003d09", - "0x1490099ea0241600754a0254900954a02406007a1602549009552024e9807", - "0x27aaa502002685809524026858093a401c128095240241280905c01e7a809", - "0x28600952402403a8300e01d49009a120251800700ea480480703001e85825", - "0x149009a1b4300c28000f43404a9201343404a8100f43404a9201201ce8007", - "0x28780939e01e87809524026872aa0309f803aaa012a48048074fe01e87009", - "0x170079ea025490099ea0241600754a0254900954a02406007a2002549009", - "0xc007a200967aaa502002688009524026880093a401c1280952402412809", - "0x1000950801c03a920120a004a8400e01d49009a0c0251800700ea4804807", - "0x4d12012a0403d12012a480480728e01e8880952402403a8300e01d49009", - "0xc27e00f45004a9201201d3f807a2602549009a254440c28000f44804a92", - "0x1528095240255280901801e8b0095240268a80939e01e8a80952402689d14", - "0x149009a2c024e900704a0254900904a024170079ea025490099ea02416007", - "0x38075240268100946001c03a9201201c0c007a2c0967aaa50200268b009", - "0x3700700ea4804829012a10038075240241000950801c03a920120a004a84", - "0x4a8100f46004a9201201ce6807a2e0254900900ea0c038075240240e809", - "0x3d1a012a48048074fe01e8c8095240268c517030a0003d18012a4804d18", - "0x14900954a02406007a3802549009a36024e7807a3602549009a334680c27e", - "0x28e0093a401c128095240241280905c01e7a8095240267a80905801d52809", - "0x1490090500254200700ea480480703001e8e0259eaa9408009a3802549009", - "0x3a920120740486e00e01d490090520254200700ea4804820012a1003807", - "0x28e8095240255280901801c03a9201209c0486e00e01d4900902802542007", - "0x3d2001201c0f007a3e025490099f2024e6007a3c025490099ea02416007", - "0x14200700ea4804814012a1003807524024138090dc01c03a9201201c0c007", - "0x486e00e01d490090520254200700ea4804820012a100380752402414009", - "0x24180901801c03a920129c80486100e01d490094e00243080700ea480481d", - "0xf007a3e02549009910024e6007a3c0254900990802416007a3a02549009", - "0x4a7001218403807524025390090c201c03a9201201c0c00700f48004807", - "0x1490090500254200700ea4804814012a1003807524024138090dc01c03a92", - "0x3a920120740486e00e01d490090520254200700ea4804820012a1003807", - "0x149009868024e6007a3c0254900986002416007a3a0254900985e02406007", - "0x3807524024cf00946001c03a9201201c0c00700f4800480703c01e8f809", - "0x3080700ea4804a72012184038075240241480950801c03a920120740486e", - "0x4a8400e01d490090280254200700ea48048270121b80380752402538009", - "0x482c00f48404a920128240480c00e01d490090400254200700ea4804828", - "0x494d0128c0038075240240381800e01e9180900e07803d22012a48048fd", - "0x1490094e40243080700ea4804829012a10038075240240e8090dc01c03a92", - "0x3a9201205004a8400e01d4900904e0243700700ea4804a7001218403807", - "0x2920095240250480901801c03a9201208004a8400e01d4900905002542007", - "0x11800700ea480480703001c03d2601201c0f007a4a025490091fa02416007", - "0x486100e01d490090520254200700ea480481d0121b80380752402494809", - "0xa00950801c03a9201209c0486e00e01d490094e00243080700ea4804a72", - "0x4a09012030038075240241000950801c03a920120a004a8400e01d49009", - "0x14900900e06003807a500240381e00f49c04a920123f40482c00eab004a92", - "0x3a920129c80486100e01d490090520254200700ea480481d0121b803807", - "0x38075240240a00950801c03a9201209c0486e00e01d490094e002430807", - "0x3d1d012a4804a09012030038075240241000950801c03a920120a004a84", - "0x4a9201347c049cf00f47c04a920123e8049cc00f47804a920123f40482c", - "0x48250120b803d1e012a4804d1e0120b003d1d012a4804d1d01203003d29", - "0x14900900e06003d2904b47a8e8100134a404a920134a4049d200e09404a92", - "0x3a920120a004a8400e01d490090400254200700ea480489d0128c003807", - "0x3807524025390090c201c03a920120a404a8400e01d4900903a02437007", - "0xf00700ea4804814012a1003807524024138090dc01c03a920129c004861", - "0x4820012a10038075240252900946001c03a9201201c0c00700f04404807", - "0x1490090520254200700ea480481d0121b8038075240241400950801c03a92", - "0x3a9201209c0486e00e01d490094e00243080700ea4804a7201218403807", - "0x3a02012a4804807012030038075240240387800e01d4900902802542007", - "0x4a92012804049f000eab004a920128080486d00e80404a92012a180482c", - "0x4d240121b403d25012a4804d270127c003d24012a4804aac0121b403d27", - "0x49f000f0ec04a920134840486d00f48804a92013494049f000f48404a92", - "0x3c5b012a4804c3c0127c003c5a012a4804c3b0121b403c3c012a4804d22", - "0x4a920132380486d00f23c04a9201316c049f000f23804a920131680486d", - "0x4caf0127c003ccd012a4804cae0121b403caf012a4804c8f0127c003cae", - "0x3a8300f3cc04a92013338049f000f3c804a920133340486d00f33804a92", - "0xc28000f4ac04a920134ac04a8100f4ac04a9201201ce5007a5402549009", - "0x2970095240269652d0309f803d2d012a48048074fe01e9600952402695d2a", - "0x1490099e6024160079e4025490099e402406007a5e02549009a5c024e7807", - "0x279cf202002697809524026978093a401c128095240241280905c01e79809", - "0x3a9201208004a8400e01d490094ea0251800700ea480480703001e97825", - "0x38075240241480950801c03a920120740486e00e01d4900905002542007", - "0x9080700ea48048270121b8038075240240a00950801c03a9201203004861", - "0x480750601c03a9201201c3c00700ea4804a7f01248c0380752402543809", - "0x15581850001e980095240269800950201e980095240240394b00eaac04a92", - "0x3d33012a4804d31a640613f007a640254900900e9fc03d31012a4804d30", - "0x4a92012a180482c00e01c04a9201201c0480c00f4d004a920134cc049cf", - "0x12a8600e04004d34012a4804d3401274803825012a48048250120b803a86", - "0x38075240243000929a01c03a9201207c04a6700e01d4900900e06003d34", - "0x14200700ea4804a87012484038075240241400950801c03a9201204004877", - "0x494d00e01d490090280254200700ea480480c0121840380752402414809", - "0x29a8184fc01e9a80952402403a7f00e01d4900903c024e480700ea4804826", - "0x3807012a480480701203003d37012a4804d3601273c03d36012a4804a82", - "0x4a920134dc049d200ea0c04a92012a0c0482e00ea1004a92012a100482c", - "0x3828012a480480750601c03a920120600487d00f4dd41a8400e04004d37", - "0x48260500614000704c0254900904e024e300704e0a80c2920120a8049c7", - "0x3820012a480481e04a0614000703c0300c292012030048ad00e09404a92", - "0x4a9201207c1001850001c0f8095240240f80950201c0f80952402403952", - "0x300780308600387802806149009028024568070c00254900900e06c0381d", - "0x3a86012a4804a8703a0614000750e0254900950e0254080750e02549009", - "0x14900950aa100c21800ea10148185240241480915a01d428095240240381b", - "0x483900ea0804a92012a0d4301850001d418095240254180950201d41809", - "0x3a7f012a4804a8001205c038075240254080939001d40281030a4804a82", - "0x13f00900e0311f8074fe025490094fe025390074fc0a80c2920120a8049c7", - "0x485200e01d4900900e060039ae0be0b41553805c0b13d82a5240613f810", - "0x140007064025490090280cc0c28000e0cc04a9201201d4180700ea480482e", - "0x149009034024e400706e0680c2920126e00483900e6e004a920120a419018", - "0x49c40129c803a7b012a4804a7b0120b0039c4012a480483701205c03807", - "0x2604202e0aa9c9c80720e8152920307100602a0589ec0623f00e71004a92", - "0x248095240242400909801c24009524024e400908401c03a9201201c0c007", - "0x1490090920241680707202549009072024170070740254900907402416007", - "0x13f00709a0254900900e9fc038075240240381800e1241c83a05402424809", - "0x4a9201205c0482c00e14004a9201274404a7b00e74404a9201213026818", - "0x2804202e0a804850012a48048500120b403842012a48048420120b803817", - "0x4380700ea480480c012a10038075240240a00950801c03a9201201c0c007", - "0xc27e00e14404a9201201d3f80700ea4804829012a100380752402415009", - "0x168095240241680905801c2a009524024290094f601c29009524024d7051", - "0x38540be0b4150090a8025490090a8024168070be025490090be02417007", - "0x480c00e0a40a00c020041490090540240c00702070c0380752402403878", - "0x380c012a480480c0120b003814012a48048140128e003810012a4804810", - "0x39be00e01d4900900e1e003829018050080100120a404a920120a4049c0", - "0x601836c01c0a009524024039bb00e03004a9201201cde80702002549009", - "0x14009524024148100306c803829012a48048290126cc03829012a4804814", - "0x14900904c024af00704a0980c2920120a0049b100e09c04a9201201cae007", - "0x48090120b003807012a48048070120300381e012a480482501258003807", - "0x81af00e09c04a9201209c0492d00e07804a92012078049b000e02404a92", - "0x38780134e8300095240600e80936801c0e81f0400a94900904e07804807", - "0x3a92012a1c049ac00ea1543287054a48048600125900380752402403818", - "0x3a83012a480480706401d4200952402403a9300e01d4900950a024e8807", - "0x4a92012a180492d00e07c04a9201207c0482c00e08004a920120800480c", - "0xf8200186ac03a83012a4804a830120dc03a84012a4804a8401298003a86", - "0xc0074fc0269da7f012a480c2800126a803a80502a0815292012a0d42286", - "0xb380700ea480482c0127440382c4f6061490094fe024d380700ea4804807", - "0x2f8095240241680934a01c03a920120b80496900e0b4170185240253d809", - "0x14900900e060038370346e01553c0640ccd702a5240602f8185020a8b5807", - "0x49c401267803839012a480480735001c1d1c4030a480483201268c03807", - "0x499e00e0cc04a920120cc0482e00e6b804a920126b80482c00e71004a92", - "0x38075240240381800e01e9e8075240601c9c40307a40383a012a480483a", - "0xce8073900254900900ea0c038075240241d00940401c03a920120a80487d", - "0x210095240240b9c8030a0003817012a4804817012a0403817012a4804807", - "0x149009090024ce007090025490090841300c27e00e13004a9201201d3f807", - "0x1980905c01cd7009524024d700905801d410095240254100901801c24809", - "0x480703001c2483335ca080800909202549009092024cd80706602549009", - "0x381800e01e9f0075240602683a0307a40384d012a480480733401c03a92", - "0x14900900e674039d1012a480480750601c03a920120a80487d00e01d49009", - "0x3a7f00e14404a92012140e881850001c280095240242800950201c28009", - "0x39f4012a480485401267003854012a48048510a40613f0070a402549009", - "0x4a920120cc0482e00e6b804a920126b80482c00ea0804a92012a080480c", - "0x38075240240381800e7d0199ae504040049f4012a48049f401266c03833", - "0x3859012a480485901298003859012a48048071b401c0d8095240240395c", - "0x48560125a4038550ac0614900940c024b380740c025490090b206c0c199", - "0xd702a2d601c2f0095240242f00933001c2f0095240242a80934a01c03a92", - "0x497200e01d4900900e06003a714e49d01553f4ea9902b82a5240602f033", - "0x480732601d3800952402403a8300e01d490090540243e80700ea4804a75", - "0x13f8074d6025490094de9c00c28000e9bc04a920129bc04a8100e9bc04a92", - "0x1348095240253500933801d350095240253586e0309f80386e012a4804807", - "0x1490094c8024170070ae025490090ae024160075040254900950402406007", - "0x3a9201201c0c0074d29902ba82020025348095240253480933601d32009", - "0x4a9201201c1900700ea480486b01272003a680d6061490094e20241c807", - "0x4a740120b003a67012a4804a670120dc03a68012a4804a6801209803a67", - "0x133068030a480c2674d0a081519100e9c804a920129c80482e00e9d004a92", - "0x4a660120a403a66012a4804a66012638038075240240381800e99404d40", - "0x3780950201d498095240240398c00e1bc04a920121880482800e18804a92", - "0x3a61012a4804a61012a0403a61012a4804a930de061140070de02549009", - "0x14900900e06003a6001350403a9203098404a3300e1a004a920121a00480c", - "0x4a5e01260803a5e012a4804a5f054060c48074be0254900900e08003807", - "0x482e00e9d004a920129d00482c00e1a004a920121a00480c00e97404a92", - "0x381800e975392740d004004a5d012a4804a5d01266c03a72012a4804a72", - "0x14900900ea0c03807524024150090fa01c03a9201298004a3000e01d49009", - "0x12da5c030a0003a5b012a4804a5b012a0403a5b012a480480731e01d2e009", - "0xce0074b0025490094b49640c27e00e96404a9201201d3f8074b402549009", - "0x13a0095240253a00905801c340095240243400901801d2b8095240252c009", - "0x12ba724e81a0080094ae025490094ae024cd8074e4025490094e402417007", - "0x74ac0254900900ea0c03807524024150090fa01c03a9201201c0c007", - "0x1298095240252aa56030a0003a55012a4804a55012a0403a55012a4804807", - "0x1490090ee024ce0070ee025490094a61840c27e00e18404a9201201d3f807", - "0x13900905c01d3a0095240253a00905801d328095240253280901801c3d009", - "0x480703001c3d2724e8994080090f4025490090f4024cd8074e402549009", - "0x49b80120b003a52012a4804a8201203003807524024150090fa01c03a92", - "0x381e00e1ec04a920120dc0484800e94404a920120680482e00e1f404a92", - "0x1490094fc0260d00700ea480482a0121f4038075240240381800e01ea1009", - "0x14080905801d290095240254100901801c03a9201294004c1b00e93d28018", - "0xf0070f60254900949e024240074a202549009030024170070fa02549009", - "0x487801306803807524024150090fa01c03a9201201c0c00700f50804807", - "0x482c00e94804a920120800480c00e01d4900949a0260d80748a9340c292", - "0x387b012a4804a4501212003a51012a48048180120b80387d012a480481f", - "0x4a920129080499c00e90804a920121ed238184fc01d2380952402403a7f", - "0x4a510120b80387d012a480487d0120b003a52012a4804a5201203003a41", - "0x14900900e1e003a414a21f52901001290404a920129040499b00e94404a92", - "0x4a920120300483700e03004a9201201d4b8070200254900900f07003807", - "0x14900900e0c803829012a480480706401c0a009524024060100310740380c", - "0x1480906e01c0a0095240240a00983c01c038095240240380901801c14009", - "0xc2920120a01481400e0420f807050025490090500241b80705202549009", - "0x3a9800e01d4900900e0600381e01350c128095240601300984001c13027", - "0x386003a0614900904a0261100703e025490090400261080704002549009", - "0x3a920121e004c2400ea1c3c0185240240e80984601c03a92012180049d1", - "0x1490090120241600704e0254900904e0240600750c0254900950e02612807", - "0xf80984e01d430095240254300984c01c0c0095240240c00905c01c04809", - "0x4a9a00ea0941a8450a0414900903ea180c00904e0321400703e02549009", - "0x13f82a5240254080985201c03a9201201c0c007500026a2281012a480c282", - "0x1490094fc0261580700ea4804a7b012744038075240253f80985401d3da7e", - "0x1700985e01c170095240241600953601c160095240241600985a01c16009", - "0xd700909201c03a9201217c0484900e0dc0d1b80640ccd705f05a0a149009", - "0x49b8012124038075240241900909201c03a920120cc0484900e01d49009", - "0x4a9201201e1800700ea4804837012124038075240240d00909201c03a92", - "0x381800e01ea2807524060e202d0304d00382d012a480482d0120dc039c4", - "0x14900900e6740383a012a480480750601c03a920120a80487d00e01d49009", - "0x3a7f00e72004a920120e41d01850001c1c8095240241c80950201c1c809", - "0x384c012a480484201267003842012a48049c802e0613f00702e02549009", - "0x4a92012a0c0482e00ea1004a92012a100482c00ea1404a92012a140480c", - "0x38075240240381800e13141a8450a0400484c012a480484c01266c03a83", - "0x4a920121240498200e12404a920121201501831201c2400952402403820", - "0x4a830120b803a84012a4804a840120b003a85012a4804a850120300384d", - "0x14900900e0600384d506a114281001213404a920121340499b00ea0c04a92", - "0x149009508024160073a20254900950a0240600700ea480482a0121f403807", - "0x480703c01c290095240254000939801c288095240254180905c01c28009", - "0x4a9201209c0480c00e01d490090540243e80700ea480480703001c03d46", - "0x481e01273003851012a48048180120b803850012a48048090120b0039d1", - "0x482c00e74404a920127440480c00e15004a920121480499c00e14804a92", - "0x4854012a480485401266c03851012a48048510120b803850012a4804850", - "0x480786401c0600952402403c3100e01d4900900e1e0038540a2140e8810", - "0x843400e05004a92012050049b300e03004a92012030049b300e05004a92", - "0x38075240240381800e0781282605551c138280520a94901802803015009", - "0x4a9201207c04c3700e01d490090400261b00703e0800c29201209c04c35", - "0xc01f0130e003828012a48048280120b803829012a48048290120b00381f", - "0x487d00e01d4900903a0261d00700ea480480703001c30009a9007404a92", - "0x14380950201d4380952402403c3b00e1e004a9201201d4180700ea4804810", - "0x13f00750a0254900900e9fc03a86012a4804a870f00614000750e02549009", - "0x4a9201201c0480c00ea0c04a92012a100499c00ea1004a92012a1942818", - "0x48280120b803818012a480481801227403829012a48048290120b003807", - "0x480703001d418280300a40380c012a0c04a92012a0c0499b00e0a004a92", - "0x4a9201201e190075040254900900f0f003807524024300093a201c03a92", - "0x140290210d003a81012a4804a810126cc03a82012a4804a820126cc03a81", - "0x4c3600e01d4900900e0600382e0589ec155494fc9fd4002a52406140a82", - "0x480732601c1680952402403a8300e01d490090200243e80700ea4804a7e", - "0x13f80735c025490090be0b40c28000e17c04a9201217c04a8100e17c04a92", - "0xdc0095240241900933801c19009524024d70330309f803833012a4804807", - "0x1490090300244e807500025490095000241600700e0254900900e02406007", - "0x140007018024dc009524024dc00933601d3f8095240253f80905c01c0c009", - "0xd00939001c1b81a030a480482e0120e4038075240240381800e6e13f818", - "0xe200906e01c1b8095240241b80904c01ce20095240240383200e01d49009", - "0xc880705802549009058024170074f6025490094f60241600738802549009", - "0x1c80931c01c03a9201201c0c007390026a5039074061490183880dc0382a", - "0x21f0070840254900902e0241400702e025490090720241480707202549009", - "0x24009524024260420308a003842012a4804842012a040384c012a4804807", - "0x1490180900251980707402549009074024060070900254900909002540807", - "0x14900900f1000384d012a480480787e01c03a9201201c0c007092026a5807", - "0xd98070a27440c29201274404c4100e140268185240242680988201ce8809", - "0xc0510a00b13d81086801c288095240242880936601c2800952402428009", - "0x1490093e80261b80700ea480480703001d030590360aaa61f40a814815292", - "0xfa00987001c2a0095240242a00905c01c290095240242900905801cfa009", - "0x82920301582a052055108038075240240381800e15404d4d0ac02549018", - "0xc29201299004c4300e01d4900900e06003a714e49d01554e4ea9902b85e", - "0x1358092e401c3726b030a480484d01310c03807524025380092e401d37a70", - "0xd18074d49bc0c2920129bc04c4100e9bc04a920129bc049b300e01d49009", - "0x370185240243700988201c03a920121ac04a0200e1ad3481852402535009", - "0x4a69012310038075240243400940401c34267030a4804a6801268c03a68", - "0x485e0120b0038075240240381000e99404a9201299c048c400e99804a92", - "0xc1e900e9d404a920129d4049b300e15c04a9201215c0482e00e17804a92", - "0xb900700ea48048100121f4038075240240381800e01ea780752406132a66", - "0x497200e01d490090dc024b900700ea4804a750125c803807524024e8809", - "0x1490094de024d180700ea480480703001c03d5001201c0f00700ea4804a6f", - "0x4a0200e985498185240243700934601c03a9201218804a0200e1bc31018", - "0xf48074be025490094c2024620074c0025490090de0246200700ea4804a93", - "0x3807524024080090fa01c03a9201201c0c00700f54403a9203097d30018", - "0x381800e01ea900900e078038075240253a8092e401c03a9201274404972", - "0x4c4300e01d490094bc024b90074ba9780c2920129d404c4300e01d49009", - "0x12d25d030a4804a5d013104038075240252e0092e401d2da5c030a48049d1", - "0x1490094b60262080700ea4804a5801280803a584b2061490094b4024d1807", - "0x48c400e01d490094aa025010074aa9580c29201295c049a300e95d2d818", - "0x2a980752406030a530307a403861012a4804a5601231003a53012a4804a59", - "0x38075240252d8092e401c03a920120400487d00e01d4900900e06003807", - "0x12e80934601c03a9201201c0c00700f5480480703c01c03a9201297404972", - "0x387d4a4061490094b6024d180700ea48048770128080387a0ee06149009", - "0x3d8095240243e80918801d288095240243d00918801c03a9201294804a02", - "0x1490090200243e80700ea480480703001c03d5400ea480c07b4a2060f4807", - "0x3a4f012a480480788801d2800952402403a8300e01d4900900e1e003807", - "0x4a9201201d3f80749a0254900949e9400c28000e93c04a9201293c04a81", - "0x1d00901801d210095240252380933801d2380952402526a450309f803a45", - "0x17007030025490090300244e8070bc025490090bc0241600707402549009", - "0x3a420ae0602f03a018025210095240252100933601c2b8095240242b809", - "0x3a3f10e06149009482024d18074820254900900f1140380752402403818", - "0x11e8095240251e80953a01d1f8095240251f80933c01d1e80952402403c46", - "0x4a1e00e01d490091160250100747422d1e02a5240251ea3f0740aa23807", - "0x2248071200254900900f1200388c012a480488701287803a38012a4804a3a", - "0x1490091188dc0c21800e8dc04a920128dc04a8100e8dc04a920122411c018", - "0x4a9201201e260074640254900900f12c03a33012a480480789401d1a009", - "0x117a314640aa2680745e02549009460025190074600254900900e08003a31", - "0x160074780254900947802406007130025490094680262700745802549009", - "0x2b8095240242b80905c01c0c0095240240c00913a01c2f0095240242f009", - "0x14900913002627807458025490094580254e00746602549009466024d9807", - "0x80071368a51522b0d8031490091308b1198570301791e0298a001c4c009", - "0x38075240240381800e27004d5513a025490181360262880700ea4804807", - "0x480703001d13809aac8a004a9203026804c5300e26804a9201227404c52", - "0x518095240240382000e01d49009450024e880700ea48048070f001c03a92", - "0x486c012030038a4012a48048a5012608038a5012a48048a3020060c4807", - "0x482e00e8a804a920128a80489d00e8ac04a920128ac0482c00e1b004a92", - "0xc0071488a51522b0d8030048a4012a48048a401266c03a29012a4804a29", - "0x5101850001c5100952402403a8300e01d490090200243e80700ea4804807", - "0x381800e01eab80900e07803a25012a4804a2601212003a26012a4804a27", - "0x4c1b00e2b4558185240244e00983401c03a920120400487d00e01d49009", - "0x48074fe01c03a9201201c3c00744a0254900915a0242400700ea48048ab", - "0x600744602549009154024ce0071540254900944a2b00c27e00e2b004a92", - "0x1150095240251500913a01d158095240251580905801c3600952402436009", - "0x114a2a4561b00600944602549009446024cd8074520254900945202417007", - "0x3807524024e88092e401c03a920121340497200e01d4900900e06003a23", - "0x5980952402538a220309f803a22012a48048074fe01c03a920120400487d", - "0x1490094e802416007074025490090740240600716a02549009166024ce007", - "0x5a80933601d390095240253900905c01c0c0095240240c00913a01d3a009", - "0x4855012744038075240240381800e2d5390184e80e80600916a02549009", - "0x1490090200243e80700ea48049d10125c803807524024268092e401c03a92", - "0x4a920122c804a8100e2c804a9201201c2c8071680254900900ea0c03807", - "0x1108c00309f8038c0012a48048074fe01d10809524024590b4030a00038b2", - "0x16007074025490090740240600717402549009176024ce00717602549009", - "0x2a0095240242a00905c01c0c0095240240c00913a01c2900952402429009", - "0x38075240240381800e2e82a0180a40e80600917402549009174024cd807", - "0x13f80700ea48048100121f403807524024e88092e401c03a9201213404972", - "0x620095240246100933801c61009524025032200309f803a20012a4804807", - "0x1490090300244e80703602549009036024160070740254900907402406007", - "0xd83a018024620095240246200933601c2c8095240242c80905c01c0c009", - "0x1490090200243e80700ea48048490128c0038075240240381800e3102c818", - "0x4a9201287404a8100e87404a9201201cc780743c0254900900ea0c03807", - "0x10e21b0309f803a1b012a48048074fe01d0e0095240250ea1e030a0003a1d", - "0x1600707402549009074024060071920254900918e024ce00718e02549009", - "0x160095240241600905c01c0c0095240240c00913a01d3d8095240253d809", - "0x38075240240381800e324160184f60e80600919202549009192024cd807", - "0x14080718c0254900900e000038c8012a480480750601c03a920120400487d", - "0x10c00952402403a7f00e86804a920123186401850001c6300952402463009", - "0x49c8012030038ce012a48048cf012670038cf012a4804a1a4300613f007", - "0x482e00e06004a920120600489d00e9ec04a920129ec0482c00e72004a92", - "0xc00719c0b00c27b390030048ce012a48048ce01266c0382c012a480482c", - "0x10b0184fc01d0b00952402403a7f00e01d490090200243e80700ea4804807", - "0x3807012a4804807012030038d3012a480482b0126700382b012a480481e", - "0x4a920120940482e00e06004a920120600489d00e09804a920120980482c", - "0x4a9201201e188071a60940c02600e030048d3012a48048d301266c03825", - "0x149009018024d980702002549009020024d98070180254900900f0c803810", - "0xc00704a0981382aab00a014814054a480c00c020060048108a801c06009", - "0x14f00700ea480481e0131580382003c061490090500262a80700ea4804807", - "0x148095240241480905c01c0a0095240240a00905801c1000952402410009", - "0x481f013160038075240240381800e07404d5903e025490180400262b807", - "0x4a9201201e1d8070c00254900900ea0c03807524024150090fa01c03a92", - "0x48074fe01d438095240243c060030a0003878012a4804878012a0403878", - "0x60075080254900950a024ce00750a0254900950ea180c27e00ea1804a92", - "0x148095240241480905c01c0a0095240240a00905801c0380952402403809", - "0xe880700ea480480703001d4202902801c0800950802549009508024cd807", - "0x49b300ea0804a9201201e190075060254900900f168038075240240e809", - "0x149018504a0c1481402115003a82012a4804a820126cc03a83012a4804a83", - "0x3a920129fc04c5600e01d4900900e0600382c4f69f81555a4fea014082a", - "0x382d012a480480732601c1700952402403a8300e01d490090540243e807", - "0x4a9201201d3f8070be0254900905a0b80c28000e0b404a920120b404a81", - "0x380901801c190095240241980933801c198095240242f9ae0309f8039ae", - "0xcd8075000254900950002417007502025490095020241600700e02549009", - "0x1600907201c03a9201201c0c007064a01408070200241900952402419009", - "0x482600e0dc04a9201201c1900700ea48049b80127200381a37006149009", - "0x3a7e012a4804a7e0120b003837012a48048370120dc0381a012a480481a", - "0x383901356c1d1c4030a480c03703401c1519100e9ec04a920129ec0482e", - "0x39c8012a480483a0120a40383a012a480483a0126380380752402403818", - "0xb8095240240b80950201c2100952402403c3e00e05c04a9201272004828", - "0x49c40120300384c012a480484c012a040384c012a480484202e06114007", - "0x3c5b00e01d4900900e0600384801357003a9203013004a3300e71004a92", - "0x2208073a21240c29201212404c4100e13404a9201201e2e80709202549009", - "0x4a92012140049b300e74404a92012744049b300e1402681852402426809", - "0x381800e1640d9f40555742a0520a20a9490180a07453da7e02115003850", - "0x482e00e14404a920121440482c00e15004a9201215004a9e00e01d49009", - "0x3a9201201c0c0070ac026af206012a480c05401315c03852012a4804852", - "0x480703001d392744ea0aaafa640ae1782a810524061030520a20aa2f007", - "0x2480988601c03a920129c40497200e9c1388185240242b80988601c03a92", - "0x2208074e0025490094e0024d980700ea4804a6f0125c803a6b4de06149009", - "0x1490094d2025010074d29a80c2920121b8049a300e1b93801852402538009", - "0x4a0200e99d340185240243580934601c35a6b030a4804a6b01310403807", - "0x160074cc025490094d0024620070d0025490094d40246200700ea4804a67", - "0x1320095240253200936601c2f0095240242f00905c01c2a8095240242a809", - "0x1490090540243e80700ea480480703001c03d6000ea480c2660d0060f4807", - "0x3a920129ac0497200e01d490094c8024b900700ea480484d0125c803807", - "0x49a300e01d4900900e06003807ac20240381e00e01d490094e0024b9007", - "0x14986f030a4804a6b01268c038075240253280940401c31265030a4804a70", - "0x4a92012a4c048c400e98404a92012188048c400e01d490090de02501007", - "0x482a0121f4038075240240381800e01eb1007524061302610307a403a60", - "0x3d6301201c0f00700ea4804a640125c803807524024268092e401c03a92", - "0x3a9201297c0497200e9792f8185240253200988601c03a9201201c0c007", - "0x1490094bc0262080700ea4804a5d0125c803a5c4ba0614900909a02621807", - "0x4c4100e01d490094b2025010074b29680c29201296c049a300e96d2f018", - "0x3a9201295804a0200e9592b8185240252c00934601d2c25c030a4804a5c", - "0xc2534aa060f48074a6025490094ae024620074aa025490094b402462007", - "0x4a5c0125c803807524024150090fa01c03a9201201c0c00700f59003a92", - "0x38075240240381800e01eb180900e078038075240252f0092e401c03a92", - "0xc292012970049a300e01d490090c2025010070ee1840c292012978049a3", - "0x4a520123100387d012a4804877012310038075240243d00940401d2907a", - "0x487d00e01d4900900e06003807aca01d490184a21f40c1e900e94404a92", - "0x12800950201d2800952402403c4400e1ec04a9201201d4180700ea480482a", - "0x13f00749a0254900900e9fc03a4f012a4804a500f6061400074a002549009", - "0x4a920127100480c00e91c04a920129140499c00e91404a9201293d26818", - "0x4a4701266c0385e012a480485e0120b803855012a48048550120b0039c4", - "0x12100952402403c5f00e01d4900900e06003a470bc154e201001291c04a92", - "0x14900910e024cf00747e0254900900f1180388748206149009484024d1807", - "0x45a3c47a0a94900947e21ce202a88e01d1f8095240251f80953a01c43809", - "0x3a920128e804a8400e8e804a9201222c04a1e00e01d4900947802501007", - "0x4600952402403c6000e01d4900947002542007470025490094820250f007", - "0x4a92012240049b300e23004a92012230049b300e24004a9201201e30807", - "0x119a3446e0a9490181202302f05502115003a3d012a4804a3d01203003890", - "0x482c00e8cc04a920128cc04a9e00e01d4900900e06003a304628c815566", - "0x2b3a2f012a480c23301315c03a34012a4804a340120b803a37012a4804a37", - "0x3600952402403c6300e26004a9201201e3100700ea480480703001d16009", - "0x4a920128dc0482c00e8f404a920128f40480c00e8ac04a9201201e32007", - "0x486c0126cc03898012a48048980126cc03a34012a4804a340120b803a37", - "0x14c6600e8bc04a920128bc04c6500e8ac04a920128ac049b300e1b004a92", - "0x4e0095240604e8098ce01c4e89b4528a8082920128bd1586c1308d11ba3d", - "0x4a9201201c1000700ea480489c0131a0038075240240381800e26804d68", - "0x11500901801c518095240251380930401d138095240251402a03062403a28", - "0xcd8071360254900913602417007452025490094520241600745402549009", - "0x150090fa01c03a9201201c0c00714626d14a2a0200245180952402451809", - "0x482c00e8a804a920128a80480c00e29404a920122680499c00e01d49009", - "0x48a5012a48048a501266c0389b012a480489b0120b803a29012a4804a29", - "0x150090fa01c03a920128b0049d100e01d4900900e060038a51368a515010", - "0x48a2012a04038a2012a48048070b201c5200952402403a8300e01d49009", - "0xc27e00e89404a9201201d3f80744c025490091442900c28000e28804a92", - "0x11e8095240251e80901801c568095240245580933801c5580952402513225", - "0x14900915a024cd807468025490094680241700746e0254900946e02416007", - "0x3807524024150090fa01c03a9201201c0c00715a8d11ba3d02002456809", - "0x4a920122a80499c00e2a804a920128c0560184fc01c5600952402403a7f", - "0x4a310120b803a32012a4804a320120b003a3d012a4804a3d01203003a23", - "0x14900900e06003a234628c91e81001288c04a9201288c0499b00e8c404a92", - "0x3a920120a80487d00e01d4900909a024b900700ea48048490125c803807", - "0x149009166024ce007166025490094e48880c27e00e88804a9201201d3f807", - "0x13a00905c01d3a8095240253a80905801ce2009524024e200901801c5a809", - "0x480703001c5aa744ea7100800916a0254900916a024cd8074e802549009", - "0x14900909a024b900700ea48048490125c8038075240242b0093a201c03a92", - "0x590095240240385900e2d004a9201201d4180700ea480482a0121f403807", - "0x14900900e9fc03a21012a48048b2168061400071640254900916402540807", - "0x480c00e2e804a920122ec0499c00e2ec04a92012884600184fc01c60009", - "0x3852012a48048520120b803851012a48048510120b0039c4012a48049c4", - "0x497200e01d4900900e060038ba0a4144e20100122e804a920122e80499b", - "0x48074fe01c03a920120a80487d00e01d4900909a024b900700ea4804849", - "0x600718802549009184024ce007184025490090b28800c27e00e88004a92", - "0xd8095240240d80905c01cfa009524024fa00905801ce2009524024e2009", - "0x11800700ea480480703001c6201b3e87100800918802549009188024cd807", - "0x398f00e87804a9201201d4180700ea480482a0121f40380752402424009", - "0x3a1c012a4804a1d43c0614000743a0254900943a0254080743a02549009", - "0x4a9201231c0499c00e31c04a920128710d8184fc01d0d80952402403a7f", - "0x4a7b0120b803a7e012a4804a7e0120b0039c4012a48049c4012030038c9", - "0x14900900e060038c94f69f8e201001232404a920123240499b00e9ec04a92", - "0x630095240240380000e32004a9201201d4180700ea480482a0121f403807", - "0x14900900e9fc03a1a012a48048c61900614000718c0254900918c02540807", - "0x480c00e33804a9201233c0499c00e33c04a920128690c0184fc01d0c009", - "0x3a7b012a4804a7b0120b803a7e012a4804a7e0120b003839012a4804839", - "0x487d00e01d4900900e060038ce4f69f81c81001233804a920123380499b", - "0xce0070560254900904a8580c27e00e85804a9201201d3f80700ea480482a", - "0x138095240241380905801c038095240240380901801c6980952402415809", - "0x6982604e01c080091a6025490091a6024cd80704c0254900904c02417007", - "0xc0070500a40c5690280300c2920300240381801201c03a9201201c3c007", - "0x3825012a48048260124cc0382604e061490090200241c80700ea4804807", - "0xf0095240240f00906e01c128095240241280906e01c0f00952402403c69", - "0x38075240240381800e1800e818ad407c100185240600f0250180aa35007", - "0x235807040025490090400240600700ea480480702001c03a9201207c04849", - "0x14900950e0241480700ea480480703001d43009ad6a1c3c01852406013809", - "0x14200904a01d418095240243c00909001d420095240254280904e01d42809", - "0x4a9201201c1000700ea480480703001c03d6c01201c0f00750402549009", - "0x4a8001209403a83012a4804a8601212003a80012a4804a8101207c03a81", - "0x23580700ea480480703001d3f009ada9fc04a92030a080481d00ea0804a92", - "0x1490090580241480700ea480480703001c17009adc0b13d81852406141809", - "0x2f80904a01cd70095240253d80909001c2f8095240241680904e01c16809", - "0x4a9201201c1000700ea480480703001c03d6f01201c0f00706602549009", - "0x49b8012094039ae012a480482e012120039b8012a480483201207c03832", - "0x23580700ea480480703001c1b809ae006804a920300cc0481d00e0cc04a92", - "0x1490090740241480700ea480480703001c1c809ae20e8e2018524060d7009", - "0xb80904a01c21009524024e200909001c0b809524024e400904e01ce4009", - "0x4a9201201c1000700ea480480703001c03d7201201c0f00709802549009", - "0x484901209403842012a480483901212003849012a480484801207c03848", - "0x5680700ea480480703001ce8809ae613404a920301300481d00e13004a92", - "0x14900900e060038510135d003a9203014004a3300e1402681852402426809", - "0x39f40135d42a052030a480c27f0400602f00700ea480484d012a1003807", - "0xe40070b206c0c2920121080483900e01d4900900e1e00380752402403818", - "0x3852012a480485201203003a06012a480485901205c038075240240d809", - "0x480703001d3aa640ae0aabb05e0aa158152920308180d0540300500606b", - "0x48560120b003a74012a4804852012030038075240242f0090a401c03a92", - "0x14900900e06003807aee0240381e00e9c404a920121540482e00e9c804a92", - "0x1490094ea9c00c27e00e9c004a9201201d3f80700ea480482a0121f403807", - "0x2b80905801c290095240242900901801d35809524025378098d801d37809", - "0x80094d6025490094d6025500074c8025490094c8024170070ae02549009", - "0x149009084024e400700ea48048070f001c03a9201201c0c0074d69902b852", - "0x3700952402403a8300e01d490090340254200700ea480482a0121f403807", - "0x1490094d41b80c28000e9a804a920129a804a8100e9a804a9201201c2c807", - "0x1340098d801d340095240253486b0309f80386b012a48048074fe01d34809", - "0x1700702802549009028024160073e8025490093e8024060074ce02549009", - "0xc0074ce0600a1f4020025338095240253380954001c0c0095240240c009", - "0x2681845001c340095240240381b00e01d490090a20251800700ea4804807", - "0x4d7800ea480c2660128cc03a66012a4804a66012a0403a66012a4804868", - "0xc007526026bc86f0c4061490184fe0800c24100e01d4900900e06003a65", - "0x49c800e981308185240242100907201c03a9201201c3c00700ea4804807", - "0x11f8070c4025490090c4024060074be025490094c00240b80700ea4804a61", - "0x14900900e06003a594b496c1557a4b89752f02a5240612f81a0de0600a00c", - "0x1490094bc024160074b0025490090c40240600700ea4804a5c01214803807", - "0x3a9201201c0c00700f5ec0480703c01d2b0095240252e80905c01d2b809", - "0x4a920129652a8184fc01d2a80952402403a7f00e01d490090540243e807", - "0x4a5b0120b003862012a480486201203003861012a4804a530131b003a53", - "0x3101001218404a9201218404aa000e96804a920129680482e00e96c04a92", - "0x3a92012108049c800e01d4900900e1e0038075240240381800e1852d25b", - "0x3877012a480480750601c03a9201206804a8400e01d490090540243e807", - "0x4a920121e83b81850001c3d0095240243d00950201c3d00952402403859", - "0x4a510131b003a51012a4804a520fa0613f0070fa0254900900e9fc03a52", - "0x482e00e05004a920120500482c00ea4c04a92012a4c0480c00e1ec04a92", - "0x381800e1ec0c0145260400487b012a480487b012a8003818012a4804818", - "0x14900900f1b4038075240253f80950801c03a9201299404a3000e01d49009", - "0x14080749a025490094a093c0c22800e93c0d0185240240d00915a01d28009", - "0x3a9201201c0c00748a026be0075240612680946601d2680952402526809", - "0x3820012a4804820012030038075240240d00950801c03a9201201c3c007", - "0x4a920121080484800e06004a920120600482e00e05004a920120500482c", - "0x43a4148491c0800910e90521247020a48048420540600a02001829403842", - "0x23700700ea4804842012720038075240252280946001c03a9201201c0c007", - "0x11e8095240251e80950201d1e8095240251f81a0308a003a3f012a4804807", - "0x3a9201201c3c00700ea480480703001d1e009afa01d4901847a02519807", - "0x3a3a012a480480744c01c4580952402403a8300e01d490090540243e807", - "0x4a9201201d3f8074700254900947422c0c28000e8e804a920128e804a81", - "0x1000901801d1b809524024480098d801c480095240251c08c0309f80388c", - "0x1500070300254900903002417007028025490090280241600704002549009", - "0x48070f001c03a9201201c0c00746e0600a0200200251b8095240251b809", - "0x48140120b003a58012a4804820012030038075240251e00946001c03a92", - "0x49f000e9d004a920129600486d00e95804a920120600482e00e95c04a92", - "0x2380074680254900900e7d003a71012a4804a560131bc03a72012a4804a57", - "0x4a920128c804aa000e8c804a920128cc04c7100e8cc04a920128d015018", - "0x49d100e01d4900900e1e0038075240240381800e8c938a724e804004a32", - "0xd00950801c03a920120a80487d00e01d49009084024e400700ea48049d1", - "0x14900900e16403a31012a480480750601c03a920129fc04a8400e01d49009", - "0x3a7f00e8bc04a920128c11881850001d180095240251800950201d18009", - "0x386c012a48048980131b003898012a4804a2f4580613f00745802549009", - "0x4a920120600482e00e05004a920120500482c00e08004a920120800480c", - "0x38075240240381800e1b00c0140400400486c012a480486c012a8003818", - "0x49c800e01d490090540243e80700ea48048370127440380752402403878", - "0x48070b201d1580952402403a8300e01d490094fe0254200700ea48049ae", - "0x13f807452025490094548ac0c28000e8a804a920128a804a8100e8a804a92", - "0x4e0095240244e8098d801c4e8095240251489b0309f80389b012a4804807", - "0x1490090300241700702802549009028024160070400254900904002406007", - "0x3a9201201c0c0071380600a0200200244e0095240244e00954001c0c009", - "0xe400700ea480482a0121f4038075240253f0093a201c03a9201201c3c007", - "0x4a8100e8a004a9201201c2c8071340254900900ea0c0380752402541809", - "0x38a3012a48048074fe01d138095240251409a030a0003a28012a4804a28", - "0x149009040024060071480254900914a0263600714a0254900944e28c0c27e", - "0x5200954001c0c0095240240c00905c01c0a0095240240a00905801c10009", - "0x1490090c00242480700ea480480703001c520180280800800914802549009", - "0x5100952402403a8300e01d490090540243e80700ea480482701272003807", - "0x14900944c2880c28000e89804a9201289804a8100e89804a9201201e39007", - "0x568098d801c56809524025128ab0309f8038ab012a48048074fe01d12809", - "0x17007028025490090280241600703a0254900903a0240600715802549009", - "0xc0071580600a01d020024560095240245600954001c0c0095240240c009", - "0x480750601c03a920120a80487d00e01d49009020024e400700ea4804807", - "0x5501850001d118095240251180950201d118095240240384d00e2a804a92", - "0x38b5012a4804a221660613f0071660254900900e9fc03a22012a4804a23", - "0x4a920120a00482c00e0a404a920120a40480c00e2d004a920122d404c6c", - "0xc028052040048b4012a48048b4012a8003818012a48048180120b803828", - "0x3829028062bf00c0200614901801201c0c00900e01d4900900e1e0038b4", - "0x80095240240800901801c1402a030a480482a0122b40380752402403818", - "0x1490090300243e80700ea480480703001c13809afe01d4901805002519807", - "0x1280952402403c7300e09804a9201201d4180700ea480482a012a1003807", - "0x14900900e9fc0381e012a480482504c0614000704a0254900904a02540807", - "0x480c00e07404a9201207c0499c00e07c04a92012078100184fc01c10009", - "0x481d012a480481d01266c0380c012a480480c0120b003810012a4804810", - "0x14900900e06c038075240241380946001c03a9201201c0c00703a0300802a", - "0x482c00e04004a920120400480c00e1e004a920121801501845001c30009", - "0x1490090f00600601002089403878012a4804878012a040380c012a480480c", - "0x3a920120a804a8400e01d4900900e06003a8550ca1c1500950aa194382a", - "0x3a83012a480480709a01d4200952402403a8300e01d490090300243e807", - "0x4a9201201d3f80750402549009506a100c28000ea0c04a92012a0c04a81", - "0xa00901801d3f8095240254000933801d40009524025412810309f803a81", - "0x150094fe025490094fe024cd807052025490090520241600702802549009", - "0xa018b000300801852406004807030024038075240240387800e9fc14814", - "0x149009020024060070500a80c2920120a8048ad00e01d4900900e06003829", - "0x1500950801c03a9201201c0c00704e026c08075240601400946601c08009", - "0x498200e09404a920120980c01831201c130095240240382000e01d49009", - "0x380c012a480480c0120b003810012a48048100120300381e012a4804825", - "0x1380946001c03a9201201c0c00703c0300802a01207804a920120780499b", - "0x480c00e07c04a920120801501845001c100095240240381b00e01d49009", - "0x381f012a480481f012a040380c012a480480c0120b003810012a4804810", - "0x14900900e060038780c0074150090f01800e82a5240240f818018040080ab", - "0x14380952402403a8300e01d490090300243e80700ea480482a012a1003807", - "0x14900950ca1c0c28000ea1804a92012a1804a8100ea1804a9201201c26807", - "0x14180933801d4180952402542a840309f803a84012a48048074fe01d42809", - "0xcd8070520254900905202416007028025490090280240600750402549009", - "0x140098ea01c1400952402403c7400ea08148140540254100952402541009", - "0x23c00700ea48048260131dc0382504c0614900904e0263b00704e02549009", - "0x60185240240600915a01c100095240240f00905001c0f00952402412809", - "0x1408070c00740c29201207c100180551e403820012a4804820012a040381f", - "0x14900950e0263d80750e1e00c292012180038188f401c3000952402430009", - "0x1420098fc01c03a92012a1404c7d00ea1142818524025430098f801d43009", - "0x3a815040614900950402640007504025490095060255100750602549009", - "0x13f8185240253f80937001d3f8095240240383200ea0004a92012a0404a1a", - "0x48780120300381d012a480481d01288c03a7e012a4804a7e0120dc03a7e", - "0x39ae0be0b41558205c0b13d82a5240614027e0540240803a00e1e004a92", - "0x3832012a4804833504062418070660254900900f2040380752402403818", - "0x4a920120c8048cf00e9fc04a920129fc0483700e9ec04a920129ec0482c", - "0x1b81a3700a9490180649fc1627b0200e80382e012a480482e012a0403832", - "0xe40098ea01ce400952402403c7400e01d4900900e0600383907471015583", - "0x23c00700ea48048420131dc0384c0840614900902e0263b00702e02549009", - "0x248095240242480950201c248095240242400905001c2400952402426009", - "0xc47a00e74404a9201274404a8100e744268185240240604903a0aa3c807", - "0x1490090a40250d0070a41440c29201214404c8000e14428018524024e8878", - "0xd80937001c0d8095240240383200e7d004a920120501701843001c2a009", - "0x3859012a48048590120dc039b8012a48049b80120b00385903606149009", - "0x4a9201213404a2300e0dc04a920120dc04a8100e7d004a920127d004a81", - "0x2b206030a480c1f40a81640d1b801871003850012a48048500120300384d", - "0x2881890601d3200952402403c8100e01d4900900e060038570bc15415584", - "0x1030095240250300905801d3a0095240241483703086003a75012a4804a64", - "0x1490094e8025408074ea025490094ea02467807036025490090360241b807", - "0xc0074d69bd3802ab0a9c5390185240613a2750361590300c38801d3a009", - "0xc10074d4025490090dc0400c18900e1b804a9201201c1000700ea4804807", - "0x1390095240253900905801c280095240242800901801d3480952402535009", - "0x1490094d2024cd8074e2025490094e20241700709a0254900909a02511807", - "0x3a920120400487d00e01d4900900e06003a694e21353905001802534809", - "0x1490094d6024240074d0025490094de024170070d6025490094e002416007", - "0x3807524024080090fa01c03a9201201c0c00700f6180480703c01d33809", - "0x14200700ea480481b012124038075240241b80950801c03a9201214404c84", - "0x3a68012a480485e0120b80386b012a48048550120b00380752402414809", - "0x4a9201299c340184fc01c3400952402403a7f00e99c04a9201215c04848", - "0x486b0120b003850012a480485001203003a65012a4804a6601267003a66", - "0x499b00e9a004a920129a00482e00e13404a9201213404a2300e1ac04a92", - "0xa00950801c03a9201201c0c0074ca9a02686b0a003004a65012a4804a65", - "0x480c012a10038075240241700950801c03a920120400487d00e01d49009", - "0x483a0120b803862012a48049c40120b0038075240241480950801c03a92", - "0x14900900e06003807b0e0240381e00ea4c04a920120e40484800e1bc04a92", - "0x3a920129fc0484900e01d490090200243e80700ea4804814012a1003807", - "0x38075240254100990801c03a920120a404a8400e01d4900901802542007", - "0x4a920126b80484800e1bc04a9201217c0482e00e18804a920120b40482c", - "0x4a6001267003a60012a4804a934c20613f0074c20254900900e9fc03a93", - "0x4a2300e18804a920121880482c00e1e004a920121e00480c00e97c04a92", - "0x4a5f012a4804a5f01266c0386f012a480486f0120b80381d012a480481d", - "0x150185240600c00902801c0c0095240240480905401d2f86f03a1883c00c", - "0xa00905001c0a0095240240800905201c03a9201201c0c007018026c4010", - "0x1280704e0254900905402413007050025490090520241380705202549009", - "0x480704001c03a9201201c0c00700f6240480703c01c1300952402414009", - "0x482500e09c04a920120300482600e07804a920120940481f00e09404a92", - "0x3a9201201c0c00703e026c5020012a480c02601207403826012a480481e", - "0x300090ae01c03a9201201c0c0070f0026c586003a0614901804e0240a007", - "0xf00750a0254900950e0253200750c0254900903a0241300750e02549009", - "0x4a840129d403a84012a480480704001c03a9201201c0c00700f63004807", - "0x4a7400ea1404a92012a0c04a6400ea1804a920121e00482600ea0c04a92", - "0x1400095240254100905201c03a9201201c0c007502026c6a82012a480c285", - "0xc27f00e0607a8074fe025490094fe025408074fe0254900950002414007", - "0x4a920129f80480c00e01d4900900e0600382d05c0b01558e4f69f80c292", - "0x485700e01d4900900e0600383301363cd705f030a480c28601205003a7e", - "0x381a012a4804832012990039b8012a480485f01209803832012a48049ae", - "0x1b8094ea01c1b8095240240382000e01d4900900e06003807b200240381e", - "0x13a0070340254900938802532007370025490090660241300738802549009", - "0x4a920120e80482900e01d4900900e060038390136441d0095240600d009", - "0xba7e0303d403817012a4804817012a0403817012a48049c80120a0039c8", - "0x484c4f60624280700ea480480703001c268490900aac904c08406149018", - "0x482600e14404a920121080480c00e14004a9201274404c8600e74404a92", - "0x381800e01ec980900e07803854012a480485001322003852012a48049b8", - "0x4a7b012808038075240242680940401c03a9201212404a0200e01d49009", - "0x3a9201201c0c00700f6500480703c01cfa0095240242400901801c03a92", - "0xfa0095240253f00901801c03a920129ec04a0200e01d49009072024e8807", - "0x4a920127d00486d00e16404a9201206c04c8900e06c04a9201201c10007", - "0x2c980900e07803854012a480485901322003852012a48049b801209803851", - "0x38075240241680940401c03a920120b804a0200e01d4900900e06003807", - "0x49d100e01d4900900e06003807b2a0240381e00e81804a920120b00480c", - "0x4c8900e15804a9201201c1000740c0254900900e0240600700ea4804a81", - "0x3852012a4804a8601209803851012a4804a060121b403855012a4804856", - "0x4a9203015004aa100e17804a920121480481700e15004a9201215404c88", - "0x4c8b00e9d404a9201215c1001891401c03a9201201c0c0074c8026cb057", - "0x385e012a480485e0129c803851012a480485101203003a74012a4804a75", - "0x1000950801c03a9201201c0c0074e81782882a0129d004a920129d004c8d", - "0x4a7200e14404a920121440480c00e9c804a9201299004c8e00e01d49009", - "0x480703001d3905e0a20a804a72012a4804a720132340385e012a480485e", - "0x380901801d380095240240f80991c01d388095240241380902e01c03a92", - "0x150094e0025490094e0026468074e2025490094e20253900700e02549009", - "0x4c7500e09c04a9201201e3a0070500a40c292012050048ba00e9c138807", - "0x3807524024128098ee01c0f025030a48048260131d803826012a4804827", - "0xc2920120a4048ad00e07c04a920120800482800e08004a9201207804c78", - "0x38780c00614900903a07c1502a8f201c0f8095240240f80950201c0e829", - "0x4a860131ec03a8650e061490090f001c0c47a00e1e004a920121e004a81", - "0x4c7e00e01d490095080263e807506a100c292012a1404c7c00ea1404a92", - "0x140281030a4804a8101320003a81012a4804a82012a8803a82012a4804a83", - "0xc2920129f8049b800e9f804a9201201c190074fe025490095000250d007", - "0x14380901801c300095240243000944601d3d8095240253d80906e01d3da7e", - "0x199ae0be0aacb82d05c0b0152920309fd3d8100120401d00750e02549009", - "0xdc0095240241928103120c03832012a480480790201c03a9201201c0c007", - "0x149009370024678074fc025490094fc0241b8070580254900905802416007", - "0x1b81a054a480c1b84fc0b81601007401c168095240241680950201cdc009", - "0x17007034025490090340241600700ea480480703001ce40390740aacc1c4", - "0xc2920300b5438181ea01ce2009524024e200950201c1b8095240241b809", - "0x26818524060e20170303d4038075240240381800e1242404c05566421017", - "0x39f40a8061490090500246100700ea480480703001c290510a00aacd1d1", - "0x4a0200e01d490090b2025010070ac8182c81b020a48048540840601548f", - "0x2f010524024fa1d10360aa478070aa0254900940c0250f00700ea4804856", - "0x4a64012878038075240253a80940401c03a9201215c04a0200e9d532057", - "0x1388098ec01d38809524025390098ea01d3900952402403c7400e9d004a92", - "0x140074d6025490094de0263c00700ea4804a700131dc03a6f4e006149009", - "0x1490090521b83002a8f201c370095240243700950201c3700952402535809", - "0x3a680d6061490094d21340c47a00e9a404a920129a404a8100e9a535018", - "0x4a9201201c190070d0025490094ce0250d0074ce9a00c2920129a004c80", - "0x2a80950201d328095240253280906e01d32a66030a4804a660126e003a66", - "0x1118074e8025490094e8025408070bc025490090bc0244e8070aa02549009", - "0x2a8684ca0dc0d00c38801c358095240243580901801d3500952402535009", - "0x4a9201201e4080700ea480480703001d302615260aacd86f0c406149018", - "0x13300906e01c310095240243100905801d2f0095240252fa6803120c03a5f", - "0x1490184e89793306f0c4030e20074bc025490094bc024678074cc02549009", - "0x3a58012a480480704001c03a9201201c0c0074b29692d82ab389712e818", - "0x1490090d6024060074ac025490094ae024c10074ae025490094b00300c189", - "0x13500944601c2f0095240242f00913a01d2e8095240252e80905801c35809", - "0xa0094ac025490094ac024cd8074b8025490094b8024170074d402549009", - "0x482c00e01d490090180243e80700ea480480703001d2b25c4d41792e86b", - "0x3861012a4804a5901212003a53012a4804a5a0120b803a55012a4804a5b", - "0x13a00950801c03a920120300487d00e01d4900900e06003807b3a0240381e", - "0x4a930120b0038075240253300909201c03a920129a004c8400e01d49009", - "0x3a7f00e18404a920129800484800e94c04a920129840482e00e95404a92", - "0x3a52012a480487a0126700387a012a48048610ee0613f0070ee02549009", - "0x4a920121780489d00e95404a920129540482c00e1ac04a920121ac0480c", - "0x4a5201266c03a53012a4804a530120b803a6a012a4804a6a01288c0385e", - "0x4851012808038075240240381800e94929a6a0bc9543581401294804a92", - "0x1490090500251000700ea480480c0121f4038075240242900940401c03a92", - "0x3e80952402403a8300e01d490090840250100700ea4804829012a1003807", - "0x1490094a21f40c28000e94404a9201294404a8100e94404a9201201c2c807", - "0x12780933801d278095240243da500309f803a50012a48048074fe01c3d809", - "0x4e80703402549009034024160070a0025490090a00240600749a02549009", - "0x1b8095240241b80905c01c300095240243000944601c0c0095240240c009", - "0x3a9201201c0c00749a0dc300180341400a00949a0254900949a024cd807", - "0x3807524024060090fa01c03a9201212404a0200e01d4900909002501007", - "0x14180700ea48049c4012a10038075240241480950801c03a920120a004a20", - "0x14000748e0254900948e0254080748e0254900900e16403a45012a4804807", - "0x4a92012909208184fc01d2080952402403a7f00e90804a9201291d22818", - "0x481a0120b00384c012a480484c01203003a3f012a480488701267003887", - "0x482e00e18004a9201218004a2300e06004a920120600489d00e06804a92", - "0x3a3f06e1800c01a09805004a3f012a4804a3f01266c03837012a4804837", - "0x4a2000e01d490090180243e80700ea480482d012a100380752402403818", - "0x482e00e8f404a920120e80482c00e01d490090520254200700ea4804828", - "0x381800e01ecf00900e0780388b012a48049c801212003a3c012a4804839", - "0x482801288003807524024060090fa01c03a920129f80484900e01d49009", - "0x1490090be0241600700ea4804a81013210038075240241480950801c03a92", - "0x48074fe01c458095240241980909001d1e009524024d700905c01d1e809", - "0x600711802549009470024ce007470025490091168e80c27e00e8e804a92", - "0xc0095240240c00913a01d1e8095240251e80905801d4380952402543809", - "0x149009118024cd80747802549009478024170070c0025490090c002511807", - "0x14900900f2480380c012a480480792201c4623c0c00611ea8702802446009", - "0x601892601c0a0095240240a00950201c060095240240600950201c0a009", - "0x3829012a4804829013250038075240240381800e01ecf829012a480c014", - "0x3826012a480480792e01c1380952402403c9600e0a004a920120a404c95", - "0x14901804c09c0c49300e09804a9201209804a8100e09c04a9201209c04a81", - "0x1280992a01c128095240241280992801c03a9201201c0c00700f68012809", - "0x4da100ea480c0200132640382003c0614900903c0264c00703c02549009", - "0x4a9201207804c9a00e07404a9201202404a1c00e01d4900900e0600381f", - "0x24d80700ea480481e012a7c038075240240381800e01ed100900e07803860", - "0x24e80750e0254900950e0254080750e0254900900f27003878012a4804807", - "0x14300943801d428095240254280993c01d42a86030a480481f50e1e004810", - "0x24a80700ea480480703001c03da35080254901850a0264f80750c02549009", - "0x300095240254180993401c0e8095240254300943801d4180952402542009", - "0x4a1c00ea0804a9201201e5000700ea480480703001c03da201201c0f007", - "0x140860030a480486001326003860012a4804a820132680381d012a4804a86", - "0x1490090c00254f80700ea480480703001d40009b4801d490185020264c807", - "0x38075240240381800e01ed280900e07803a7f012a480482801326803807", - "0x3a92012a0004ca100e01d4900900e06003a7e01369803a920300a004c99", - "0x14f80700ea480480703001c03da501201c0f0074fe025490090c00264d007", - "0x382c012a4804a804f6062510074f60254900900f26c0380752402430009", - "0x14900905c0264f00705c025490094fc0b00c4a200e0b004a920120b004c9e", - "0x1680992a01c03a9201201c0c00700f69c168095240601700993e01c17009", - "0x480703001c03da501201c0f0074fe025490090be0264d0070be02549009", - "0xc27f01326403a7f012a48049ae013268039ae012a480480794001c03a92", - "0x480750601c03a920120400487d00e01d4900900e060038330136a003a92", - "0x1901850001cdc009524024dc00950201cdc0095240240385900e0c804a92", - "0x39c4012a480481a06e0613f00706e0254900900e9fc0381a012a48049b8", - "0x4a9201207404a1c00e01c04a9201201c0480c00e0e804a920127100499c", - "0x483a01266c0382a012a480482a0120b803818012a48048180120b00381d", - "0x1490090660265180700ea480480703001c1d02a0300740380c0120e804a92", - "0x4a1a00e1080b8185240240b80990001c0b80952402403ca400e7201c818", - "0x384909006149009090024dc0070900254900900e0c80384c012a4804842", - "0x26049054060061c400e13004a92012130048cf00e12404a9201212404837", - "0x14900900f204038075240240381800e148288500556a4e884d030a480c039", - "0x482c00e7d004a920121500b81890601c0b8095240240b80994a01c2a009", - "0x39f4012a48049f401233c03848012a48048480120dc0384d012a480484d", - "0x14900900e060038550ac818155aa0b206c0c292030720fa0483a2134061c4", - "0x485701260803857012a480485e020060c48070bc0254900900e08003807", - "0x482c00e07404a9201207404a1c00e01c04a9201201c0480c00e99004a92", - "0x4a64012a4804a6401266c03859012a48048590120b80381b012a480481b", - "0x482c00e01d490090200243e80700ea480480703001d320590360740380c", - "0x3a72012a480485501212003a74012a48048560120b803a75012a4804a06", - "0xe400950801c03a920120400487d00e01d4900900e06003807b560240381e", - "0x48500120b0038075240242400909201c03a9201205c04c8400e01d49009", - "0x3a7f00e9c804a920121480484800e9d004a920121440482e00e9d404a92", - "0x3a6f012a4804a7001267003a70012a4804a724e20613f0074e202549009", - "0x4a920129d40482c00e07404a9201207404a1c00e01c04a9201201c0480c", - "0x13a81d00e03004a6f012a4804a6f01266c03a74012a4804a740120b803a75", - "0x3a920120a004a9f00e01d490090200243e80700ea480480703001d37a74", - "0x370095240243700950201c370095240240385900e9ac04a9201201d41807", - "0x4a6a4d20613f0074d20254900900e9fc03a6a012a480486e4d606140007", - "0x4a1c00e01c04a9201201c0480c00e9a004a920121ac0499c00e1ac04a92", - "0x382a012a480482a0120b803818012a48048180120b003809012a4804809", - "0x3e80700ea480480703001d3402a0300240380c0129a004a920129a00499b", - "0x4a8100e1a004a9201201c2c8074ce0254900900ea0c0380752402408009", - "0x3a65012a48048074fe01d3300952402434267030a0003868012a4804868", - "0x14900900e024060070de025490090c4024ce0070c4025490094cc9940c27e", - "0x1500905c01c0c0095240240c00905801c048095240240480943801c03809", - "0xc11700e1bc1501801201c060090de025490090de024cd80705402549009", - "0x491900e01d4900900e0600382504c09c155ac0500a40a02a52406015009", - "0xf820018a480481e0127d40381e012a480482801246c03828012a4804828", - "0x48600121b8038075240240e8090dc01c03a9201208004ca600e1e03001d", - "0x481f0124980381f012a480481f0127b0038075240243c00950801c03a92", - "0x1428098ec01d42809524025430098ea01d4300952402403c7400ea1c04a92", - "0x14007504025490095060263c00700ea4804a840131dc03a8350806149009", - "0x4a92012a0404a8100ea00060185240240600915a01d4080952402541009", - "0x23d0074fc025490094fc025408074fc9fc0c292012a01408180551e403a81", - "0x14900905c0263e00705c025490090580263d8070589ec0c2920129f803818", - "0xd700954401cd70095240242f8098fc01c03a920120b404c7d00e17c16818", - "0x39b8012a480483201286803832066061490090660264000706602549009", - "0x4a920120500482c00e0dc0d0185240240d00937001c0d00952402403832", - "0x4a7f01288c03a87012a4804a870121ec03837012a48048370120dc03814", - "0xe202a524060dc0370520500803a00e9ec04a920129ec0480c00e9fc04a92", - "0x2418070980254900900f204038075240240381800e1080b9c80556b41c83a", - "0x4a920120680483700e71004a920127100482c00e12004a9201213019818", - "0x1d1c40200e803839012a4804839012a0403848012a480484801233c0381a", - "0x492b00e01d4900900e060038520a2140155ae3a21342482a5240602401a", - "0x4854012a1003a724e89d5320570bc1542b2060b206cfa054040a4804a87", - "0x14900940c0254200700ea480481b01280803807524024fa0090dc01c03a92", - "0x3a920121780491000e01d490090aa0254200700ea4804856012a1003807", - "0x38075240253a80909201c03a920129900485200e01d490090ae02501007", - "0x988074e20254900900e0c803807524025390090a401c03a920129d004849", - "0x4a920129c40483700e9bc04a920129c00482a00e9c02c8185240242c809", - "0x49d1012a040384d012a480484d0120b803849012a48048490120b003a71", - "0x14900900e06003a6a0136bc3726b030a480c2714de9ec1519100e74404a92", - "0x14900900f29c03a69012a480486e0120a40386e012a480486e01263803807", - "0x13480950201c358095240243580906e01d340095240242c80905401c35809", - "0x480703001d33009b601a13381852406035a684d60a8c88074d202549009", - "0x48078e801d328095240243400905201c340095240243400931c01c03a92", - "0x23b8074c2a4c0c2920121bc04c7600e1bc04a9201218804c7500e18804a92", - "0x3a5f012a4804a600120a003a60012a4804a610131e00380752402549809", - "0x12e80950201d2ea5e030a480480c4be9fc1547900e97c04a9201297c04a81", - "0x12d8185240252d80990001d2da5c030a4804a5d4ce0623d0074ba02549009", - "0x12c03903086003a58012a4804a690120a003a59012a4804a5a01286803a5a", - "0x1b8074aa9580c292012958049b800e95804a9201201c190074ae02549009", - "0x1328095240253280950201d2b8095240252b80950201d2a8095240252a809", - "0x12a84d092030e20074b8025490094b8024060074bc025490094bc02511807", - "0x480790201c03a9201201c0c0074a41e83b82ab62185298185240612ba59", - "0x10c0070f6025490094ca024140074a2025490090fa96c0c48300e1f404a92", - "0x4a920129580483700e94c04a9201294c0482c00e94004a920121ece8818", - "0x30a5301871003a50012a4804a50012a0403a51012a4804a5101233c03a56", - "0x382000e01d4900900e06003a4248e914155b249a93c0c29203094128a56", - "0x3a3f012a480488701260803887012a4804a41020060c480748202549009", - "0x4a9201297804a2300e93c04a9201293c0482c00e97004a920129700480c", - "0x12f24f4b803004a3f012a4804a3f01266c03a4d012a4804a4d0120b803a5e", - "0x4a920129140482c00e01d490090200243e80700ea480480703001d1fa4d", - "0x2d980900e0780388b012a4804a4201212003a3c012a4804a470120b803a3d", - "0x38075240252d80990801c03a920120400487d00e01d4900900e06003807", - "0x1600700ea48049d1012a10038075240252b00909201c03a9201299404a84", - "0x458095240252900909001d1e0095240243d00905c01d1e8095240243b809", - "0x149009470024ce007470025490091168e80c27e00e8e804a9201201d3f807", - "0x12f00944601d1e8095240251e80905801d2e0095240252e00901801c46009", - "0x600911802549009118024cd80747802549009478024170074bc02549009", - "0x80090fa01c03a920120e404a8400e01d4900900e0600388c4789791ea5c", - "0x49d1012a10038075240253480950801c03a9201203004a8400e01d49009", - "0x14900946e0254080746e0254900900e00003890012a480480750601c03a92", - "0x1198184fc01d1980952402403a7f00e8d004a920128dc4801850001d1b809", - "0x3a66012a4804a6601203003a31012a4804a3201267003a32012a4804a34", - "0x4a920121340482e00e9fc04a920129fc04a2300e12404a920121240482c", - "0x3a9201201c0c0074621353f8494cc03004a31012a4804a3101266c0384d", - "0x38075240240600950801c03a920120400487d00e01d4900907202542007", - "0x74600254900900ea0c03807524024e880950801c03a9201216404852", - "0x11600952402517a30030a0003a2f012a4804a2f012a0403a2f012a4804807", - "0x1490090d8024ce0070d8025490094582600c27e00e26004a9201201d3f807", - "0x13f80944601c248095240242480905801d350095240253500901801d15809", - "0x600945602549009456024cd80709a0254900909a024170074fe02549009", - "0x80090fa01c03a920120e404a8400e01d4900900e06003a2b09a9fc24a6a", - "0x48500120b003807524025438090c201c03a9201203004a8400e01d49009", - "0x381e00e26c04a920121480484800e8a404a920121440482e00e8a804a92", - "0x1490090200243e80700ea480481a012124038075240240381800e01eda009", - "0x3a920120cc04c8400e01d4900950e0243080700ea480480c012a1003807", - "0x149009084024240074520254900902e024170074540254900939002416007", - "0x4e00933801c4e0095240244d89d0309f80389d012a48048074fe01c4d809", - "0x11180745402549009454024160074f6025490094f60240600713402549009", - "0x4d0095240244d00933601d148095240251480905c01d3f8095240253f809", - "0x14200700ea48048100121f4038075240240381800e26914a7f4549ec06009", - "0x3a27012a48048254500613f0074500254900900e9fc0380752402406009", - "0x4a9201209c0482c00e01c04a9201201c0480c00e28c04a9201289c0499c", - "0x48a301266c03826012a48048260120b803818012a480481801288c03827", - "0xc00902801c0c0095240240480905401c5182603009c0380c01228c04a92", - "0xa009524024080090ae01c03a9201201c0c007018026da81005406149018", - "0x3db601201c0f00705002549009028025320070520254900905402413007", - "0x3826012a48048270129d403827012a480480704001c03a9201201c0c007", - "0xc2920120a404a1200e0a004a9201209804a6400e0a404a9201203004826", - "0x381f0136dc10009524060140094e801c0f0095240241280902e01c12829", - "0x3860012a480481d0120a00381d012a48048200120a40380752402403818", - "0xc00750c026dc2870f0061490180c001c0c1fe00e18004a9201218004a81", - "0x1480942401d428095240240383200e01d4900903c0242900700ea4804807", - "0x1428095240254280906e01d41a87030a4804a870126e003a8405206149009", - "0x38075240240381800ea0004db9502a080c292030a0d42a840f004254007", - "0x14900950e024dc0074fc025490094fe024998074fe0a40c2920120a404a12", - "0x1546a00ea0404a92012a040482600e9f804a920129f80483700e9ed43818", - "0x1601095001c03a9201201c0c0070be0b40c5ba05c0b00c2920309ed3f282", - "0x4a8101205c038075240240381800e0c804dbb0666b80c2920300b943829", - "0xc4aa00e0dc04a920120cc0481700e06804a920126e004ca900e6e004a92", - "0xd7009524024d700901801c1d009524024e200953201ce20095240240d037", - "0x14080950e01c03a9201201c0c0070746b80c0090740254900907402655807", - "0x49c8012a04039c8012a480480700001c1c80952402403a8300e01d49009", - "0xc27e00e10804a9201201d3f80702e025490093900e40c28000e72004a92", - "0x190095240241900901801c240095240242600995801c260095240240b842", - "0x2f80909201c03a9201201c0c0070900c80c0090900254900909002655807", - "0x4a87012124038075240241480950e01c03a92012a0404a8700e01d49009", - "0x14900909a0254080709a0254900900f2b803849012a480480750601c03a92", - "0x280184fc01c2800952402403a7f00e74404a920121342481850001c26809", - "0x382d012a480482d01203003852012a48048510132b003851012a48049d1", - "0x4a87012124038075240240381800e1481681801214804a9201214804cab", - "0x4a9201201c000070a80254900900ea0c038075240241480950e01c03a92", - "0x48074fe01c0d809524024fa054030a00039f4012a48049f4012a04039f4", - "0x60070ac0254900940c0265600740c025490090361640c27e00e16404a92", - "0x480703001c2b2800300242b0095240242b00995601d4000952402540009", - "0x1490090aa026578070aa0254900900e080038075240241480950e01c03a92", - "0x480c00e99004a9201215c04a9900e15c04a920121780f01895401c2f009", - "0x14900900e06003a6450c06004a64012a4804a640132ac03a86012a4804a86", - "0x13a8095240240382000e01d490090520254380700ea480481f01274403807", - "0x4a72012a6403a72012a4804a7403c062550074e8025490094ea02657807", - "0x38180129c404a920129c404cab00e01c04a9201201c0480c00e9c404a92", - "0x3828052062de0140180614901801201c0c00900e01d4900900e1e003a71", - "0x60095240240600901801c13810030a48048100122b40380752402403818", - "0x1490090200254200700ea480480703001c13009b7a01d4901804e02519807", - "0xf00996601c0f009524024128180312c803825012a480482a0132c403807", - "0x25a0070280254900902802416007018025490090180240600704002549009", - "0x48260128c0038075240240381800e0800a00c0540241000952402410009", - "0x601896a01c0c0095240240c0094e401c060095240240600901801c03a92", - "0x480703001d43809b7c1e004a9203018004cb600e1800e81f054a4804818", - "0x801845001d428095240240381b00ea1804a920121e01501896e01c03a92", - "0x3814012a48048140120b00381f012a480481f01203003a84012a4804a85", - "0x4a92012a1004a8100ea1804a92012a1804a0400e07404a9201207404a72", - "0xc007502a094182a012a0541283054a4804a8450c0740a01f01882403a84", - "0x14380997001c03a920120a8048f900e01d490090200254200700ea4804807", - "0x3a7e012a4804a7f0132cc03a7f012a4804a8003a0625900750002549009", - "0x4a920129f804cb400e05004a920120500482c00e07c04a9201207c0480c", - "0x48f900e01d490090200254200700ea480480703001d3f01403e0a804a7e", - "0x480709a01d3d80952402403a8300e01d490090300242900700ea480482a", - "0x13f80705c025490090589ec0c28000e0b004a920120b004a8100e0b004a92", - "0xd70095240242f80997201c2f8095240241702d0309f80382d012a4804807", - "0x14900935c0265a00705002549009050024160070520254900905202406007", - "0x801852406004807030024038075240240387800e6b814029054024d7009", - "0x381000e0a004a920120600482a00e01d4900900e06003829028062df80c", - "0x4dc004c09c0c2920300a00481400e04004a920120400480c00e01d49009", - "0x4a9201209c0482600e07804a920120980485700e01d4900900e06003825", - "0x38075240240381800e01ee080900e0780381f012a480481e01299003820", - "0x100095240241280904c01c300095240240e8094ea01c0e80952402403820", - "0x14901803e0253a0070f0025490090400240b80703e025490090c002532007", - "0x482a00ea1404a92012a1c0482900e01d4900900e06003a8601370943809", - "0x141283030a480c28401205003a85012a4804a85012a0403a84012a480482a", - "0x4a8301209803a80012a4804a8201215c038075240240381800ea0404dc3", - "0x14900900e06003807b880240381e00e9f804a92012a0004a6400e9fc04a92", - "0x14900950202413007058025490094f60253a8074f60254900900e08003807", - "0x382d013714170095240613f0094e801d3f009524024160094c801d3f809", - "0x39ae012a4804a7f01205c0385f012a480482e0120a40380752402403818", - "0x4a920120c804a8100e0c804a9201217c0482800e0cc04a92012a1404828", - "0xdc00946601cdc009524024dc00950201cdc009524024190330308a003832", - "0x800901801c03a9201201c3c00700ea480480703001c0d009b8c01d49018", - "0x1390070f0025490090f002539007018025490090180241600702002549009", - "0x1b82a0120e8e2037054a48049ae0f0030080103c801cd7009524024d7009", - "0x38075240240d00946001c03a9201201c3c00700ea480480703001c1d1c4", - "0x1490093906b83c02a97401ce40095240241c80945e01c1c80952402403820", - "0x600905801c080095240240800901801c210095240240b80997601c0b809", - "0x14900900e0600384201804015009084025490090840265e00701802549009", - "0x38075240254280950801c03a920120b4049d100e01d4900900e1e003807", - "0x2c8070980254900900ea0c038075240253f80950e01c03a920121e004852", - "0x248095240242404c030a0003848012a4804848012a0403848012a4804807", - "0x1490093a20265e8073a2025490090921340c27e00e13404a9201201d3f807", - "0x2800997801c060095240240600905801c080095240240800901801c28009", - "0x38075240240387800e01d4900900e06003850018040150090a002549009", - "0x3852012a48048510128c803851012a480480704001c03a92012a18049d1", - "0x4810012030039f4012a48048540132ec03854012a48048520541e0154ba", - "0x802a0127d004a920127d004cbc00e03004a920120300482c00e04004a92", - "0x3a920120600485200e01d490090540242900700ea480480703001cfa00c", - "0x2c8095240242c80950201c2c8095240240384d00e06c04a9201201d41807", - "0x4a060ac0613f0070ac0254900900e9fc03a06012a480485903606140007", - "0x482c00e05004a920120500480c00e17804a9201215404cbd00e15404a92", - "0x48070f001c2f0290280a80485e012a480485e0132f003829012a4804829", - "0x3a9201201c0c0070520500c5c70180400c2920300240381801201c03a92", - "0x80095240240800901801c03a9201201c08007050025490090300249e807", - "0x1300997c01c03a9201201c0c00704a026e402604e061490180500254b007", - "0xf00703e0254900903c026600070400254900904e0265f80703c02549009", - "0x481d0133040381d012a480480704001c03a9201201c0c00700f72404807", - "0x48f800e07c04a9201218004cc000e08004a9201209404cbf00e18004a92", - "0x3a9201201c0c00750c026e5287012a480c01f012a5403878012a4804820", - "0x14900950a02661807508025490090540249e80750a0254900950e02661007", - "0x25f00700ea480480703001d40809b96a09418185240614200952c01d42809", - "0x13f0095240254000998001d3f8095240254180997e01d4000952402541009", - "0x4cc100e9ec04a9201201c1000700ea480480703001c03dcc01201c0f007", - "0x3a7e012a480482c01330003a7f012a4804a810132fc0382c012a4804a7b", - "0x14900905c0266100700ea480480703001c16809b9a0b804a920309f804a95", - "0x4cc500e0cd428185240254280998801cd70095240253f8091f001c2f809", - "0x38075240240d00940401c03a920126e004a6500e068dc032054a4804833", - "0xc29201217c04cc400e17c04a9201217c04cc300e0dc04a920120c804828", - "0x4a0200e01d49009072025328073900e41d02a524024e200998a01ce205f", - "0x3842012a480481706e0611400702e025490090740241400700ea48049c8", - "0x14900900e0600384c01373803a9203010804a3300e10804a9201210804a81", - "0x1420073a21342482a5240242400998a01c24285030a4804a8501331003807", - "0x2620070a00254900909a0246a80700ea48049d10128080380752402424809", - "0x4852012a10039f40a81481529201214404cc500e1442f8185240242f809", - "0xd8500303500381b012a480485401235403807524024fa00940401c03a92", - "0x14280998c01c03a9201217c04cc600e01d4900900e06003807b9e01d49018", - "0x15292012a1404cc500e01d4900900e06003807ba00240381e00e01d49009", - "0x485601231003807524025030094ca01c03a9201216404a8400e15903059", - "0x13280700ea480485e012a1003a640ae1781529201217c04cc500e15404a92", - "0x2e88075240613a8550307a403a75012a4804a64012310038075240242b809", - "0x387800e01d4900900e06003807ba00240381e00e01d4900900e06003807", - "0x493f00e03004a920120300482c00e04004a920120400480c00e01d49009", - "0x14900935c1e006010020504039ae012a48049ae0124fc03878012a4804878", - "0x3a9201213004a3000e01d4900900e06003a714e49d0150094e29c93a02a", - "0x1000700ea48048070f001c03a92012a1404cc600e01d490090be02663007", - "0x4a920129bcd7078054a8c03a6f012a4804a700128bc03a70012a4804807", - "0x480c0120b003810012a48048100120300386e012a4804a6b01331c03a6b", - "0x3a9201201c0c0070dc0300802a0121b804a920121b804cc800e03004a92", - "0x26300700ea480487801244003807524024168093a201c03a9201201c3c007", - "0x385900e9a804a9201201d4180700ea4804a7f0133240380752402542809", - "0x386b012a4804a694d4061400074d2025490094d2025408074d202549009", - "0x4a9201299c04cca00e99c04a920121ad340184fc01d3400952402403a7f", - "0x48680133200380c012a480480c0120b003810012a480481001203003868", - "0xe880700ea48048070f001c03a9201201c0c0070d00300802a0121a004a92", - "0x1518074ca025490094cc025190074cc0254900900e0800380752402543009", - "0x149009020024060070de025490090c4026638070c4025490094ca0a83c02a", - "0x6010054024378095240243780999001c060095240240600905801c08009", - "0x38075240241500922001c03a920120600491000e01d4900900e0600386f", - "0x3a61012a4804a61012a0403a61012a480480709a01d4980952402403a83", - "0x1490094c097c0c27e00e97c04a9201201d3f8074c0025490094c2a4c0c280", - "0x1480905801c0a0095240240a00901801d2e8095240252f00999401d2f009", - "0x14900900e1e003a5d052050150094ba025490094ba0266400705202549009", - "0x38075240240381800e0a40a018ba4030080185240600480703002403807", - "0x3810012a4804810012030038075240240381000e0a004a9201206004ccb", - "0x4826013338038075240240381800e09404dd304c09c0c2920300a004ccd", - "0x381e00e07c04a9201207804cd100e08004a9201209c04cd000e07804a92", - "0x14900903a0266900703a0254900900e080038075240240381800e01eea009", - "0x100092c001c0f809524024300099a201c10009524024128099a001c30009", - "0x38075240240381800ea1804dd550e0254901803e026698070f002549009", - "0x4a920120400480c00ea1004a92012a1404a9400ea1404a92012a1c04cd4", - "0x1501005535403a84012a4804a840126cc0382a012a480482a0124b403810", - "0x14900900e06003a80013759408095240614100935401d41283030a4804a84", - "0x1490094fc024e88074fc9fc0c292012a04049a700e01d4900900e1e003807", - "0x48780126c00380c012a480480c0120b003a83012a4804a8301203003807", - "0x13d82a5240253f878018a0c081af00e9fc04a920129fc0492d00e1e004a92", - "0x49ac00e01d4900900e1e0038075240240381800e0b81627b0540241702c", - "0x16007506025490095060240600705a025490095000266b00700ea4804878", - "0x381800e0b40628305402416809524024168099ae01c0600952402406009", - "0x4a9201201c1000700ea4804a86012744038075240240387800e01d49009", - "0x480c00e0cc04a920126b804cd900e6b804a9201217c150780553600385f", - "0x4833012a480483301335c0380c012a480480c0120b003810012a4804810", - "0x482a0125a4038075240240c00935801c03a9201201c0c0070660300802a", - "0x149009370025408073700254900900e13403832012a480480750601c03a92", - "0x1b8184fc01c1b80952402403a7f00e06804a920126e01901850001cdc009", - "0x3814012a48048140120300383a012a48049c4013358039c4012a480481a", - "0x3c0070740a40a02a0120e804a920120e804cd700e0a404a920120a40482c", - "0x3829012a48048140133680381401806149009030024b380700ea4804807", - "0x14009524024140099b801c148095240241480906e01c1400952402403cdb", - "0x383200e01d4900904c0242480704a0981382a5240241402900e0aa6e807", - "0x480c00e080080185240240800937001c03a9201201c0800703c02549009", - "0x38075240240381800e01eeb8075240600f0200304d003827012a4804827", - "0x14901803e0740c13400e074080185240240800937001c0f80952402403ca7", - "0x149009020024dc0070c00254900900f378038075240240381800e01eec007", - "0x3c6900e01d4900900e06003807bb201d490180c01e00c13400e1e008018", - "0x2ed00752406143a860304d003a8602006149009020024dc00750e02549009", - "0x80185240240800937001d4280952402403cdf00e01d4900900e06003807", - "0x14900900f380038075240240381800e01eed80752406142a840304d003a84", - "0x3807bb801d49018506a080c13400ea08080185240240800937001d41809", - "0x3a8002006149009020024dc0075020254900900f3840380752402403818", - "0x13f80952402403ce200e01d4900900e06003807bba01d49018502a000c134", - "0x3a9201201c3c00700ea480480703001c03dde00ea480c27f0200609a007", - "0x3807524024150094ca01c03a920120940484900e01d49009018024b4807", - "0x3a7b012a4804a7b012a0403a7b012a48048079c601d3f00952402403a83", - "0x1490090580b80c27e00e0b804a9201201d3f807058025490094f69f80c280", - "0x480905801c138095240241380901801c2f809524024168099c801c16809", - "0x14900900e0600385f01209c150090be025490090be0267280701202549009", - "0x3ddf01201c0f0070660254900935c0253000735c0254900900f39803807", - "0x1300070640254900900f39c038075240240800909201c03a9201201c0c007", - "0xc00700f7800480703c01cdc009524024198091aa01c1980952402419009", - "0xd0094c001c0d00952402403ce800e01d490090200242480700ea4804807", - "0x480703001c03de101201c0f00706e025490093700246a80737002549009", - "0x149009388025300073880254900900f3a4038075240240800909201c03a92", - "0x3a9201201c0c00700f7880480703c01c1d0095240241b8091aa01c1b809", - "0x1d0095240241c8094c001c1c80952402403cea00e01d4900902002424807", - "0x2480700ea480480703001c03de301201c0f007390025490090740246a807", - "0x6a8073900254900902e0253000702e0254900900f3ac0380752402408009", - "0x800909201c03a9201201c0c00700f7900480703c01c21009524024e4009", - "0x2100942801c21009524024260094c001c2600952402403cec00e01d49009", - "0x38075240240381800e12404de500ea480c0480133b40384808406149009", - "0x4a6500e01d4900904a0242480700ea480480c0125a40380752402403878", - "0x48070b201c2680952402403a8300e01d490090540253280700ea4804842", - "0x13f8070a0025490093a21340c28000e74404a9201274404a8100e74404a92", - "0x2a009524024290099c801c29009524024280510309f803851012a4804807", - "0x1490090a802672807012025490090120241600704e0254900904e02406007", - "0x15292012124150270553b8038075240240381800e150048270540242a009", - "0x2f305640c061490180b2108fa02a1b801c03a9201206c04a6500e1640d9f4", - "0x485601298003857012a4804a06012030038075240240381800e1782a818", - "0x38075240240387800e01d4900900e06003807bce0240381e00e99004a92", - "0x14180700ea480482501212403807524024060092d201c03a9201217804a65", - "0x1400074e8025490094e8025408074e80254900900e36c03a75012a4804807", - "0x4a920129c9388184fc01d3880952402403a7f00e9c804a920129d13a818", - "0x48090120b003855012a480485501203003a6f012a4804a7001339003a70", - "0x3a9201201c0c0074de0242a82a0129bc04a920129bc04ce500e02404a92", - "0x3a6b012a48048071b401c03a920120400484900e01d4900905402532807", - "0x3700952402403cef00e99004a920129ac04a6000e15c04a9201209c0480c", - "0x381800e01ef40075240603726a0304d003a6a04a0614900904a024dc007", - "0x48079de01d348095240253200c030664038075240240387800e01d49009", - "0x1546a00e9a404a920129a40492d00e1ac04a920121ac0483700e1ac04a92", - "0x13400901801c03a9201201c0c0074cc1a00c5e94ce9a00c29203009435857", - "0x1b8074d2025490094d20249680701202549009012024160074d002549009", - "0x13282a0121bc31265054a4804a674d2025340109e001d3380952402533809", - "0x3a920129a40496900e01d490094cc0242480700ea480480703001c37862", - "0x1308095240253080950201d3080952402403cae00ea4c04a9201201d41807", - "0x4a604be0613f0074be0254900900e9fc03a60012a4804a6152606140007", - "0x482c00e1a004a920121a00480c00e97404a9201297804ce400e97804a92", - "0x480703001d2e8090d00a804a5d012a4804a5d01339403809012a4804809", - "0x12e00952402403cf200e01d4900904a0242480700ea48048070f001c03a92", - "0x12c818bd49692d8185240613225c0ae0a86e0074b8025490094b802530007", - "0x4a9201201c100074ae025490094b40300c19900e01d4900900e06003a58", - "0x12d80901801d298095240252a80954a01d2a8095240252b2570313cc03a56", - "0x150094a6025490094a60267280701202549009012024160074b602549009", - "0x149009018024b480700ea4804a58012994038075240240381800e94c04a5b", - "0x4a920121dc04a8100e1dc04a9201201c6d8070c20254900900ea0c03807", - "0x3d2520309f803a52012a48048074fe01c3d0095240243b861030a0003877", - "0x160074b2025490094b2024060074a2025490090fa026720070fa02549009", - "0x4c2300e94404a5905402528809524025288099ca01c0480952402404809", - "0x3829012a480480706401c0a009524024060099ea01c06010030a4804809", - "0xc0290500609a007028025490090280241b8070500a80c2920120a8049b8", - "0x482a0126e003827012a480480794e01c03a9201201c0c00700f7ac03a92", - "0x26f00700ea480480703001c03dec00ea480c02704c0609a00704c0a80c292", - "0x3a920300940f01826801c0f02a030a480482a0126e003825012a4804807", - "0xf80952402403cf700e08004a9201201e7b00700ea480480703001c03ded", - "0x4a9201207c0483700e18004a9201208004cdc00e07404a9201201e7c807", - "0x38075240240381800e01ef700900e07803a87012a480481d0120dc03878", - "0x26e0075080254900900f3ec03a85012a48048079f401d4300952402403aa6", - "0x1438095240254200906e01c3c0095240254280906e01c3000952402543009", - "0x14900950e024ee007504025490090f0024ee007506025490090c00267e007", - "0x3a80012a48048079fc01c03a9201201c0c00700f7bc0480703c01d40809", - "0x3a83012a4804a8001337003a7e012a4804807a0001d3f80952402403cff", - "0x4a8303001c154dd00ea0404a920129f80483700ea0804a920129fc04837", - "0x382d012a4804a8205c0628100700ea480482c0121240382e0589ec15292", - "0xc007066026f81ae0be0614901805a9ec0c50300e0b404a920120b404a60", - "0x381800e0dc0d018be26e019018524061409ae0be0aa8200700ea4804807", - "0x20f0070740254900906402406007388025490093700400c41d00e01d49009", - "0x1b80909201c03a9201201c0c00700f7c80480703c01c1c809524024e2009", - "0x4810013090038075240241500909201c03a920120500484900e01d49009", - "0x14900902e0254080702e0254900900f418039c8012a480480750601c03a92", - "0x260184fc01c2600952402403a7f00e10804a9201205ce401850001c0b809", - "0x381a012a480481a01203003849012a480484801341c03848012a4804842", - "0x4814012124038075240240381800e1240d01801212404a9201212404d09", - "0x1490095020242480700ea4804810013090038075240241500909201c03a92", - "0x4a9201274404a8100e74404a9201201e8500709a0254900900ea0c03807", - "0x280510309f803851012a48048074fe01c28009524024e884d030a00039d1", - "0x28480706602549009066024060070a8025490090a4026838070a402549009", - "0x1490090300242480700ea480480703001c2a0330300242a0095240242a009", - "0x49f40200620e8073e8025490093e80241b8073e80254900900eaa403807", - "0x4c2300e0e404a9201206c04c1e00e0e804a9201201c0480c00e06c04a92", - "0x3855012a480480794e01c2b009524025030099ea01d03059030a4804839", - "0xc0550ac0e81550400e15404a920121540483700e15804a9201215804837", - "0x3a74012a4804807a1601c03a9201201c0c0074ea9900c5f30ae1780c292", - "0x484900e9c138a72054a4804a740ae178154dd00e9d004a920129d004cdc", - "0x4a8100e9ac04a9201201e868074de025490094e00268600700ea4804a71", - "0x2c8095240242c80983c01c3700952402537a6b0308a003a6b012a4804a6b", - "0x14900900eaa803a6a012a480486e0b2062870070dc025490090dc02540807", - "0xc50300e1ac04a920121ac04a6000e1ac04a920129a40a018a0401d34809", - "0x4a9201201e8780700ea480480703001c34009be899d3401852406035a72", - "0x134018a0601d32809524025328094c001d328095240253302a03140803a66", - "0xc06f4ce1881550400e01d4900900e06003a930137d437862030a480c265", - "0x4a920129813501883a01c03a9201201c0c0074bc97c0c5f64c09840c292", - "0x4a5b01344403a5b012a4804a5c4ba062880074b80254900900e08003a5d", - "0x13081801296804a9201296804d0900e98404a920129840480c00e96804a92", - "0x38075240253500984801c03a920129780484900e01d4900900e06003a5a", - "0x3a58012a4804a58012a0403a58012a4804807a0c01d2c80952402403a83", - "0x1490094ae9580c27e00e95804a9201201d3f8074ae025490094b09640c280", - "0x129809a1201d2f8095240252f80901801d298095240252a809a0e01d2a809", - "0x38075240253500984801c03a9201201c0c0074a697c0c0094a602549009", - "0x1408070ee0254900900f42803861012a480480750601c03a9201299c04849", - "0x12900952402403a7f00e1e804a920121dc3081850001c3b8095240243b809", - "0x4a9301203003a51012a480487d01341c0387d012a480487a4a40613f007", - "0x38075240240381800e9454981801294404a9201294404d0900ea4c04a92", - "0x2850070f60254900900ea0c038075240241500909201c03a920129a804c24", - "0x1278095240252807b030a0003a50012a4804a50012a0403a50012a4804807", - "0x14900948a0268380748a0254900949e9340c27e00e93404a9201201d3f807", - "0x1238680300252380952402523809a1201c340095240243400901801d23809", - "0x2480700ea4804814012124038075240253a80909201c03a9201201c0c007", - "0x3d0600e90804a9201201d4180700ea48048590130900380752402415009", - "0x3887012a4804a4148406140007482025490094820254080748202549009", - "0x4a920128f404d0700e8f404a9201221d1f8184fc01d1f80952402403a7f", - "0x3a3c4c806004a3c012a4804a3c01342403a64012a4804a6401203003a3c", - "0x381800e0a014818bee05006018524060048070300240380752402403878", - "0x1380c03144c038075240240381000e09c04a920120a804d1200e01d49009", - "0x14900903c0268a00700ea480480703001c0f8200317e00f02504c0a949018", - "0xe809a2c01c3c00952402412809a2a01c300095240241300901801c0e809", - "0x4a9201201c1000700ea480480703001c03df901201c0f00750e02549009", - "0x481f01345403860012a480482001203003a85012a4804a8601345c03a86", - "0x4d1800ea1004a920121e004c2500ea1c04a92012a1404d1600e1e004a92", - "0x28c80700ea48048070f001c03a9201201c0c007504026fd283012a480c287", - "0x13d82abf69f93fa80054a480c2810200600a010a3401d4080952402541809", - "0x149009500024160070c0025490090c00240600700ea480480703001c1702c", - "0x13f00984e01d420095240254200984c01d3f8095240253f80905c01d40009", - "0x168100120ccd705f05a041490094fca113fa800c0032140074fc02549009", - "0x4a9201201d3f80700ea4804a840130a8038075240240381800e0ccd705f", - "0x3000901801c0d009524024dc009a3601cdc009524024170320309f803832", - "0x28e00705802549009058024170074f6025490094f6024160070c002549009", - "0x48070f001c03a9201201c0c0070340b13d8600200240d0095240240d009", - "0x1b8105080aa8e80706e0254900900e08003807524025410093a201c03a92", - "0x160070c0025490090c002406007074025490093880268f00738802549009", - "0x1d0095240241d009a3801c0c0095240240c00905c01c0a0095240240a009", - "0x4c2a00e01d490090200268f80700ea480480703001c1d01802818008009", - "0xe400950201ce40095240240384d00e0e404a9201201d4180700ea480482a", - "0x13f0070840254900900e9fc03817012a48049c80720614000739002549009", - "0x4a920120a40480c00e12004a9201213004d1b00e13004a9201205c21018", - "0x484801347003818012a48048180120b803828012a48048280120b003829", - "0xc29201203004d2100e01d4900900e1e0038480300a01481001212004a92", - "0x4c4300e01d4900904c0251600704c09c1402a52402414809a4401c1480c", - "0xe81f030a480482001310c03820012a480480786201c0f025030a4804828", - "0x1490090c0024d18070c00780c29201207804c4100e01d4900903e024b9007", - "0x49a300ea180e8185240240e80988201c03a92012a1c04a0200ea1c3c018", - "0x3a83012a4804878012310038075240254200940401d42285030a4804a86", - "0x14900900e06003807bf801d49018504a0c0c1e900ea0804a92012a14048c4", - "0x3807bfa0240381e00e01d4900903c024b900700ea480481d0125c803807", - "0x38075240254080940401d40281030a480481e01268c0380752402403818", - "0x4a92012a00048c400e01d490094fe025010074fc9fc0c292012074049a3", - "0x381800e01eff0075240601627b0307a40382c012a4804a7e01231003a7b", - "0x49a300e17c04a9201201e9200705a0b80c292012094049a300e01d49009", - "0xc2920120cc04d2500e0c81681852402416809a4a01c199ae030a480485f", - "0x2ff837034061490183700c80382a55801cdc009524024dc00933c01cdc033", - "0x1490090340240600700ea4804837012808038075240240381800e0e8e2018", - "0x138092e401c03a9201201c0c00700f80003a920300cc168183d201c0d009", - "0x48100125c80380752402406009a5201c03a9201205004d2700e01d49009", - "0x1490090340240600700ea480482e01280803807524024d700940401c03a92", - "0xd7009524024d700933c01c03a9201201c0c00700f8040480703c01c1c809", - "0x38075240240381800e13021018c0405ce4018524060d702e0340a956007", - "0x29480700ea480481401349c03807524024138092e401c03a9201205c04a02", - "0xf007072025490093900240600700ea48048100125c80380752402406009", - "0x4842012030038075240242600940401c03a9201201c0c00700f80404807", - "0x3a920120e804a0200e01d4900900e06003807c060240381e00e12004a92", - "0x38075240241700940401c03a920126b804a0200e01d4900905a02501007", - "0x248185240241380988601c24009524024e200901801c03a920120cc04a02", - "0x48500125c8038510a0061490093a2026218073a20254900900f0c40384d", - "0x1010073e81500c292012148049a300e148268185240242680988201c03a92", - "0x2c8185240240d80934601c0d851030a480485101310403807524024fa009", - "0x1490090b2024620070ac025490090a80246200700ea4804a0601280803a06", - "0x480703001c03e0400ea480c0550ac060f480700ea480480702001c2a809", - "0x3e0501201c0f00700ea480484d0125c803807524024288092e401c03a92", - "0x3a9201217804a0200e15c2f0185240242680934601c03a9201201c0c007", - "0x1490090ae0246200700ea4804a6401280803a754c8061490090a2024d1807", - "0xc00700f81803a920309c93a0183d201d390095240253a80918801d3a009", - "0x3d2400e9c1388185240242480934601c03a9201201c3c00700ea4804807", - "0x135270030a4804a700134940386e4d6061490094de024d18074de02549009", - "0x135048054ab003a69012a4804a6901267803a690dc061490090dc02692807", - "0x1490094d00250100700ea480480703001c3426703181d3406b030a480c269", - "0x381800e01f04007524060372700307a40386b012a480486b01203003807", - "0x48100125c80380752402406009a5201c03a9201205004d2700e01d49009", - "0x1490090d60240600700ea4804a71012808038075240253580940401c03a92", - "0x1358095240253580933c01c03a9201201c0c00700f8240480703c01d33009", - "0x38075240240381800ea4c37818c141893281852406135a710d60a956007", - "0xb900700ea480480c0134a4038075240240a009a4e01c03a9201218804a02", - "0x381800e01f0480900e07803a66012a4804a650120300380752402408009", - "0x480703c01d308095240243780901801c03a92012a4c04a0200e01d49009", - "0x3a920129c004a0200e01d490090d00250100700ea480480703001c03e0b", - "0x38075240243700940401c03a920129c404a0200e01d490094d602501007", - "0x4a920120a80482e00e02404a920120240482c00e98404a9201299c0480c", - "0x4a610194a80380c012a480480c012a7003810012a48048100126cc0382a", - "0x3a5b0138312e0095240612e809a5601d2ea5e4be980082920120300802a", - "0x306a59012a480c25a0130e003a5a012a4804a5c0134b00380752402403818", - "0x1490094be024160074c0025490094c00240600700ea480480703001d2c009", - "0x12c809a5a01d2f0095240252f00905c01c0c0095240240c00913a01d2f809", - "0x2978070c294d2aa564ae031490094b29780c25f4c0032970074b202549009", - "0x4a920121dc04aab00e01d4900900e0600387a0138383b80952406030809", - "0x4a520134c0038075240243e809a4e01d2887d030a48048140134c003a52", - "0x4d3100e93c04a9201294404d3100e01d490090f6026938074a01ec0c292", - "0x3a47012a4804a4d0120a003a45012a4804a4f0120a003a4d012a4804a50", - "0x1490184840251980748402549009484025408074840254900948e9140c228", - "0x48870134c803887012a480480704001c03a9201201c0c00748202707807", - "0x480c00e8f004a920128f404d3400e8f404a920128fc04d3300e8fc04a92", - "0x3a55012a4804a5501227403a56012a4804a560120b003a57012a4804a57", - "0x11e2534aa9592b80c0128f004a920128f004d3500e94c04a9201294c0482e", - "0x29b8071160254900900f4d8038075240252080946001c03a9201201c0c007", - "0x460095240251c009a6801d1c0095240251d009a6601d1d00952402445809", - "0x1490094aa0244e8074ac025490094ac024160074ae025490094ae02406007", - "0x12b2570180244600952402446009a6a01d298095240252980905c01d2a809", - "0x1490090f40255680700ea480481401349c038075240240381800e23129a55", - "0x12a80913a01d2b0095240252b00905801d2b8095240252b80901801c48009", - "0x6009120025490091200269a8074a6025490094a6024170074aa02549009", - "0xa009a4e01c03a92012960049d100e01d4900900e060038904a69552b257", - "0x4a34012a0403a34012a48048070b201d1b80952402403a8300e01d49009", - "0xc27e00e8c804a9201201d3f807466025490094688dc0c28000e8d004a92", - "0x1300095240253000901801d180095240251880955a01d1880952402519a32", - "0x1490094bc02417007030025490090300244e8074be025490094be02416007", - "0x14900900e06003a304bc0612fa600180251800952402518009a6a01d2f009", - "0x1490094c00240600745e025490094b60255680700ea480481401349c03807", - "0x12f00905c01c0c0095240240c00913a01d2f8095240252f80905801d30009", - "0x381800e8bd2f0184be9800600945e0254900945e0269a8074bc02549009", - "0x1490090180269480700ea480481401349c038075240240387800e01d49009", - "0x4a920121200480c00e01d49009092024b900700ea48048100125c803807", - "0x14900913002699807130025490094580269b8074580254900900f84003a66", - "0xc00913a01c048095240240480905801d1580952402436009a6801c36009", - "0x6009456025490094560269a807054025490090540241700703002549009", - "0xa009a4e01c03a9201209c0497200e01d4900900e06003a2b05406004a66", - "0x48250125c803807524024080092e401c03a9201203004d2900e01d49009", - "0x4a2a0134dc03a2a012a4804807c2001c1c8095240240380901801c03a92", - "0x482c00e27404a9201226c04d3400e26c04a920128a404d3300e8a404a92", - "0x382a012a480482a0120b803818012a480481801227403809012a4804809", - "0x80185240240800988201c4e82a0300241c80c01227404a9201227404d35", - "0x482601310c03826012a480480786201c13828030a480482901310c03829", - "0xd180704009c0c29201209c04c4100e01d4900904a024b900703c0940c292", - "0xf0185240240f00988201c03a9201207404a0200e0740f81852402410009", - "0x481f012310038075240254380940401d43878030a480486001268c03860", - "0x3807c2201d4901850aa180c1e900ea1404a920121e0048c400ea1804a92", - "0x381e00e01d4900904e024b900700ea480481e0125c80380752402403818", - "0x14200940401d41a84030a480482701268c038075240240381800e01f09009", - "0x48c400e01d4900950402501007502a080c292012078049a300e01d49009", - "0x3098075240613fa800307a403a7f012a4804a8101231003a80012a4804a83", - "0x4a9201201f0a0074f69f80c2920120a0049a300e01d4900900e06003807", - "0x4d2500e17d3d8185240253d809a4a01c1682e030a480482c01268c0382c", - "0x14901835c17c0382a55801cd7009524024d700933c01cd702d030a480482d", - "0x600700ea4804832012808038075240240381800e068dc018c2a0c819818", - "0x3a9201201c0c00700f85803a920300b53d8183d201c1980952402419809", - "0x3807524024150092e401c03a9201205004c5800e01d49009020024b9007", - "0x600700ea4804a7e012808038075240241700940401c03a9201203004972", - "0x1700933c01c03a9201201c0c00700f85c0480703c01c1b80952402419809", - "0x381800e7201c818c300e8e20185240601727e0660a95600705c02549009", - "0x481401316003807524024080092e401c03a920120e804a0200e01d49009", - "0x1490093880240600700ea480480c0125c803807524024150092e401c03a92", - "0x3807524024e400940401c03a9201201c0c00700f85c0480703c01c1b809", - "0x4a0200e01d4900900e06003807c320240381e00e05c04a920120e40480c", - "0x13f00940401c03a920120b804a0200e01d490094f60250100700ea480481a", - "0x600988201c0b809524024dc00901801c03a920120b404a0200e01d49009", - "0x3849012a480480786201c2404c030a480484201310c0384201806149009", - "0xc29201212004c4100e01d4900909a024b90073a21340c29201212404c43", - "0xe880988201c03a9201214804a0200e148288185240242800934601c28048", - "0x38075240240d80940401c0d9f4030a480485401268c038543a206149009", - "0x14901840c1640c1e900e81804a920127d0048c400e16404a92012144048c4", - "0x149009090024b900700ea48049d10125c8038075240240381800e01f0d007", - "0x2a856030a480484801268c038075240240381800e01f0d80900e07803807", - "0x1490090bc025010070ae1780c292012744049a300e01d490090ac02501007", - "0x13aa640307a403a75012a480485701231003a64012a480485501231003807", - "0x30a0074e49d00c292012130049a300e01d4900900e06003807c3801d49018", - "0x13901852402539009a4a01d37a70030a4804a7101268c03a71012a4804807", - "0xb82a55801c370095240243700933c01c3726f030a4804a6f01349403a6b", - "0x4a69012808038075240240381800e9a035818c3a9a5350185240603726b", - "0xc00700f87803a920309bd390183d201d350095240253500901801c03a92", - "0x480704001c03a920129d004a0200e01d490094e00250100700ea4804807", - "0x4a3100e99804a920129a80480c00e1a004a9201299c04a2f00e99c04a92", - "0x4a70012678038075240240381800e01f0f80900e07803a65012a4804868", - "0x480703001d30a9303188037862030a480c2704e89a8152ac00e9c004a92", - "0x1490094c0025178074c00254900900e080038075240243780940401c03a92", - "0x480703c01d328095240252f80946201d330095240243100901801d2f809", - "0x12f0095240240382000e01d490094c20250100700ea480480703001c03e1f", - "0x1490094ba025188074cc02549009526024060074ba025490094bc02519007", - "0x38075240253400940401c03a9201201c0c00700f87c0480703c01d32809", - "0x10100700ea4804a74012808038075240253800940401c03a920129c804a02", - "0x60074b6025490094b8025190074b80254900900e0800380752402537809", - "0xc00700f87c0480703c01d328095240252d80946201d3300952402435809", - "0x12d00945e01d2d0095240240382000e01d49009098024b900700ea4804807", - "0x4c0074ca025490094b2025188074cc0254900902e024060074b202549009", - "0x12b8095240612c00927001d2c0095240252c00946201d2c00952402532809", - "0x4a9201201f1100700ea4804a57012744038075240240381800e95804e21", - "0x13302ac4a01d2980952402529809c4801d29a55030a4804a5501388c03a55", - "0xc00748491d2282ac4c93527a500f69443ea520f41dc308265240612980c", - "0x4380952402527a4103189c03a41012a4804a4d0c20631380700ea4804807", - "0x11e818c4e01d1e8095240243da3f03189c03a3f012a4804a5010e06313807", - "0x4a9201294845818c4e01c458095240243ea3c03189c03a3c012a4804a51", - "0x11c00901801c460095240243b809c5001d1c0095240243d23a03189c03a3a", - "0x3890118061490091180262080705402549009054024d980747002549009", - "0x14900946e0271200746e9540c29201295404e2300e24004a92012240049b3", - "0x11a0095240251a00901801d19a34030a4804a371200a91c010c5201d1b809", - "0x488c0126cc03a32012a4804a320126cc03a320200614900902002620807", - "0x1188185240252a88c4648d00862900e95404a9201295404e2400e23004a92", - "0x4a920128bc049b300e8b004a9201201f1500745e0254900900eabc03a30", - "0x11586c1300a9490184588bc0c00902115003a2c012a4804a2c0126cc03a2f", - "0x482c00e8ac04a920128ac04a9e00e01d4900900e0600389b4528a81562b", - "0x31609d012a480c22b01315c0386c012a480486c0120b803898012a4804898", - "0x317227450268152920308cc4e86c1300431680700ea480480703001c4e009", - "0x1138098ca01c4d0095240244d00905801c03a9201201c0c0071482945182a", - "0x560ad1560ab17a2544c288152920308c00a2281340431680744e02549009", - "0x112809524025128098ca01c510095240245100905801c03a9201201c0c007", - "0x480703001c5a0b51660ab18a224462a81529203089513a2614404318007", - "0x5502a8bc01d11009524025110098ca01c550095240245500905801c03a92", - "0xb900700ea480480703001c612201740ab190bb1808845901052406111223", - "0x3807524024620092e401d0f0c4030a48048c001310c038075240245d809", - "0x4a92012878049b300e01d4900943a024b90074388740c29201204004c43", - "0x4a0200e324638185240250d80934601d0da1e030a4804a1e01310403a1e", - "0x10d0c6030a48048c801268c038c8438061490094380262080700ea48048c9", - "0x4a92012318048c400e86004a9201231c048c400e01d4900943402501007", - "0x67a180307a403a21012a4804a210120b8038b2012a48048b20120b0038cf", - "0x10f0092e401c03a920128700497200e01d4900900e06003807c6601d49018", - "0x10b00946201d0b0095240246700945e01c670095240240382000e01d49009", - "0x14900943c024d180700ea480480703001c03e3401201c0f00705602549009", - "0x4a0200e3550a0185240250e00934601c03a9201234c04a0200e85469818", - "0xf4807424025490091aa024620071a80254900942a0246200700ea4804a14", - "0x3a11012a480480704001c03a9201201c0c00700f8d403a920308486a018", - "0x3807c680240381e00e0ac04a9201236804a3100e36804a9201284404a2f", - "0x1188071b6025490091b8025190071b80254900900e0800380752402403818", - "0x1080095240246c80956001c6c80952402415809c6c01c158095240246d809", - "0x1490094420241700716402549009164024160074620254900946202406007", - "0x3a9201201c0c007420884592310200250800952402508009c6e01d10809", - "0x4a92012309078184fc01d0780952402403a7f00e01d49009020024b9007", - "0x48ba0120b003a31012a4804a31012030038e3012a4804a0e0138e003a0e", - "0x11881001238c04a9201238c04e3700e88004a920128800482e00e2e804a92", - "0x4a9201201d3f80700ea48048100125c8038075240240381800e38d100ba", - "0x11880901801d0580952402506009c7001d060095240245a0e20309f8038e2", - "0x31b80716a0254900916a02417007166025490091660241600746202549009", - "0x80092e401c03a9201201c0c0074162d459a310200250580952402505809", - "0x5620a0309f803a0a012a48048074fe01c03a9201289c04c5800e01d49009", - "0x1600746202549009462024060071d8025490091ea0271c0071ea02549009", - "0x7600952402476009c6e01c568095240245680905c01c5580952402455809", - "0x4c5800e01d49009020024b900700ea480480703001c760ad1568c408009", - "0x770184fc01c7700952402403a7f00e01d49009460024b900700ea4804814", - "0x3a31012a4804a31012030038f1012a48048f00138e0038f0012a48048a4", - "0x4a920123c404e3700e29404a920122940482e00e28c04a9201228c0482c", - "0xb900700ea480489c012744038075240240381800e3c4528a3462040048f1", - "0x497200e01d49009460024b900700ea48048140131600380752402408009", - "0x10380950201d038095240240385900e3cc04a9201201d4180700ea4804a33", - "0x3a09012a48048980120b003a04012a4804a071e60614000740e02549009", - "0x3807c720240381e00e3f004a920128100484800e3f404a920121b00482e", - "0x497200e01d490090280262c00700ea48048100125c80380752402403818", - "0x482e00e82404a920128a80482c00e01d49009466024b900700ea4804a30", - "0x13f0071f60254900900e9fc038fc012a480489b012120038fd012a4804a29", - "0x4a920128c40480c00e3e404a920123e804e3800e3e804a920123f07d818", - "0x48f90138dc038fd012a48048fd0120b803a09012a4804a090120b003a31", - "0x3a920120400497200e01d4900900e060038f91fa825188100123e404a92", - "0x38075240252a809c7401c03a920120a80497200e01d490090280262c007", - "0x14900900ea0c038f7012a4804a471f0063138071f0025490094849140c627", - "0x838f6030a0003907012a4804907012a0403907012a48048070b201c7b009", - "0x31c007400025490094048040c27e00e80404a9201201d3f80740402549009", - "0x48095240240480905801c7b8095240247b80901801cff80952402500009", - "0xff8180123dc080093fe025490093fe0271b8070300254900903002417007", - "0x22c00700ea48048100125c8038075240252b0093a201c03a9201201c0c007", - "0x480c00e01d49009018024b900700ea480482a0125c8038075240240a009", - "0x48100125c8038075240240381800e01f1d80900e078039fe012a4804a66", - "0x149009018024b900700ea480482a0125c8038075240240a0098b001c03a92", - "0x14900906e0243680706e0254900900e0240600700ea48048280125c803807", - "0x49fb0138d8039fb012a48049fc0128bc039fc012a480480704001cff009", - "0x482e00e02404a920120240482c00e7e404a920127e804ab000e7e804a92", - "0x482a00e7e40c0093fc040049f9012a48049f90138dc03818012a4804818", - "0x14900900e0600380c0138f00802a030a480c01801205003818012a4804809", - "0x482901209c03829012a48048140120a003814012a48048100120a403807", - "0x381e00e09804a920120a00482500e09c04a920120a80482600e0a004a92", - "0x14900904a0240f80704a0254900900e080038075240240381800e01f1e809", - "0x1300903a01c130095240240f00904a01c138095240240600904c01c0f009", - "0x3001d030a480c027012050038075240240381800e07c04e3e04002549018", - "0x481d01209803a87012a480486001215c038075240240381800e1e004e3f", - "0x14900900e06003807c800240381e00ea1404a92012a1c04a6400ea1804a92", - "0x1490090f002413007506025490095080253a8075080254900900e08003807", - "0x481700ea09430185240254300942401d42809524025418094c801d43009", - "0x3a9201201c0c0074fe02720a80012a480c2850129d003a81012a4804a82", - "0x1490094f6025408074f6025490094fc024140074fc0254900950002414807", - "0x38075240240381800e0b404e4205c0b00c2920309ec038184cc01d3d809", - "0x2f8185240614300902801c160095240241600901801c03a92012a0404852", - "0x2f80904c01c19009524024d70090ae01c03a9201201c0c007066027219ae", - "0x480703001c03e4401201c0f007034025490090640253200737002549009", - "0x4833012098039c4012a48048370129d403837012a480480704001c03a92", - "0x4a7400e0e804a920126e00481700e06804a9201271004a6400e6e004a92", - "0xb8095240241c80905201c03a9201201c0c00739002722839012a480c01a", - "0xc0420580607a80708402549009084025408070840254900902e02414007", - "0x484805c0801564700e01d4900900e060039d109a124156460901300c292", - "0x4a7200e13004a920121300480c00e14404a9201214004e4800e14004a92", - "0x480703001c2883a0980a804851012a48048510139240383a012a480483a", - "0x1490090400254200700ea48049d1012808038075240242680940401c03a92", - "0x3e4a01201c0f0070a4025490090920240600700ea480482e01299403807", - "0x13280700ea4804820012a1003807524024e40093a201c03a9201201c0c007", - "0x3258070a80254900900e08003852012a480482c0120300380752402417009", - "0xfa009524024fa009c9201c1d0095240241d0094e401cfa0095240242a009", - "0x14300950e01c03a9201208004a8400e01d4900900e060039f407414815009", - "0x14900900e06003807c980240381e00e06c04a920120b40480c00e01d49009", - "0x3a92012a1804a8700e01d490090400254200700ea4804a7f01274403807", - "0x4a9201216404e4b00e16404a9201201c100070360254900900e02406007", - "0x1032810360a804a06012a4804a0601392403a81012a4804a810129c803a06", - "0x2a8095240240f809c9601c2b0095240241380902e01c03a9201201c0c007", - "0x1490090aa027248070ac025490090ac0253900700e0254900900e02406007", - "0x4a9201201f268070200a80c292012060049a300e1542b0070540242a809", - "0x3828052050152920120301500705511c0380c012a480480c012a740380c", - "0x13818c9c01c03a9201201c0c00704a0272782604e061490180520500c64e", - "0x1490090400240c19900e01d4900900e0600381f0139401001e030a480c028", - "0x3c00953a01c3c00952402403e4d00e18004a920120980e81833201c0e809", - "0x1490090c00249680750aa194382a5240243c01003c0aa238070f002549009", - "0x38075240240381800ea0804e51506a100c292030a1943818c9c01c30009", - "0x3001833201c03a9201201c0c0074fe027292805020614901850aa100c64e", - "0x382c012a480480704001d3d80952402541a7e03066403a7e012a4804a80", - "0x1490095020240600705a0254900905c0255280705c025490090589ec0c4f3", - "0xb480700ea480480703001c16a8103002416809524024168099ca01d40809", - "0x385900e17c04a9201201d4180700ea4804a830129940380752402430009", - "0x3833012a48049ae0be0614000735c0254900935c0254080735c02549009", - "0x3807ca60240381e00e6e004a920120cc0484800e0c804a920129fc0480c", - "0x3a8300e01d4900950a0250100700ea48048600125a40380752402403818", - "0xc28000e0dc04a920120dc04a8100e0dc04a9201201c2c80703402549009", - "0xdc009524024e200909001c190095240254100901801ce20095240241b81a", - "0x14900907202672007072025490093700e80c27e00e0e804a9201201d3f807", - "0xe4032030024e4009524024e40099ca01c190095240241900901801ce4009", - "0x13280700ea48048090125a4038075240240800940401c03a9201201c0c007", - "0x4a8100e10804a9201201c2c80702e0254900900ea0c0380752402413009", - "0x240095240240f80901801c2600952402421017030a0003842012a4804842", - "0x10100700ea480480703001c03e5401201c0f0070920254900909802424007", - "0x3a8300e01d490090500250100700ea48048090125a40380752402408009", - "0xc28000e74404a9201274404a8100e74404a9201201c2c80709a02549009", - "0x248095240242800909001c240095240241280901801c28009524024e884d", - "0x1490090a4026720070a4025490090921440c27e00e14404a9201201d3f807", - "0x2a0480300242a0095240242a0099ca01c240095240242400901801c2a009", - "0xc0070520500c6550180400c2920300240381801201c03a9201201c3c007", - "0x600704e0a80c2920120a8049b800e0a004a9201201e5380700ea4804807", - "0x3a9201201c0c00700f95803a920300a01381826801c0800952402408009", - "0x14900904c0600c19900e09804a9201209804a6000e09804a9201201d49807", - "0x48250124b40381e012a480481e0120dc0381e012a480480794e01c12809", - "0x480703001c3001d03195c0f820030a480c01e0540401546a00e09404a92", - "0x1280925a01c060095240240600905801c100095240241000901801c03a92", - "0x1529201207c1280c0400427800703e0254900903e0241b80704a02549009", - "0x38075240243000909201c03a9201201c0c00750ca1c3c02a012a1943878", - "0x1408075080254900900f2b803a85012a480480750601c03a9201209404969", - "0x14100952402403a7f00ea0c04a92012a114281850001d4200952402542009", - "0x481d01203003a80012a4804a8101339003a81012a4804a835040613f007", - "0xe82a012a0004a92012a0004ce500e03004a920120300482c00e07404a92", - "0x13f80952402403cf200e01d490090540242480700ea480480703001d4000c", - "0x14900900e08003a7e012a4804a7f030060cc8074fe025490094fe02530007", - "0x480c00e0b804a920120b004aa500e0b004a920129ed3f0189e601d3d809", - "0x482e012a480482e0133940380c012a480480c0120b003810012a4804810", - "0x482a012124038075240240c0092d201c03a9201201c0c00705c0300802a", - "0x1490090be025408070be0254900900e1340382d012a480480750601c03a92", - "0x198184fc01c1980952402403a7f00e6b804a9201217c1681850001c2f809", - "0x3814012a4804814012030039b8012a480483201339003832012a48049ae", - "0x568073700a40a02a0126e004a920126e004ce500e0a404a920120a40482c", - "0x14900900e0600382a01396003a9203006004a3300e0600481852402404809", - "0x381800e01c0480900e0254900900e0260f00700ea4804809012a1003807", - "0x48100120dc03810012a480480706401c03a920120a804a3000e01d49009", - "0x48ad00e05004a9201201c0d8070180254900902001c0c41d00e04004a92", - "0x4a920120a004a8100e0a004a920120501481845001c14809030a4804809", - "0x381800e09c04e5900ea480c0280128cc0380c012a480480c01307803828", - "0x380c012024060095240240600983c01c03a9201202404a8400e01d49009", - "0x483700e09804a9201201c1900700ea48048270128c00380752402403818", - "0x381e012a48048072a401c128095240241300c03107403826012a4804826", - "0x481f012a040381f012a480481e040061140070400240c292012024048ad", - "0x381d01396803a9203007c04a3300e09404a9201209404c1e00e07c04a92", - "0x480904a0254900904a0260f00700ea4804809012a100380752402403818", - "0x3860012a480480706401c03a9201207404a3000e01d4900900e06003825", - "0x4a9201201f2d8070f0025490090c00940c41d00e18004a9201218004837", - "0x4a8100ea1404a92012a1d4301845001d43009030a48048090122b403a87", - "0x4e5c00ea480c2850128cc03878012a480487801307803a85012a4804a85", - "0x3c0095240243c00983c01c03a9201202404a8400e01d4900900e06003a84", - "0x4a9201201c1900700ea4804a840128c0038075240240381800e1e004809", - "0x4807cba01d410095240254187803107403a83012a4804a830120dc03a83", - "0x3a7f012a4804a81500061140075000240c292012024048ad00ea0404a92", - "0x3a920309fc04a3300ea0804a92012a0804c1e00e9fc04a920129fc04a81", - "0x1490095040260f00700ea4804809012a10038075240240381800e9f804e5e", - "0x480706401c03a920129f804a3000e01d4900900e06003a8201202541009", - "0x32f807058025490094f6a080c41d00e9ec04a920129ec0483700e9ec04a92", - "0x4a920120b81681845001c16809030a48048090122b40382e012a4804807", - "0xc05f0128cc0382c012a480482c0130780385f012a480485f012a040385f", - "0x1600983c01c03a9201202404a8400e01d4900900e060039ae01398003a92", - "0x1900700ea48049ae0128c0038075240240381800e0b00480905802549009", - "0x190095240241982c03107403833012a48048330120dc03833012a4804807", - "0x49b8034061140070340240c292012024048ad00e6e004a9201201f30807", - "0x4a3300e0c804a920120c804c1e00e0dc04a920120dc04a8100e0dc04a92", - "0x20f00700ea4804809012a10038075240240381800e71004e6200ea480c037", - "0x3a9201271004a3000e01d4900900e060038320120241900952402419009", - "0x1490090740c80c41d00e0e804a920120e80483700e0e804a9201201c19007", - "0xb81845001c0b809030a48048090122b4039c8012a4804807cc601c1c809", - "0x3839012a480483901307803842012a4804842012a0403842012a48049c8", - "0x3a9201202404a8400e01d4900900e0600384c01399003a9203010804a33", - "0x484c0128c0038075240240381800e0e404809072025490090720260f007", - "0x2403903107403848012a48048480120dc03848012a480480706401c03a92", - "0x1140073a20240c292012024048ad00e13404a9201201f3280709202549009", - "0x4a9201212404c1e00e14004a9201214004a8100e14004a92012134e8818", - "0x4809012a10038075240240381800e14404e6600ea480c0500128cc03849", - "0x4a3000e01d4900900e06003849012024248095240242480983c01c03a92", - "0xc41d00e14804a920121480483700e14804a9201201c1900700ea4804851", - "0xd809030a48048090122b4039f4012a4804807cce01c2a00952402429049", - "0x485401307803859012a4804859012a0403859012a48049f403606114007", - "0x4a8400e01d4900900e06003a060139a003a9203016404a3300e15004a92", - "0x38075240240381800e150048090a8025490090a80260f00700ea4804809", - "0x3856012a48048560120dc03856012a480480706401c03a9201281804a30", - "0xc292012024048ad00e17804a9201201f348070aa025490090ac1500c41d", - "0x4c1e00e99004a9201299004a8100e99004a920121782b81845001c2b809", - "0x38075240240381800e9d404e6a00ea480c2640128cc03855012a4804855", - "0x14900900e060038550120242a8095240242a80983c01c03a9201202404a84", - "0x4a920129d00483700e9d004a9201201c1900700ea4804a750128c003807", - "0x48090122b403a71012a4804807cd601d390095240253a05503107403a74", - "0x3a6f012a4804a6f012a0403a6f012a4804a714e0061140074e00240c292", - "0x14900900e06003a6b0139b003a920309bc04a3300e9c804a920129c804c1e", - "0x381800e9c8048094e4025490094e40260f00700ea4804809012a1003807", - "0x486e0120dc0386e012a480480706401c03a920129ac04a3000e01d49009", - "0x48ad00e9a404a9201201c648074d4025490090dc9c80c41d00e1b804a92", - "0x4a920129a004a8100e9a004a920129a43581845001c35809030a4804809", - "0x381800e99c04e6d00ea480c2680128cc03a6a012a4804a6a01307803a68", - "0x3a6a012025350095240253500983c01c03a9201202404a8400e01d49009", - "0x483700e1a004a9201201c1900700ea4804a670128c00380752402403818", - "0x3a65012a4804807cdc01d330095240243426a03107403868012a4804868", - "0x486f012a040386f012a4804a650c4061140070c40240c292012024048ad", - "0x3a930139bc03a920301bc04a3300e99804a9201299804c1e00e1bc04a92", - "0x48094cc025490094cc0260f00700ea4804809012a100380752402403818", - "0x3a61012a480480706401c03a92012a4c04a3000e01d4900900e06003a66", - "0x4a9201201f380074c0025490094c29980c41d00e98404a9201298404837", - "0x4a8100e97404a9201297d2f01845001d2f009030a48048090122b403a5f", - "0x4e7100ea480c25d0128cc03a60012a4804a6001307803a5d012a4804a5d", - "0x1300095240253000983c01c03a9201202404a8400e01d4900900e06003a5c", - "0x4a9201201c1900700ea4804a5c0128c0038075240240381800e98004809", - "0x48070a801d2d0095240252da6003107403a5b012a4804a5b0120dc03a5b", - "0x20f0074b0025490094b0025408074b0025490094b20240c22800e96404a92", - "0x3a9201201c0c0074ae027390075240612c00946601d2d0095240252d009", - "0x4a570128c0038075240240381800e968048094b4025490094b40260f007", - "0x12b25a03107403a56012a4804a560120dc03a56012a480480706401c03a92", - "0x1529201204004d2200e954048094aa025490094aa0260f0074aa02549009", - "0x152920300a414018012043398070500300c29201203004c4100e0a40a00c", - "0x128095240241280986e01c03a9201201c0c00703e0800f02ace809413027", - "0x14901804a0261c00704c0254900904c0241700704e0254900904e02416007", - "0x4807cec01c3c00952402403ab200e01d4900900e060038600139d40e809", - "0x843400ea1c04a92012a1c049b300e1e004a920121e0049b300ea1c04a92", - "0x38075240240381800ea05412830559dd4228550c0a94901850e1e013027", - "0x4a92012a140482e00ea1804a92012a180482c00ea1004a92012a1004c37", - "0x4807cf201c03a9201201c0c0074fe0273c280012a480c2840130e003a85", - "0x3128074f6025490094f6027120074f69f80c2920129f804e2300e9f804a92", - "0x1c83a3880ab3d0370346e01903335c17c1682e058099490184f60300382a", - "0x1490090347200c62700e72004a920120dc16018c4e01c03a9201201c0c007", - "0x313807098025490090641080c62700e10804a920126e00b818c4e01c0b809", - "0x485f092063138070920254900935c1200c62700e12004a920120cc26018", - "0x60070a00254900905c027140073a20254900905a1340c62700e13404a92", - "0x280185240242800988201c150095240241500936601ce8809524024e8809", - "0x29009c4801c2927e030a4804a7e01388c03851012a48048510126cc03851", - "0x4a9201201e920073e81500c2920121482882a3a2043148070a402549009", - "0x499e00e1542b018524024fa00934601d03059030a480481b01268c0381b", - "0xc0074ea9900c67b0ae1780c29203015503054054ab003a06012a4804a06", - "0x480c00e9c804a920129d004a2f00e9d004a9201201c1000700ea4804807", - "0x3a6f012a4804a720128c403a70012a480485701267803a71012a480485e", - "0x13580946401d358095240240382000e01d4900900e06003807cf80240381e", - "0x1188074e0025490094ea024cf0074e2025490094c8024060070dc02549009", - "0x1490180ac1653882a55801c2c8095240242c80933c01d3780952402437009", - "0x3a67012a4804a6a012030038075240240381800e9a035818cfa9a535018", - "0x4a920129bc04a3100e99804a920129c00499e00e1a004a920129a40499e", - "0xcf0070c40254900900e6f4038075240240381800e01f3f00900e07803a65", - "0x3a604c20633fa930de061490180c49c03582a55801c3100952402431009", - "0x3868012a4804a6801267803a67012a480486f0120300380752402403818", - "0x3807cfc0240381e00e99404a920129bc04a3100e99804a92012a4c0499e", - "0x4a3200e97c04a9201201c1000700ea4804a6f0128b00380752402403818", - "0x3868012a4804a6801267803a67012a4804a6101203003a5e012a4804a5f", - "0x4a920309940493800e99404a9201297804a3100e99804a920129800499e", - "0x4a67012030038075240252e8093a201c03a9201201c0c0074b80274025d", - "0x4e2400e14004a92012140049b300e05004a92012050049b300e99c04a92", - "0x1330680306d803a5a4b6061490094fc1400a2670218a403a7e012a4804a7e", - "0x152920309654028550c043408074b2025490094b2024d98074b202549009", - "0x12c0095240252c00905801c03a9201201c0c0070c294d2a82ad049592ba58", - "0x341a520f41dc152920309680ea574b0043408074ac025490094ac02696807", - "0x129009a5a01c3b8095240243b80905801c03a9201201c0c0070f69443e82a", - "0x12124748a0ab42a4d49e940152920309492b07a0ee043420074a402549009", - "0x4380952402520809d0e01d2080952402526809d0c01c03a9201201c0c007", - "0x1490094a0024160074b6025490094b60240600747e0254900910e02744007", - "0x12825b0200251f8095240251f809d1201d278095240252780905c01d28009", - "0x1490094848f40c27e00e8f404a9201201d3f80700ea480480703001d1fa4f", - "0x12280905801d2d8095240252d80901801c458095240251e00956201d1e009", - "0x8009116025490091160274480748e0254900948e0241700748a02549009", - "0x14900900e9fc038075240252b00987401c03a9201201c0c00711691d22a5b", - "0x480c00e23004a920128e004ab100e8e004a920121ed1d0184fc01d1d009", - "0x3a51012a4804a510120b80387d012a480487d0120b003a5b012a4804a5b", - "0x4c3a00e01d4900900e0600388c4a21f52d81001223004a9201223004e89", - "0x480184fc01c4800952402403a7f00e01d490094b4024b900700ea480481d", - "0x3a5b012a4804a5b01203003a34012a4804a37012ac403a37012a4804861", - "0x4a920128d004e8900e94c04a9201294c0482e00e95404a920129540482c", - "0x10100700ea4804a5c012744038075240240381800e8d129a554b604004a34", - "0x4c3a00e01d490094cc0250100700ea480481d0130e80380752402434009", - "0xa0092e401c03a920121400497200e01d490094fc0271d00700ea4804a80", - "0x4a32012a0403a32012a4804807d1401d1980952402403a8300e01d49009", - "0xc27e00e8c004a9201201d3f807462025490094648cc0c28000e8c804a92", - "0x1338095240253380901801d160095240251780956201d1780952402518a30", - "0x1490094580274480750a0254900950a0241700750c0254900950c02416007", - "0x3807524024150092e401c03a9201201c0c007458a154326702002516009", - "0x31d00700ea4804a800130e8038075240240a0092e401c03a9201207404c3a", - "0x4a920120e84c018c4e01c4c0095240241c9c403189c038075240253f009", - "0x4a920128a804a8100e8a804a9201201c2c8074560254900900ea0c0386c", - "0x11489b0309f80389b012a48048074fe01d148095240251522b030a0003a2a", - "0x160070d8025490090d8024060071380254900913a0255880713a02549009", - "0x4e0095240244e009d1201d428095240254280905c01d4300952402543009", - "0x497200e01d490094fe024e880700ea480480703001c4e28550c1b008009", - "0x60092e401c03a920120500497200e01d4900903a0261d00700ea480482a", - "0x4a28012a0403a28012a48048070b201c4d00952402403a8300e01d49009", - "0x170071460254900950c0241600744e025490094502680c28000e8a004a92", - "0xc00700fa2c0480703c01c520095240251380909001c5280952402542809", - "0xa0092e401c03a9201207404c3a00e01d49009054024b900700ea4804807", - "0x14100905c01c518095240254180905801c03a920120300497200e01d49009", - "0xc27e00e28804a9201201d3f807148025490095020242400714a02549009", - "0x38095240240380901801d128095240251300956201d13009524024520a2", - "0x14900944a0274480714a0254900914a024170071460254900914602416007", - "0x3807524024150092e401c03a9201201c0c00744a2945180702002512809", - "0x38ab012a4804860013a3003807524024060092e401c03a9201205004972", - "0x4a9201201c0480c00e2b004a920122b404e8800e2b404a920122ac04e87", - "0x48ac013a2403826012a48048260120b803827012a48048270120b003807", - "0x3a920120a80497200e01d4900900e060038ac04c09c038100122b004a92", - "0x38aa012a48048074fe01c03a920120500497200e01d49009018024b9007", - "0x14900900e0240600744402549009446025588074460254900903e2a80c27e", - "0x111009d1201c100095240241000905c01c0f0095240240f00905801c03809", - "0x14900900e7d803814012a4804807d1a01d1102003c01c0800944402549009", - "0x1490180200a80482a88401c03a9201201c3c00700ea48048070ac01c14009", - "0x482504c0634780700ea480480703001c0f82003c0ab4702504c0a413810", - "0x4e9200e01d490090c0027488070f01800c29201207404e9000e07404a92", - "0x3a86012a4804a87012acc03a87012a4804878013a4c03878012a4804878", - "0x38095240240380901801d42009524025430092c001d428095240240395c", - "0x149009508024d8007030025490090300244e80704e0254900904e02416007", - "0x669400e0a404a920120a4140183da01d428095240254280925a01d42009", - "0x380c012a480480c0280634a80750203141283020a4804a8550806013807", - "0x149009500024b200700ea480480703001d3f809d2ca0004a92030a04049b4", - "0x480752601c03a920120b0049d100e01d490094fc024d60070589ed3f02a", - "0x14100905801d418095240254180901801c168095240240383200e0b804a92", - "0x1b80705c0254900905c025300074f6025490094f60249680750402549009", - "0xd50070666b82f82a5240241682e4f6a094180c35601c1680952402416809", - "0xc2920120c8049a700e01d4900900e060039b8013a5c1900952406019809", - "0xe20092d201c1d1c4030a480481a01259c038075240241b8093a201c1b81a", - "0xb9c8054a480c0390526b81516b00e0e404a920120e8049a500e01d49009", - "0x39d109a06149009084024d180700ea480480703001c248480980ab4c042", - "0x484d012678038510a0061490093a20300c69900e74404a920127440499e", - "0xcf0073e80254900900f118038540a40614900909a1400c69900e13404a92", - "0x1490093e81502f82a88e01cfa009524024fa00953a01c2a0095240242a009", - "0x4a1e00e15804a9201281804a1e00e01d490090b20250100740c1640d82a", - "0x3857012a480485e0ac062248070bc0254900900f12003855012a4804851", - "0x1490090aa15c0c21800e15404a9201215404a8100e15c04a9201215c04a81", - "0x13a009d3601d3a0095240253a809d3401d3a8095240253200989c01d32009", - "0x4e807390025490093900241600703602549009036024060074e402549009", - "0x13900952402539009d3801c0b8095240240b80905c01c2900952402429009", - "0x3a71012a480485f012030038075240240381800e9c80b85239006c06009", - "0x4a920121240484800e9bc04a920121200482e00e9c004a920121300482c", - "0x13506e030a48049b8013068038075240240381800e01f4e80900e07803a6b", - "0x4a920126b80482c00e9c404a9201217c0480c00e01d490090dc0260d807", - "0x34e80900e07803a6b012a4804a6a01212003a6f012a48048290120b803a70", - "0x1490094d20260d8070d69a40c2920129fc04c1a00e01d4900900e06003807", - "0x48290120b803a70012a4804a820120b003a71012a4804a8301203003807", - "0x1340184fc01d3400952402403a7f00e9ac04a920121ac0484800e9bc04a92", - "0x3a71012a4804a7101203003868012a4804a67013a7803a67012a4804a6b", - "0x4a920129bc0482e00e03004a920120300489d00e9c004a920129c00482c", - "0x3a9201201c0c0070d09bc062704e203004868012a4804868013a7003a6f", - "0x3a66012a48048074fe01c03a920120a0049c900e01d490090280274f807", - "0x14900900e024060070c4025490094ca0274f0074ca0254900903e9980c27e", - "0x1000905c01c0c0095240240c00913a01c0f0095240240f00905801c03809", - "0x49a300e1881001803c01c060090c4025490090c40274e00704002549009", - "0xc29201204004d2500e0a40a0185240240c00934601c06010030a4804809", - "0xf02504c0a94900904e0a00c6a000e09c0a0185240240a009a4a01c14010", - "0x8018d4001c0f829030a480482901349403820012a480481e00e06313807", - "0x3002650e0ab5080750e025490090f00800c62700e1e03001d054a480481f", - "0x141009524024039bb00e01d4900900e06003a835080635128550c06149018", - "0x149009504024cf0075000254900950a024cf0075020254900950c02406007", - "0x3a7e012a480480737a01c03a9201201c0c00700fa8c0480703c01d3f809", - "0x4a920129f80499e00ea0004a92012a0c0499e00ea0404a92012a100480c", - "0x382d05c0b0152920120513d818d4001d3d80c030a480480c01349403a7f", - "0x19018d480ccd7018524060172800be0ab508070be0254900905aa040c627", - "0x1b809524024d700901801c0d009524024039bb00e01d4900900e060039b8", - "0x3ea501201c0f00707402549009034024cf00738802549009066024cf007", - "0x3837012a480483201203003839012a480480737a01c03a9201201c0c007", - "0xc02c03a0dc156a100e0e804a920120e40499e00e71004a920126e00499e", - "0x3848012a480480737601c03a9201201c0c0070981080c6a602e7200c292", - "0x4a920121200499e00e13404a9201205c0499e00e12404a920127200480c", - "0x60070a00254900900e6f4038075240240381800e01f5380900e078039d1", - "0xe88095240242800933c01c268095240242600933c01c2480952402421009", - "0x3508073e8025490090a81240c62700e15029051054a480482901806350007", - "0x480c00e01d4900900e0600385640c06354059036061490183a2144fa02a", - "0x381800e01f5480900e0780385e012a480485901267803855012a480481b", - "0x156a100e17804a920121580499e00e15404a920128180480c00e01d49009", - "0x480737601c03a9201201c0c0074e89d40c6aa4c815c0c29203014826855", - "0x499e00e9c004a920129900499e00e9c404a9201215c0480c00e9c804a92", - "0x14900900e6f4038075240240381800e01f5580900e07803a6f012a4804a72", - "0x13580933c01d380095240253a00933c01d388095240253a80901801d35809", - "0x381800e1ad34818d589a8370185240613785e4e20ab508074de02549009", - "0x381e00e99c04a920129a80499e00e9a004a920121b80480c00e01d49009", - "0x486b01267803a68012a4804a69012030038075240240381800e01f56809", - "0x480703001c31265031ab933068030a480c03a4fe9a0156a100e99c04a92", - "0x480703c01d498095240253300933c01c378095240243400901801c03a92", - "0x1490090c4024cf0070de025490094ca0240600700ea480480703001c03eaf", - "0x14900900e06003a5e4be063582604c2061490185269c03782ad4201d49809", - "0x1490094c0024cf0074b8025490094c2024060074ba0254900900e6ec03807", - "0x3a9201201c0c00700fac40480703c01d2d0095240252e80933c01d2d809", - "0x4a920129780499e00e97004a9201297c0480c00e96404a9201201cde807", - "0xc6b24ae9600c29203096933a5c055a8403a5a012a4804a5901267803a5b", - "0x1490094ae024cf0074a6025490094b00240600700ea480480703001d2aa56", - "0x1298095240252b00901801c03a9201201c0c00700facc0480703c01c30809", - "0x4eb500e1dc04a920121852d9c404a0435a0070c2025490094aa024cf007", - "0x126a4f4a01ed2887d4a41e8142920120a83ba53055ad803877012a4804877", - "0x4a4f48a0631380748a0254900949a1e80c62700e01d490094a40275b807", - "0x3a41012a480487b48406313807484025490094a091c0c62700e91c04a92", - "0x1490090fa024d980710e0254900910e0240600710e025490094a29040c627", - "0xa00c030a480c00900e0600480700ea48048070f001c3e8870300243e809", - "0x480702001c138095240241500999601c03a9201201c0c0070500a40c6b8", - "0xf009d72094130185240601380999a01c060095240240600901801c03a92", - "0xf809524024130099a001c100095240241280999c01c03a9201201c0c007", - "0x1000700ea480480703001c03eba01201c0f00703a0254900904002668807", - "0x381f012a480481e01334003878012a480486001334803860012a4804807", - "0x4a9203007404cd300ea1c04a9201207c0496000e07404a920121e004cd1", - "0x14200952801d42009524025430099a801c03a9201201c0c00750a0275da86", - "0x96807030025490090300244e807018025490090180240600750602549009", - "0x4a8302006006010d7801d418095240254180936601c0800952402408009", - "0x3a9201201c0c0074fc0275ea7f012a480c2800126a803a80502a0815292", - "0x3a920120b0049d100e0b13d8185240253f80934e01c03a9201201c3c007", - "0x1490095020244e80702802549009028024160075040254900950402406007", - "0x14100cd2801d3d8095240253d80925a01d438095240254380936001d40809", - "0x14900900e060039ae0be0b4170100126b82f82d05c041490094f6a1d40814", - "0x198095240253f0099ac01c03a92012a1c049ac00e01d4900900e1e003807", - "0x1490095020244e80702802549009028024160075040254900950402406007", - "0x3a9201201c0c007066a040a28202002419809524024198099ae01d40809", - "0x26c0070640254900900e08003807524025428093a201c03a9201201c3c007", - "0x14900901802406007034025490093700266c807370025490090640414382a", - "0xd0099ae01c0c0095240240c00913a01c0a0095240240a00905801c06009", - "0x149009020024b480700ea480480703001c0d0180280300800903402549009", - "0xe20095240240384d00e0dc04a9201201d4180700ea480482a0126b003807", - "0x14900900e9fc0383a012a48049c406e061400073880254900938802540807", - "0x480c00e05c04a9201272004cd600e72004a920120e81c8184fc01c1c809", - "0x3818012a480481801227403828012a48048280120b003829012a4804829", - "0x6010030a480482a01268c038170300a01481001205c04a9201205c04cd7", - "0x482901267803828012a4804807c9a01c14814030a480480c0120634c807", - "0x13027054a480482805201c1544700e0a004a920120a004a9d00e0a404a92", - "0xf809d7c0800f0185240601302703193803814012a480481401227403825", - "0x381800e1e004ebf0c00740c2920300940f018c9c01c03a9201201c0c007", - "0x3a86012a480482050e060cc80750e025490090c00600c19900e01d49009", - "0x149009508024cf0075060254900900f93403a8450a061490090200500c699", - "0x1402815040a949009506a100e82a88e01d418095240254180953a01d42009", - "0xc2815040632700750a0254900950a0244e80750c0254900950c02496807", - "0x160185240614027f031938038075240240381800e9ec04ec04fc9fc0c292", - "0xc19900e17c04a920120b94301833201c03a9201201c0c00705a0276082e", - "0x19009524024199ae0313cc03833012a480480704001cd70095240253f05f", - "0x14900950a0244e80705802549009058024060073700254900906402552807", - "0x38075240240381800e6e14282c054024dc009524024dc0099ca01d42809", - "0x2c8070340254900900ea0c038075240253f0094ca01c03a92012a1804969", - "0xe20095240241b81a030a0003837012a4804837012a0403837012a4804807", - "0x3ec201201c0f00707202549009388024240070740254900905a02406007", - "0x14180700ea4804a8001280803807524025430092d201c03a9201201c0c007", - "0x14000702e0254900902e0254080702e0254900900e164039c8012a4804807", - "0x4a920121080484800e0e804a920129ec0480c00e10804a9201205ce4018", - "0x484801339003848012a48048390980613f0070980254900900e9fc03839", - "0x4ce500ea1404a92012a140489d00e0e804a920120e80480c00e12404a92", - "0x149009030024b480700ea480480703001c24a850740a804849012a4804849", - "0x2680952402403a8300e01d490090400253280700ea480481001280803807", - "0x1490093a21340c28000e74404a9201274404a8100e74404a9201201c2c807", - "0x480703c01c290095240242800909001c288095240243c00901801c28009", - "0x3a9201204004a0200e01d49009030024b480700ea480480703001c03ec3", - "0x39f4012a48048070b201c2a00952402403a8300e01d4900904a02501007", - "0x14900903e02406007036025490093e81500c28000e7d004a920127d004a81", - "0x290590309f803859012a48048074fe01c290095240240d80909001c28809", - "0x4e8070a2025490090a2024060070ac0254900940c0267200740c02549009", - "0x38104d61580a0510540242b0095240242b0099ca01c0a0095240240a009", - "0x9c18f00e0409493831e01c080070540600480731c4e0c78070204a49c18f", - "0x815e0540600480731c4e0c78070204a49c18f00e0410a02a0300240398e", - "0xc78070204a49c18f00e0427202a0300240398e27063c038102524e0c7807", - "0x36282a0300240398e27063c038102524e0c7807021b101501801201cc7138", - "0x38102524e0c7807021b181501801201cc713831e01c0812927063c03810", - "0x1501801201cc713831e01c0812927063c03810d8e0a80c00900e6389c18f", - "0x9493831e6ec0380cd920a80c00900e6389c18f00e0409493831e01c086c8", - "0xc713831e01c0812927063c03810d940401501801201cc713831e6ec0380c", - "0x3810d980a80c00900e6389c18f00e0409493831e01c086cb05406004807", - "0xa0070184a49c18f02801c066cd0540600480731c4e0c78070204a49c18f", - "0xc00900e6389c18f00e0409493831e01c086ce0200a80c00900e6389c18f", - "0x9493831e01c086d00540600480731c4e0c78070204a49c18f00e0436782a", - "0x480731c4e0c78070204a49c18f00e0436882a0300240398e27063c03810", - "0x9c18f00e0436982a0300240398e27063c038102524e0c7807021b4815018", - "0x398e27063c038102524e0c7807021b501501801201cc713831e01c08129", - "0x36b0100540600480731c4e0c78073980309493831e01ce600cdaa0a80c009", - "0x86d70180401501801201cc713831e050039cc0284a49c18f02801ce6014", - "0x380c2524e0c79d000e0336c02a0300240398e27063c038102524e0c7807", - "0xc713831e01ce600c2524e0c78073980336c8100540600480731c4e0c79d0", - "0x86db0540600480731c4e0c78070204a49c18f00e0436d01005406004807", - "0xc78070204a49c18f00e0436e02a0300240398e27063c038102524e0c7807", - "0x36f02a0300240398e27063c038102524e0c7807021b741501801201cc7138", - "0x9406f27063c03829dbe0401501801201cd298f00e0a80b84925263c0380c", - "0xd792900e0a894807031b800a00c0200a80c00900e6b09c18f00e0409406f", - "0x9612d2964e0c780704fb880c00900e6c0c78070544a4c7807055b8404807", - "0xa593831e0a37182805205006010054060048073624e0c780702005c0b817", - "0xc79bb00e043720290280300802a0300240398e27063c1501702e05c0b9b6", - "0x39c327063c038102964e0c7807021b941501801201cdf18f37601c081bd", - "0xc7807019b9c1501801201ce193831e01c0814b27063c03810dcc0a80c009", - "0x38102964e0c7807021ba00802a030024039c3270050c780701852c9c014", - "0xc00900e7249c18f00e0402494b27063c0380cdd20a80c00900e70c9c18f", - "0xb94b31e01c086eb0540600480738663c0382a02e52cc7807021ba80802a", - "0xe618f00e0300b81702e52c9c1cc31e01c146ec0540600480738663c0382a", - "0x14eee01201ce692900e0a894807031bb4148140180401501801201ce1938", - "0x3778140180401501801201ce1938398050c780702851ca5938398050c7807", - "0xe618f00e05378010054060048073864e0c79d000e030a593831e7400380c", - "0xef0070304a403818de20300802a030024039c3270730c780701805ca5938", - "0xc7807021bcc0802a030024039df31e01c150172424a4c7807019bc804807", - "0x48073d463c0382a248490c7807021bd01501801201cf498f00e0a894929", - "0x3791031e01c066f6054060048073ea63c0382a220464c7807021bd415018", - "0xc00900e808038180bc17876007021bdc0802a030024039f631e01c1505e", - "0xc7807053be40802a03002403a0727063c038101e23c09c18f00e0337c02a", - "0xc7807053be80a00c0200a80c00900e8789c01431e01c0604243a0409c014", - "0x1512900e0637d8140180401501801201d1593831e01c080c002004008138", - "0x2f11031e01c086fd030024039f600e0600811000e0ab7e00900e94094807", - "0x813831e01c066ff01201c7600902e3b00c6fe054060048073ec63c0382a", - "0xa18f00e0302813802863c0380ce000401501801201cfa13831e01c0821d", - "0x67020540600480702001c0c01a02004003810e020401501801201ce8938", - "0x1501022005003810e060401501801201cfa81431e01c08110232050c7807", - "0xe080a80c00900e7d80a007" - ], - "sierra_program_debug_info": { - "type_names": [], - "libfunc_names": [], - "user_func_names": [] - }, - "contract_class_version": "0.1.0", - "entry_points_by_type": { - "EXTERNAL": [ - { - "selector": "0x1143aa89c8e3ebf8ed14df2a3606c1cd2dd513fac8040b0f8ab441f5c52fe4", - "function_idx": 20 - }, - { - "selector": "0x3c118a68e16e12e97ed25cb4901c12f4d3162818669cc44c391d8049924c14", - "function_idx": 5 - }, - { - "selector": "0x5562b3e932b4d139366854d5a2e578382e6a3b6572ac9943d55e7efbe43d00", - "function_idx": 16 - }, - { - "selector": "0x600c98a299d72ef1e09a2e1503206fbc76081233172c65f7e2438ef0069d8d", - "function_idx": 21 - }, - { - "selector": "0x62c83572d28cb834a3de3c1e94977a4191469a4a8c26d1d7bc55305e640ed5", - "function_idx": 17 - }, - { - "selector": "0x679c22735055a10db4f275395763a3752a1e3a3043c192299ab6b574fba8d6", - "function_idx": 25 - }, - { - "selector": "0x7772be8b80a8a33dc6c1f9a6ab820c02e537c73e859de67f288c70f92571bb", - "function_idx": 23 - }, - { - "selector": "0xd47144c49bce05b6de6bce9d5ff0cc8da9420f8945453e20ef779cbea13ad4", - "function_idx": 1 - }, - { - "selector": "0xe7510edcf6e9f1b70f7bd1f488767b50f0363422f3c563160ab77adf62467b", - "function_idx": 8 - }, - { - "selector": "0xf818e4530ec36b83dfe702489b4df537308c3b798b0cc120e32c2056d68b7d", - "function_idx": 12 - }, - { - "selector": "0x10d2fede95e3ec06a875a67219425c27c5bd734d57f1b221d729a2337b6b556", - "function_idx": 10 - }, - { - "selector": "0x12ead94ae9d3f9d2bdb6b847cf255f1f398193a1f88884a0ae8e18f24a037b6", - "function_idx": 27 - }, - { - "selector": "0x14dae1999ae9ab799bc72def6dc6e90890cf8ac0d64525021b7e71d05cb13e8", - "function_idx": 3 - }, - { - "selector": "0x169f135eddda5ab51886052d777a57f2ea9c162d713691b5e04a6d4ed71d47f", - "function_idx": 11 - }, - { - "selector": "0x1ae1a515cf2d214b29bdf63a79ee2d490efd4dd1acc99d383a8e549c3cecb5d", - "function_idx": 26 - }, - { - "selector": "0x23039bef544cff56442d9f61ae9b13cf9e36fcce009102c5b678aac93f37b36", - "function_idx": 4 - }, - { - "selector": "0x27c3334165536f239cfd400ed956eabff55fc60de4fb56728b6a4f6b87db01c", - "function_idx": 2 - }, - { - "selector": "0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325", - "function_idx": 9 - }, - { - "selector": "0x30f842021fbf02caf80d09a113997c1e00a32870eee0c6136bed27acb348bea", - "function_idx": 24 - }, - { - "selector": "0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f", - "function_idx": 22 - }, - { - "selector": "0x32564d7e0fe091d49b4c20f4632191e4ed6986bf993849879abfef9465def25", - "function_idx": 18 - }, - { - "selector": "0x3604cea1cdb094a73a31144f14a3e5861613c008e1e879939ebc4827d10cd50", - "function_idx": 6 - }, - { - "selector": "0x382be990ca34815134e64a9ac28f41a907c62e5ad10547f97174362ab94dc89", - "function_idx": 13 - }, - { - "selector": "0x38be5d5f7bf135b52888ba3e440a457d11107aca3f6542e574b016bf3f074d8", - "function_idx": 14 - }, - { - "selector": "0x3a6a8bae4c51d5959683ae246347ffdd96aa5b2bfa68cc8c3a6a7c2ed0be331", - "function_idx": 7 - }, - { - "selector": "0x3b097c62d3e4b85742aadd0dfb823f96134b886ec13bda57b68faf86f294d97", - "function_idx": 0 - }, - { - "selector": "0x3d95049b565ec2d4197a55108ef03996381d31c84acf392a0a42b28163d69d1", - "function_idx": 15 - }, - { - "selector": "0x3eb640b15f75fcc06d43182cdb94ed38c8e71755d5fb57c16dd673b466db1d4", - "function_idx": 19 - } - ], - "L1_HANDLER": [ - { - "selector": "0x205500a208d0d49d79197fea83cc3f5fde99ac2e1909ae0a5d9f394c0c52ed0", - "function_idx": 29 - }, - { - "selector": "0x39edbbb129ad752107a94d40c3873cae369a46fd2fc578d075679aa67e85d12", - "function_idx": 28 - } - ], - "CONSTRUCTOR": [ - { - "selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", - "function_idx": 30 - } - ] - }, - "abi": [ - { - "type": "constructor", - "name": "constructor", - "inputs": [ - { - "name": "arg1", - "type": "core::felt252" - }, - { - "name": "arg2", - "type": "core::felt252" - } - ] - }, - { - "type": "function", - "name": "test_storage_read_write", - "inputs": [ - { - "name": "address", - "type": "core::starknet::storage_access::StorageAddress" - }, - { - "name": "value", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "test_count_actual_storage_changes", - "inputs": [], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "function", - "name": "test_call_contract", - "inputs": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "entry_point_selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Array::" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "test_emit_events", - "inputs": [ - { - "name": "events_number", - "type": "core::integer::u64" - }, - { - "name": "keys", - "type": "core::array::Array::" - }, - { - "name": "data", - "type": "core::array::Array::" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "test_get_block_hash", - "inputs": [ - { - "name": "block_number", - "type": "core::integer::u64" - } - ], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "struct", - "name": "core::starknet::info::BlockInfo", - "members": [ - { - "name": "block_number", - "type": "core::integer::u64" - }, - { - "name": "block_timestamp", - "type": "core::integer::u64" - }, - { - "name": "sequencer_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "struct", - "name": "core::starknet::info::v2::ResourceBounds", - "members": [ - { - "name": "resource", - "type": "core::felt252" - }, - { - "name": "max_amount", - "type": "core::integer::u64" - }, - { - "name": "max_price_per_unit", - "type": "core::integer::u128" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "core::starknet::info::v2::TxInfo", - "members": [ - { - "name": "version", - "type": "core::felt252" - }, - { - "name": "account_contract_address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "max_fee", - "type": "core::integer::u128" - }, - { - "name": "signature", - "type": "core::array::Span::" - }, - { - "name": "transaction_hash", - "type": "core::felt252" - }, - { - "name": "chain_id", - "type": "core::felt252" - }, - { - "name": "nonce", - "type": "core::felt252" - }, - { - "name": "resource_bounds", - "type": "core::array::Span::" - }, - { - "name": "tip", - "type": "core::integer::u128" - }, - { - "name": "paymaster_data", - "type": "core::array::Span::" - }, - { - "name": "nonce_data_availability_mode", - "type": "core::integer::u32" - }, - { - "name": "fee_data_availability_mode", - "type": "core::integer::u32" - }, - { - "name": "account_deployment_data", - "type": "core::array::Span::" - } - ] - }, - { - "type": "function", - "name": "test_get_execution_info", - "inputs": [ - { - "name": "expected_block_info", - "type": "core::starknet::info::BlockInfo" - }, - { - "name": "expected_tx_info", - "type": "core::starknet::info::v2::TxInfo" - }, - { - "name": "expected_caller_address", - "type": "core::felt252" - }, - { - "name": "expected_contract_address", - "type": "core::felt252" - }, - { - "name": "expected_entry_point_selector", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "test_library_call", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - }, - { - "name": "function_selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Array::" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "test_nested_library_call", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - }, - { - "name": "lib_selector", - "type": "core::felt252" - }, - { - "name": "nested_selector", - "type": "core::felt252" - }, - { - "name": "a", - "type": "core::felt252" - }, - { - "name": "b", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::array::Span::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "test_replace_class", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "test_send_message_to_l1", - "inputs": [ - { - "name": "to_address", - "type": "core::felt252" - }, - { - "name": "payload", - "type": "core::array::Array::" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "segment_arena_builtin", - "inputs": [], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "l1_handler", - "name": "l1_handle", - "inputs": [ - { - "name": "from_address", - "type": "core::felt252" - }, - { - "name": "arg", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "l1_handler", - "name": "l1_handler_set_value", - "inputs": [ - { - "name": "from_address", - "type": "core::felt252" - }, - { - "name": "key", - "type": "core::starknet::storage_access::StorageAddress" - }, - { - "name": "value", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "function", - "name": "test_deploy", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - }, - { - "name": "contract_address_salt", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Array::" - }, - { - "name": "deploy_from_zero", - "type": "core::bool" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "test_keccak", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "test_sha256", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "test_secp256k1", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "test_secp256r1", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "assert_eq", - "inputs": [ - { - "name": "x", - "type": "core::felt252" - }, - { - "name": "y", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "invoke_call_chain", - "inputs": [ - { - "name": "call_chain", - "type": "core::array::Array::" - } - ], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "fail", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "recursive_fail", - "inputs": [ - { - "name": "depth", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "recurse", - "inputs": [ - { - "name": "depth", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "recursive_syscall", - "inputs": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "function_selector", - "type": "core::felt252" - }, - { - "name": "depth", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "advance_counter", - "inputs": [ - { - "name": "index", - "type": "core::felt252" - }, - { - "name": "diff_0", - "type": "core::felt252" - }, - { - "name": "diff_1", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "struct", - "name": "sierra_test_contract::sierra_test_contract::TestContract::IndexAndValues", - "members": [ - { - "name": "index", - "type": "core::felt252" - }, - { - "name": "values", - "type": "(core::integer::u128, core::integer::u128)" - } - ] - }, - { - "type": "function", - "name": "xor_counters", - "inputs": [ - { - "name": "index_and_x", - "type": "sierra_test_contract::sierra_test_contract::TestContract::IndexAndValues" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "call_xor_counters", - "inputs": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "index_and_x", - "type": "sierra_test_contract::sierra_test_contract::TestContract::IndexAndValues" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "test_ec_op", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "add_signature_to_counters", - "inputs": [ - { - "name": "index", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "send_message", - "inputs": [ - { - "name": "to_address", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "event", - "name": "sierra_test_contract::sierra_test_contract::TestContract::Event", - "kind": "enum", - "variants": [] - } - ] -} \ No newline at end of file diff --git a/crates/blockifier/feature_contracts/cairo1/test_contract.cairo b/crates/blockifier/feature_contracts/cairo1/test_contract.cairo index 9450aa119f..5816db5c59 100644 --- a/crates/blockifier/feature_contracts/cairo1/test_contract.cairo +++ b/crates/blockifier/feature_contracts/cairo1/test_contract.cairo @@ -554,9 +554,10 @@ mod TestContract { assert!(outputs.get_output(mul) == u384 { limb0: 6, limb1: 0, limb2: 0, limb3: 0 }); } - - // Add drop for AddInputResult as it only has PanicDestruct. + // Add drop for these objects as they only have PanicDestruct. impl AddInputResultDrop of Drop>; + impl CircuitDataDrop of Drop>; + impl CircuitInputAccumulatorDrop of Drop>; #[external(v0)] fn test_rc96_holes(ref self: ContractState) { @@ -569,4 +570,4 @@ mod TestContract { let in1 = CircuitElement::> {}; (in1,).new_inputs().next([3, 0, 0, 0]); } -} +} \ No newline at end of file diff --git a/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract.sierra.json b/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract.sierra.json new file mode 100644 index 0000000000..cb91d22d1b --- /dev/null +++ b/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract.sierra.json @@ -0,0 +1,8459 @@ +{ + "sierra_program": [ + "0x1", + "0x6", + "0x0", + "0x2", + "0x8", + "0x0", + "0x84f", + "0x7b1", + "0x19c", + "0x52616e6765436865636b", + "0x800000000000000100000000000000000000000000000000", + "0x436f6e7374", + "0x800000000000000000000000000000000000000000000002", + "0x1", + "0x49", + "0x2", + "0x6e5f627974657320746f6f20626967", + "0x1a", + "0x1000000000000000000000000000000", + "0x10000000000000000000000000000", + "0x100000000000000000000000000", + "0x1000000000000000000000000", + "0x10000000000000000000000", + "0x100000000000000000000", + "0x1000000000000000000", + "0x10000000000000000", + "0x100000000000000", + "0x1000000000000", + "0x10000000000", + "0x100000000", + "0x1000000", + "0x10000", + "0x100", + "0x537472756374", + "0x800000000000000f00000000000000000000000000000001", + "0x0", + "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", + "0x456e756d", + "0x800000000000000700000000000000000000000000000011", + "0x14cb65c06498f4a8e9db457528e9290f453897bdb216ce18347fff8fef2cd11", + "0x11", + "0x426f756e646564496e74", + "0x800000000000000700000000000000000000000000000002", + "0xf", + "0x3", + "0x18", + "0x426f78", + "0x800000000000000700000000000000000000000000000001", + "0x1c", + "0x75313238", + "0x800000000000000700000000000000000000000000000000", + "0x800000000000000700000000000000000000000000000003", + "0x25e2ca4b84968c2d8b83ef476ca8549410346b00836ce79beaf538155990bb2", + "0x1b", + "0x42697477697365", + "0x556e696e697469616c697a6564", + "0x800000000000000200000000000000000000000000000001", + "0x1d", + "0x753235365f737562204f766572666c6f77", + "0x43", + "0x51", + "0x800000000000000000000000000000000000000000000003", + "0x26", + "0x23", + "0x25", + "0x24", + "0x483ada7726a3c4655da4fbfc0e1108a8", + "0x79be667ef9dcbbac55a06295ce870b07", + "0x29bfcdb2dce28d959f2815b16f81798", + "0xfd17b448a68554199c47d08ffb10d4b8", + "0xe", + "0xd", + "0xb", + "0xa", + "0x9", + "0x8", + "0x7", + "0x6", + "0x5", + "0x4", + "0x107", + "0x98", + "0x18ef5e2178ac6be59ceafd15e6995810f636807e02c51d309c3f65e37000fc5", + "0x33", + "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", + "0x4172726179", + "0x800000000000000300000000000000000000000000000001", + "0x800000000000000300000000000000000000000000000003", + "0x36", + "0x37", + "0x2f23416cc60464d4158423619ba713070eb82b686c9d621a22c67bd37f6e0a9", + "0x35", + "0x38", + "0x3f", + "0x3c", + "0x3e", + "0x3d", + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e16", + "0x6b17d1f2e12c4247f8bce6e563a440f2", + "0x77037d812deb33a0f4a13945d898c296", + "0x2bce33576b315ececbb6406837bf51f5", + "0x800000000000000700000000000000000000000000000005", + "0x2907a9767b8e0b68c23345eea8650b1366373b598791523a07fddaa450ba526", + "0x553132384d756c47756172616e746565", + "0x44", + "0x4e6f6e5a65726f", + "0x47", + "0x46", + "0x5369676e6174757265206f7574206f662072616e6765", + "0xffffffff00000000ffffffffffffffff", + "0xbce6faada7179e84f3b9cac2fc632551", + "0x496e76616c6964207369676e6174757265", + "0x66656c74323532", + "0x3233063c5dc6197e9bf4ddc53b925e10907665cf58255b7899f8212442d4605", + "0x4a", + "0x1d8a68005db1b26d0d9f54faae1798d540e7df6326fae758cc2cf8f7ee88e72", + "0x4b", + "0x536563703235366b31506f696e74", + "0x3179e7829d19e62b12c79010203ceee40c98166e97eb104c25ad1adb6b9675a", + "0x4d", + "0x4e", + "0x3c7b5436891664778e6019991e6bd154eeab5d43a552b1f19485dec008095d3", + "0x4f", + "0x55", + "0x54", + "0x57", + "0x14ef93a95bec47ff4e55863055b7a948870fa13be1cbddd481656bdaf5facc2", + "0x52", + "0xfffffffffffffffffffffffffffffffe", + "0xbaaedce6af48a03bbfd25e8cd0364141", + "0x753332", + "0x56", + "0x20", + "0x10", + "0x79", + "0x69", + "0x80000000", + "0x7533325f6d756c204f766572666c6f77", + "0x7533325f616464204f766572666c6f77", + "0x800000", + "0x66", + "0x8000", + "0x63", + "0x80", + "0x60", + "0x6a", + "0x8000000000000000", + "0x753634", + "0x4b656363616b206c61737420696e70757420776f7264203e3762", + "0x7a", + "0x313d53fcef2616901e3fd6801087e8d55f5cb59357e1fc8b603b82ae0af064c", + "0x7b", + "0x7f", + "0x38b0179dda7eba3d95708820abf10d3d4f66e97d9a9013dc38d712dce2af15", + "0x7d", + "0x800000000000000700000000000000000000000000000004", + "0x3342418ef16b3e2799b906b1e4e89dbb9b111332dd44f72458ce44f9895b508", + "0x38f1b5bca324642b144da837412e9d82e31937ed4bbe21a1ebccb0c3d3d8d36", + "0x7533325f737562204f766572666c6f77", + "0x4369726375697444617461", + "0x83", + "0x43697263756974", + "0x800000000000000800000000000000000000000000000001", + "0x86", + "0x43697263756974496e707574416363756d756c61746f72", + "0x43697263756974496e707574", + "0x800000000000000800000000000000000000000000000002", + "0x85", + "0x4e6f7420616c6c20696e707574732068617665206265656e2066696c6c6564", + "0x526573756c743a3a756e77726170206661696c65642e", + "0x74584e9f10ffb1a40aa5a3582e203f6758defc4a497d1a2d5a89f274a320e9", + "0x89", + "0x536e617073686f74", + "0x8b", + "0x149ee8c97f9cdd259b09b6ca382e10945af23ee896a644de8c7b57da1779da7", + "0x8c", + "0x800000000000000300000000000000000000000000000004", + "0x36775737a2dc48f3b19f9a1f4bc3ab9cb367d1e2e827cef96323826fd39f53f", + "0x8e", + "0x602e", + "0x206c696d62313a20302c206c696d62323a20302c206c696d62333a2030207d", + "0x6f7574707574286d756c29203d3d2075333834207b206c696d62303a20362c", + "0x679ea9c5b65e40ad9da80f5a4150d36f3b6af3e88305e2e3ae5eccbc5743d9", + "0x94", + "0x1f", + "0x617373657274696f6e206661696c65643a20606f7574707574732e6765745f", + "0x62797465733331", + "0x5539364c696d62734c7447756172616e746565", + "0x800000000000000100000000000000000000000000000001", + "0x4d756c4d6f6447617465", + "0x9f", + "0x9e", + "0x5375624d6f6447617465", + "0xa0", + "0x496e766572736547617465", + "0xa1", + "0x4164644d6f6447617465", + "0xffffffffffffffffffffffff", + "0x35de1f6419a35f1a8c6f276f09c80570ebf482614031777c6d07679cf95b8bb", + "0xa2", + "0x436972637569744661696c75726547756172616e746565", + "0x436972637569745061727469616c4f757470757473", + "0xb4", + "0x436972637569744f757470757473", + "0xa8", + "0xaa", + "0x4369726375697444657363726970746f72", + "0x416c6c20696e707574732068617665206265656e2066696c6c6564", + "0x46a6158a16a947e5916b2a2ca68501a45e93d7110e81aa2d6438b1c57c879a3", + "0x55393647756172616e746565", + "0x800000000000000100000000000000000000000000000005", + "0xb1", + "0xb6", + "0x9c", + "0x436972637569744d6f64756c7573", + "0x4d756c4d6f64", + "0xbb", + "0x52616e6765436865636b3936", + "0xbd", + "0x4164644d6f64", + "0xc0", + "0x6d232c016ef1b12aec4b7f88cc0b3ab662be3b7dd7adbce5209fcfdbd42a504", + "0x45635374617465", + "0x4b5810004d9272776dec83ecc20c19353453b956e594188890b48467cb53c19", + "0x3dbce56de34e1cfe252ead5a1f14fd261d520d343ff6b7652174e62976ef44d", + "0x4563506f696e74", + "0xc7", + "0x4fad269cbf860980e38768fe9cb6b0b9ab03ee3fe84cfde2eccce597c874fd8", + "0x654fd7e67a123dd13868093b3b7777f1ffef596c2e324f25ceaf9146698482c", + "0x1671f96113fa573e5b6df9aef6a004dbf7cc3c475398dd3be1b2590f1f9cdd9", + "0xcb", + "0xce", + "0x7538", + "0x53746f726167654261736541646472657373", + "0x3c4930bb381033105f3ca15ccded195c90cd2af5baa0e1ceb36fde292df7652", + "0xcf", + "0x34482b42d8542e3c880c5c93d387fb8b01fe2a5d54b6f50d62fe82d9e6c2526", + "0x2691cb735b18f3f656c3b82bd97a32b65d15019b64117513f8604d1e06fe58b", + "0x7265637572736976655f6661696c", + "0x4469766973696f6e2062792030", + "0x32564d7e0fe091d49b4c20f4632191e4ed6986bf993849879abfef9465def25", + "0x62c83572d28cb834a3de3c1e94977a4191469a4a8c26d1d7bc55305e640ed5", + "0x3288d594b9a45d15bb2fcb7903f06cdb06b27f0ba88186ec4cfaa98307cb972", + "0xd8", + "0xa853c166304d20fb0711becf2cbdf482dee3cac4e9717d040b7a7ab1df7eec", + "0xd9", + "0xe0", + "0xdd", + "0xdf", + "0xde", + "0x177e60492c5a8242f76f07bfe3661bd", + "0xb292a619339f6e567a305c951c0dcbcc", + "0x42d16e47f219f9e98e76e09d8770b34a", + "0xe59ec2a17ce5bd2dab2abebdf89a62e2", + "0xe6", + "0xe3", + "0xe5", + "0xe4", + "0xe3b0c44298fc1c149afbf4c8996fb924", + "0x87d9315798aaa3a5ba01775787ced05e", + "0xaaf7b4e09fc81d6d1aa546e8365d525d", + "0x27ae41e4649b934ca495991b7852b855", + "0xec", + "0xe9", + "0xeb", + "0xea", + "0x4aaec73635726f213fb8a9e64da3b86", + "0x49288242", + "0x6e1cda979008bfaf874ff796eb3bb1c0", + "0x32e41495a944d0045b522eba7240fad5", + "0xf2", + "0xef", + "0xf1", + "0xf0", + "0xdb0a2e6710c71ba80afeb3abdf69d306", + "0x502a43ce77c6f5c736a82f847fa95f8c", + "0x2d483fe223b12b91047d83258a958b0f", + "0xce729c7704f4ddf2eaaf0b76209fe1b0", + "0xf6", + "0xf5", + "0x536563703235367231506f696e74", + "0xffffffff000000010000000000000000", + "0xcb47311929e7a903ce831cb2b3e67fe265f121b394a36bc46c17cf352547fc", + "0xf4", + "0x185fda19bc33857e9f1d92d61312b69416f20cf740fa3993dcc2de228a6671d", + "0xf8", + "0xf83fa82126e7aeaf5fe12fff6a0f4a02d8a185bf5aaee3d10d1c4e751399b4", + "0xf9", + "0x107a3e65b6e33d1b25fa00c80dfe693f414350005bc697782c25eaac141fedd", + "0x101", + "0xfe", + "0xff", + "0x4ac5e5c0c0e8a4871583cc131f35fb49", + "0x4c8e4fbc1fbb1dece52185e532812c4f", + "0x7a5f81cf3ee10044320a0d03b62d3e9a", + "0xc2b7f60e6a8b84965830658f08f7410c", + "0x105", + "0x104", + "0x100000000000000000000000000000000", + "0xe888fbb4cf9ae6254f19ba12e6d9af54", + "0x788f195a6f509ca3e934f78d7a71dd85", + "0x10b", + "0x10a", + "0x556e657870656374656420636f6f7264696e61746573", + "0x767410c1", + "0xbb448978bd42b984d7de5970bcaf5c43", + "0x111", + "0x10e", + "0x110", + "0x10f", + "0x8e182ca967f38e1bd6a49583f43f1876", + "0xf728b4fa42485e3a0a5d2f346baa9455", + "0xe3e70682c2094cac629f6fbed82c07cd", + "0x8e031ab54fc0c4a8f0dc94fad0d0611", + "0x496e76616c696420617267756d656e74", + "0x116", + "0x115", + "0x53686f756c64206265206e6f6e65", + "0xffffffffffffffffffffffffffffffff", + "0xfffffffffffffffffffffffefffffc2f", + "0x140", + "0x13f", + "0x61be55a8", + "0x800000000000000700000000000000000000000000000009", + "0x11b", + "0x336711c2797eda3aaf8c07c5cf7b92162501924a7090b25482d45dd3a24ddce", + "0x11c", + "0x536861323536537461746548616e646c65", + "0x11d", + "0x11e", + "0x324f33e2d695adb91665eafd5b62ec62f181e09c2e0e60401806dcc4bb3fa1", + "0x11f", + "0x800000000000000000000000000000000000000000000009", + "0x11a", + "0x12a", + "0x129", + "0x128", + "0x127", + "0x126", + "0x125", + "0x124", + "0x123", + "0x5be0cd19", + "0x1f83d9ab", + "0x9b05688c", + "0x510e527f", + "0xa54ff53a", + "0x3c6ef372", + "0xbb67ae85", + "0x6a09e667", + "0x176a53827827a9b5839f3d68f1c2ed4673066bf89e920a3d4110d3e191ce66b", + "0x12b", + "0x61616161", + "0x496e646578206f7574206f6620626f756e6473", + "0x57726f6e67206572726f72206d7367", + "0x496e76616c696420696e707574206c656e677468", + "0x53686f756c64206661696c", + "0xa5963aa610cb75ba273817bce5f8c48f", + "0x57726f6e6720686173682076616c7565", + "0x587f7cc3722e9654ea3963d5fe8c0748", + "0x135", + "0x3f829a4bc463d91621ba418d447cc38c95ddc483f9ccfebae79050eb7b3dcb6", + "0x136", + "0x25e50662218619229b3f53f1dc3253192a0f68ca423d900214253db415a90b4", + "0x138", + "0x13a", + "0x38b507bf259d96f5c53e8ab8f187781c3d096482729ec2d57f3366318a8502f", + "0x13b", + "0x13c", + "0x3c5ce4d28d473343dbe52c630edf038a582af9574306e1d609e379cd17fc87a", + "0x13d", + "0x424c4f434b5f494e464f5f4d49534d41544348", + "0x54585f494e464f5f4d49534d41544348", + "0x43414c4c45525f4d49534d41544348", + "0x434f4e54524143545f4d49534d41544348", + "0x53454c4543544f525f4d49534d41544348", + "0x147", + "0x1597b831feeb60c71f259624b79cf66995ea4f7e383403583674ab9c33b9cec", + "0x148", + "0x149", + "0x21afb2f280564fc34ddb766bf42f7ca36154bbba994fbc0f0235cd873ace36a", + "0x14a", + "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", + "0x14c", + "0x14d", + "0x45b67c75542d42836cef6c02cca4dbff4a80a8621fa521cbfff1b2dd4af35a", + "0x14e", + "0x155", + "0x17f", + "0x436f6e747261637441646472657373", + "0x800000000000000700000000000000000000000000000006", + "0x7d4d99e9ed8d285b5c61b493cedb63976bc3d9da867933d829f49ce838b5e7", + "0x151", + "0x150", + "0x152", + "0x153", + "0x80000000000000070000000000000000000000000000000e", + "0x348a62b7a38c0673e61e888d83a3ac1bf334ee7361a8514593d3d9532ed8b39", + "0x53797374656d", + "0x157", + "0x1ce0be45cbaa9547dfece0f040e22ec60de2d0d5a6c79fa5514066dfdbb7ca6", + "0x3128e9bfd21b6f544f537413d7dd38a8f2e017a3b81c1a4bcf8f51a64d0dc3d", + "0x15b", + "0x33ecdfa3f249457fb2ae8b6a6713b3069fa0c38450e972297821b52ba929029", + "0x15c", + "0x1d49f7a4b277bf7b55a2664ce8cef5d6922b5ffb806b89644b9e0cdbbcac378", + "0x15e", + "0x13fdd7105045794a99550ae1c4ac13faa62610dfab62c16422bfcf5803baa6e", + "0x15f", + "0x7536345f616464204f766572666c6f77", + "0x22", + "0xc", + "0x45634f70", + "0x7772be8b80a8a33dc6c1f9a6ab820c02e537c73e859de67f288c70f92571bb", + "0x30395f664644a8fcaf5ade2c4222939f92c008e26373687503ba48223c8c394", + "0x24ccc81478f923e8f3889df16e5878b10ce3b21f7fb3e3d758231c4957f5722", + "0x168", + "0x506564657273656e", + "0x6661696c", + "0x223b876ce59fbc872ac2e1412727be9abe279bf03bb3002a29d7aeba8b23a9f", + "0x16c", + "0x4609194bf9403d809e38367adb782a43edaf535df565a1b05eea7b577c89af", + "0x16d", + "0x7820213d2079", + "0x73756363657373", + "0x800000000000000f00000000000000000000000000000003", + "0x3153ad87fe24a37e12e7b17b2ed757f4e86be104f506a9fcc51c44f485a3293", + "0x171", + "0x537175617368656446656c7432353244696374", + "0x46656c7432353244696374", + "0x5365676d656e744172656e61", + "0x436c61737348617368", + "0x4661696c656420746f20646573657269616c697a6520706172616d202334", + "0x4661696c656420746f20646573657269616c697a6520706172616d202335", + "0x800000000000000f00000000000000000000000000000002", + "0xcc5e86243f861d2d64b08c35db21013e773ac5cf10097946fe0011304886d5", + "0x17a", + "0x2271e6a0c1b1931cf78a8bfd030df986f9544c426af3bd6023dc55382237cf7", + "0x17c", + "0x1d2ae7ecff8f8db67bf542f1d1f8201ff21e9f36f780ef569bcc7bc74ab634c", + "0x17d", + "0x3808c701a5d13e100ab11b6c02f91f752ecae7e420d21b56c90ec0a475cc7e5", + "0x1cbd0cd3f779a7c0d3cdc804f89c39bcf71a85b43d3cf8a042111f0bc2ddf63", + "0x909b0519d7c88c554565d942b48b326c8dcbd2e2915301868fb8159e606aa3", + "0x182", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", + "0x17b6ecc31946835b0d9d92c2dd7a9c14f29af0371571ae74a1b228828b2242", + "0x187", + "0x34f9bd7c6cb2dd4263175964ad75f1ff1461ddc332fbfb274e0fb2a5d7ab968", + "0x188", + "0x29d7d57c04a880978e7b3689f6218e507f3be17588744b58dc17762447ad0e7", + "0x18a", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0x4f7574206f6620676173", + "0x4275696c74696e436f737473", + "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", + "0x194", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x53746f7261676541646472657373", + "0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511", + "0x4761734275696c74696e", + "0x33e", + "0x7265766f6b655f61705f747261636b696e67", + "0x77697468647261775f676173", + "0x6272616e63685f616c69676e", + "0x7374727563745f6465636f6e737472756374", + "0x656e61626c655f61705f747261636b696e67", + "0x73746f72655f74656d70", + "0x61727261795f736e617073686f745f706f705f66726f6e74", + "0x756e626f78", + "0x72656e616d65", + "0x656e756d5f696e6974", + "0x19a", + "0x6a756d70", + "0x7374727563745f636f6e737472756374", + "0x656e756d5f6d61746368", + "0x1ad5911ecb88aa4a50482c4de3232f196cfcaf7bd4e9c96d22b283733045007", + "0x64697361626c655f61705f747261636b696e67", + "0x64726f70", + "0x199", + "0x61727261795f6e6577", + "0x636f6e73745f61735f696d6d656469617465", + "0x198", + "0x61727261795f617070656e64", + "0x197", + "0x19b", + "0x6765745f6275696c74696e5f636f737473", + "0x196", + "0x77697468647261775f6761735f616c6c", + "0x195", + "0x647570", + "0x73746f726167655f77726974655f73797363616c6c", + "0x73746f726167655f726561645f73797363616c6c", + "0x736e617073686f745f74616b65", + "0x193", + "0x192", + "0x191", + "0x190", + "0x18f", + "0x18e", + "0x18d", + "0x616c6c6f635f6c6f63616c", + "0x66696e616c697a655f6c6f63616c73", + "0x73746f72655f6c6f63616c", + "0x21adb5788e32c84f69a1863d85ef9394b7bf761a0ce1190f826984e5075c371", + "0x18b", + "0x66756e6374696f6e5f63616c6c", + "0x21", + "0x189", + "0x63616c6c5f636f6e74726163745f73797363616c6c", + "0x186", + "0x18c", + "0x7536345f7472795f66726f6d5f66656c74323532", + "0x185", + "0x184", + "0x183", + "0x6765745f626c6f636b5f686173685f73797363616c6c", + "0x180", + "0x17e", + "0x17b", + "0x179", + "0x178", + "0x181", + "0x636c6173735f686173685f7472795f66726f6d5f66656c74323532", + "0x177", + "0x6c6962726172795f63616c6c5f73797363616c6c", + "0x7265706c6163655f636c6173735f73797363616c6c", + "0x73656e645f6d6573736167655f746f5f6c315f73797363616c6c", + "0x176", + "0x66656c743235325f646963745f6e6577", + "0x175", + "0x27", + "0x174", + "0x66656c743235325f69735f7a65726f", + "0x173", + "0x626f6f6c5f6e6f745f696d706c", + "0x6465706c6f795f73797363616c6c", + "0x28", + "0x172", + "0x29", + "0x2a", + "0x2b", + "0x66656c743235325f737562", + "0x170", + "0x16f", + "0x2c", + "0x16e", + "0x16b", + "0x2d", + "0x2e", + "0x636f6e74726163745f616464726573735f746f5f66656c74323532", + "0x16a", + "0x2f", + "0x30", + "0x169", + "0x31", + "0x753132385f746f5f66656c74323532", + "0x167", + "0x166", + "0x32", + "0x165", + "0x164", + "0x34", + "0x73746f726167655f626173655f616464726573735f636f6e7374", + "0x1275130f95dda36bcbb6e9d28796c1d7e10b6e9fd5ed083e0ede4b12f613528", + "0x73746f726167655f616464726573735f66726f6d5f62617365", + "0x66656c743235325f616464", + "0x7536345f6571", + "0x656d69745f6576656e745f73797363616c6c", + "0x163", + "0x7536345f6f766572666c6f77696e675f616464", + "0x162", + "0x75313238735f66726f6d5f66656c74323532", + "0x160", + "0x15d", + "0x15a", + "0x7533325f7472795f66726f6d5f66656c74323532", + "0x161", + "0x6765745f657865637574696f6e5f696e666f5f76325f73797363616c6c", + "0x154", + "0x156", + "0x753132385f6571", + "0x61727261795f6c656e", + "0x7533325f6571", + "0x14f", + "0x39", + "0x14b", + "0x146", + "0x145", + "0x144", + "0x143", + "0x142", + "0x159", + "0x158", + "0x636c6173735f686173685f746f5f66656c74323532", + "0x141", + "0x66656c743235325f646963745f737175617368", + "0x3a", + "0x13e", + "0x3b", + "0x139", + "0x137", + "0x6b656363616b5f73797363616c6c", + "0x134", + "0x133", + "0x132", + "0x131", + "0x61727261795f676574", + "0x130", + "0x12f", + "0x12e", + "0x12d", + "0x12c", + "0x636f6e73745f61735f626f78", + "0x121", + "0x7368613235365f73746174655f68616e646c655f696e6974", + "0x120", + "0x7368613235365f73746174655f68616e646c655f646967657374", + "0x122", + "0x119", + "0x118", + "0x117", + "0x736563703235366b315f6e65775f73797363616c6c", + "0x114", + "0x113", + "0x112", + "0x10d", + "0x10c", + "0x736563703235366b315f6765745f78795f73797363616c6c", + "0x109", + "0x108", + "0x106", + "0x753132385f736166655f6469766d6f64", + "0x103", + "0x66656c743235325f6d756c", + "0x102", + "0xfd", + "0xfc", + "0xfb", + "0xfa", + "0x7365637032353672315f6e65775f73797363616c6c", + "0xf7", + "0xf3", + "0xee", + "0xed", + "0x7365637032353672315f6765745f78795f73797363616c6c", + "0xe8", + "0xe7", + "0xe2", + "0xe1", + "0xdc", + "0xdb", + "0xda", + "0xd7", + "0x7533325f6f766572666c6f77696e675f737562", + "0x61727261795f706f705f66726f6e74", + "0xd6", + "0xd5", + "0xd4", + "0xd3", + "0xd2", + "0xd1", + "0x706564657273656e", + "0xad292db4ff05a993c318438c1b6c8a8303266af2da151aa28ccece6726f1f1", + "0xd0", + "0xcd", + "0x2679d68052ccd03a53755ca9169677965fbd93e489df62f5f40d4f03c24f7a4", + "0xcc", + "0x62697477697365", + "0xca", + "0xc9", + "0x65635f706f696e745f7472795f6e65775f6e7a", + "0xc8", + "0x756e777261705f6e6f6e5f7a65726f", + "0xc6", + "0xc5", + "0x65635f706f696e745f69735f7a65726f", + "0x65635f73746174655f696e6974", + "0xc3", + "0x65635f73746174655f6164645f6d756c", + "0xc4", + "0x65635f73746174655f7472795f66696e616c697a655f6e7a", + "0x65635f706f696e745f7a65726f", + "0x65635f73746174655f616464", + "0x65635f706f696e745f756e77726170", + "0x161bc82433cf4a92809836390ccd14921dfc4dc410cf3d2adbfee5e21ecfec8", + "0xc2", + "0xba", + "0xb9", + "0xb8", + "0x7472795f696e746f5f636972637569745f6d6f64756c7573", + "0x696e69745f636972637569745f64617461", + "0xb3", + "0x696e746f5f7539365f67756172616e746565", + "0xb2", + "0xb5", + "0x6164645f636972637569745f696e707574", + "0xb0", + "0xbe", + "0xbf", + "0xc1", + "0xbc", + "0xb7", + "0xaf", + "0xae", + "0xad", + "0xac", + "0x6765745f636972637569745f64657363726970746f72", + "0xa9", + "0xa7", + "0x6576616c5f63697263756974", + "0x6765745f636972637569745f6f7574707574", + "0x3ec1c84a1511eed894537833882a965abdddafab0d627a3ee76e01e6b57f37a", + "0x1d1238f44227bdf67f367571e4dec83368c54054d98ccf71a67381f7c51f1c4", + "0x7539365f67756172616e7465655f766572696679", + "0xa3", + "0x40", + "0x97", + "0x96", + "0x41", + "0x95", + "0x93", + "0x92", + "0x91", + "0x90", + "0x8f", + "0x7374727563745f736e617073686f745f6465636f6e737472756374", + "0x7533325f746f5f66656c74323532", + "0x8d", + "0x42", + "0x8a", + "0xa5", + "0x88", + "0x4ef3b3bc4d34db6611aef96d643937624ebee01d56eae5bde6f3b158e32b15", + "0x87", + "0x84", + "0x82", + "0x61727261795f736c696365", + "0x81", + "0x7e", + "0x7c", + "0x78", + "0x7533325f736166655f6469766d6f64", + "0x77", + "0x76", + "0x75", + "0x74", + "0x73", + "0x72", + "0x71", + "0x70", + "0x6f", + "0x6e", + "0x6d", + "0x6c", + "0x7536345f69735f7a65726f", + "0x7536345f736166655f6469766d6f64", + "0x45", + "0x68", + "0x67", + "0x65", + "0x64", + "0x62", + "0x61", + "0x5f", + "0x7533325f776964655f6d756c", + "0x646f776e63617374", + "0x7533325f6f766572666c6f77696e675f616464", + "0x5e", + "0x5d", + "0x5c", + "0x5b", + "0x5a", + "0x59", + "0x58", + "0x61727261795f736e617073686f745f6d756c74695f706f705f66726f6e74", + "0x53", + "0x7368613235365f70726f636573735f626c6f636b5f73797363616c6c", + "0x753132385f6f766572666c6f77696e675f737562", + "0x50", + "0x48", + "0x4c", + "0x753235365f67756172616e7465655f696e765f6d6f645f6e", + "0x753132385f6d756c5f67756172616e7465655f766572696679", + "0x753531325f736166655f6469766d6f645f62795f75323536", + "0x7365637032353672315f6d756c5f73797363616c6c", + "0x7365637032353672315f6164645f73797363616c6c", + "0x757063617374", + "0x753132385f69735f7a65726f", + "0x627974657333315f7472795f66726f6d5f66656c74323532", + "0x627974657333315f746f5f66656c74323532", + "0x393d13543d6033e70e218aad8050e8de40a1dfbac0e80459811df56e3716ce6", + "0x736563703235366b315f6d756c5f73797363616c6c", + "0x736563703235366b315f6164645f73797363616c6c", + "0x696e746f5f626f78", + "0x7370616e5f66726f6d5f7475706c65", + "0x753132385f627974655f72657665727365", + "0x1e", + "0x753132385f67756172616e7465655f6d756c", + "0x753132385f6f766572666c6f77696e675f616464", + "0x17", + "0x16", + "0x626f756e6465645f696e745f616464", + "0x15", + "0x14", + "0x13", + "0x656e756d5f66726f6d5f626f756e6465645f696e74", + "0x12", + "0x3406", + "0xffffffffffffffff", + "0x19", + "0x1ff", + "0x1ec", + "0x1e7", + "0x1d5", + "0x1c4", + "0x1b4", + "0x1ab", + "0x6b", + "0x1f2", + "0x31e", + "0x21e", + "0x223", + "0x30b", + "0x306", + "0x231", + "0x236", + "0x255", + "0x24c", + "0x25e", + "0x2f5", + "0x268", + "0x26d", + "0x28c", + "0x283", + "0x295", + "0x2e4", + "0x2aa", + "0x2d4", + "0x2cd", + "0x311", + "0x39c", + "0x33a", + "0x33f", + "0x38b", + "0x387", + "0x359", + "0x379", + "0x370", + "0x38f", + "0x49f", + "0x48f", + "0x487", + "0x477", + "0x3c8", + "0x3cd", + "0x465", + "0x3d7", + "0x3dc", + "0x452", + "0x3e6", + "0x3eb", + "0x43e", + "0x403", + "0x42b", + "0x424", + "0x589", + "0x4bf", + "0x4c4", + "0x576", + "0x571", + "0x4d2", + "0x4d7", + "0x55f", + "0x4e0", + "0x4e5", + "0x504", + "0x4fb", + "0x50d", + "0x54e", + "0x522", + "0x53e", + "0x535", + "0x57c", + "0x68c", + "0x5a7", + "0x5ac", + "0x67b", + "0x677", + "0x5b9", + "0x5be", + "0x666", + "0x5c8", + "0x5cd", + "0x654", + "0x5d7", + "0x5dc", + "0x641", + "0x5e6", + "0x5eb", + "0x62d", + "0x603", + "0x61a", + "0x67f", + "0x705", + "0x6a8", + "0x6ad", + "0x6f4", + "0x6f0", + "0x6c4", + "0x6e2", + "0x6d9", + "0x6f8", + "0x7c1", + "0x723", + "0x728", + "0x7b0", + "0x731", + "0x736", + "0x754", + "0x74c", + "0x75d", + "0x7a0", + "0x771", + "0x791", + "0x788", + "0x80d", + "0x7e6", + "0x7ff", + "0x933", + "0x82d", + "0x832", + "0x920", + "0x91b", + "0x840", + "0x845", + "0x909", + "0x84e", + "0x853", + "0x872", + "0x869", + "0x87b", + "0x8f8", + "0x884", + "0x889", + "0x8e5", + "0x894", + "0x899", + "0x8ae", + "0x8d3", + "0x8ca", + "0x926", + "0x99", + "0x9a", + "0x9b", + "0x9d", + "0x985", + "0x958", + "0x978", + "0x971", + "0x9d5", + "0x9a8", + "0x9c8", + "0x9c1", + "0xa2a", + "0x9f9", + "0xa1c", + "0xa14", + "0xa7b", + "0xa4e", + "0xa6e", + "0xa67", + "0xb19", + "0xa97", + "0xa9c", + "0xb09", + "0xaa6", + "0xaab", + "0xaf8", + "0xac0", + "0xae8", + "0xada", + "0xbb1", + "0xb33", + "0xb38", + "0xb55", + "0xb4e", + "0xb5e", + "0xba2", + "0xb71", + "0xb94", + "0xb8d", + "0xbf3", + "0xbd4", + "0xbe6", + "0xc67", + "0xc0f", + "0xc14", + "0xc57", + "0xc28", + "0xc49", + "0xc42", + "0xcdb", + "0xc83", + "0xc88", + "0xccb", + "0xc9c", + "0xcbd", + "0xcb6", + "0xdb7", + "0xcf7", + "0xcfc", + "0xda6", + "0xda2", + "0xd09", + "0xd0e", + "0xd91", + "0xd18", + "0xd1d", + "0xd7f", + "0xd33", + "0xd6e", + "0xd43", + "0xd58", + "0xd64", + "0xdaa", + "0xe7c", + "0xdd3", + "0xdd8", + "0xe6b", + "0xde2", + "0xde7", + "0xe59", + "0xdf1", + "0xdf6", + "0xe46", + "0xe0d", + "0xe34", + "0xe2c", + "0xeef", + "0xede", + "0xea7", + "0xece", + "0xec5", + "0xf9b", + "0xf0d", + "0xf12", + "0xf8a", + "0xf86", + "0xf75", + "0xf30", + "0xf66", + "0xf5d", + "0xf8e", + "0xff0", + "0xfbf", + "0xfe2", + "0xa4", + "0xfda", + "0x106c", + "0x100d", + "0x1012", + "0x105b", + "0x1027", + "0x104c", + "0x1044", + "0x10e9", + "0x1089", + "0x108e", + "0x10d9", + "0x10a2", + "0x10cb", + "0xa6", + "0x10c2", + "0x1147", + "0x110f", + "0x1137", + "0xab", + "0x112d", + "0x11aa", + "0x116e", + "0x119c", + "0x1191", + "0x118d", + "0x1194", + "0x1231", + "0x11c7", + "0x11cc", + "0x1221", + "0x11d7", + "0x11dc", + "0x1211", + "0x11f0", + "0x1203", + "0x12f2", + "0x124d", + "0x1252", + "0x12e2", + "0x125d", + "0x1262", + "0x12d1", + "0x12cd", + "0x126f", + "0x1274", + "0x12bc", + "0x1289", + "0x12ac", + "0x12a2", + "0x12d5", + "0x1391", + "0x130e", + "0x1313", + "0x1381", + "0x131d", + "0x1322", + "0x1370", + "0x1337", + "0x1360", + "0x1355", + "0x13d8", + "0x13ae", + "0x13ba", + "0x13bf", + "0x13cd", + "0x142f", + "0x1423", + "0x1416", + "0x1405", + "0x1447", + "0x144c", + "0x14a7", + "0x14a3", + "0x145d", + "0x1462", + "0x1499", + "0x1494", + "0x1475", + "0x147a", + "0x148a", + "0x1485", + "0x148f", + "0x149e", + "0x14ab", + "0x14c2", + "0x14c7", + "0x1719", + "0x14d2", + "0x14d7", + "0x1706", + "0x16fc", + "0x14e7", + "0x14ec", + "0x16ea", + "0x16df", + "0x16d1", + "0x16c1", + "0x1506", + "0x150b", + "0x16b0", + "0x1516", + "0x151b", + "0x169f", + "0x1526", + "0x152b", + "0x168e", + "0x1534", + "0x1539", + "0x156a", + "0x155d", + "0x1555", + "0x1573", + "0x167e", + "0x157c", + "0x1581", + "0x166b", + "0x165e", + "0x164e", + "0x163c", + "0x1598", + "0x159d", + "0x1626", + "0x1618", + "0x15ae", + "0x15b3", + "0x1602", + "0x15f4", + "0x15e1", + "0x15cc", + "0x1610", + "0x1634", + "0x1676", + "0x16f4", + "0x1711", + "0x1b18", + "0x175c", + "0x1774", + "0x1775", + "0x1b0b", + "0x1b00", + "0x1ad5", + "0x1aca", + "0x17f9", + "0x1adf", + "0x1830", + "0x1849", + "0x1ab8", + "0x184c", + "0x1ae2", + "0x1aab", + "0x1a9e", + "0x1a91", + "0x18e9", + "0x1901", + "0x1a84", + "0x1904", + "0x1aea", + "0x1931", + "0x1aec", + "0x19d", + "0x19e", + "0x19f", + "0x1a0", + "0x1a1", + "0x1a2", + "0x1a3", + "0x1a4", + "0x1a5", + "0x1a6", + "0x1a7", + "0x1a8", + "0x1a9", + "0x1aa", + "0x1967", + "0x1ac", + "0x1ad", + "0x197f", + "0x1ae", + "0x1af", + "0x1b0", + "0x1b1", + "0x1a77", + "0x1b2", + "0x1b3", + "0x1b5", + "0x1b6", + "0x1982", + "0x1b7", + "0x1b8", + "0x1b9", + "0x1aee", + "0x1ba", + "0x1bb", + "0x1bc", + "0x1bd", + "0x1be", + "0x1bf", + "0x1c0", + "0x1c1", + "0x1c2", + "0x1c3", + "0x1c5", + "0x1c6", + "0x1c7", + "0x1c8", + "0x1c9", + "0x1ca", + "0x1cb", + "0x1cc", + "0x1cd", + "0x1ce", + "0x1cf", + "0x1d0", + "0x1d1", + "0x1d2", + "0x1d3", + "0x1d4", + "0x1d6", + "0x1d7", + "0x19af", + "0x1d8", + "0x1d9", + "0x1af0", + "0x1da", + "0x1db", + "0x1dc", + "0x1dd", + "0x1de", + "0x1df", + "0x1e0", + "0x1e1", + "0x1e2", + "0x1e3", + "0x1e4", + "0x1e5", + "0x1e6", + "0x1e8", + "0x1e9", + "0x1ea", + "0x1eb", + "0x1ed", + "0x1ee", + "0x1ef", + "0x1f0", + "0x1f1", + "0x1f3", + "0x1f4", + "0x1f5", + "0x1f6", + "0x1f7", + "0x19db", + "0x1f8", + "0x1f9", + "0x1af2", + "0x1fa", + "0x1fb", + "0x1fc", + "0x1fd", + "0x1fe", + "0x200", + "0x201", + "0x202", + "0x203", + "0x204", + "0x205", + "0x206", + "0x207", + "0x208", + "0x209", + "0x20a", + "0x20b", + "0x20c", + "0x20d", + "0x20e", + "0x20f", + "0x210", + "0x211", + "0x212", + "0x213", + "0x214", + "0x215", + "0x216", + "0x217", + "0x218", + "0x219", + "0x21a", + "0x21b", + "0x1a0d", + "0x21c", + "0x21d", + "0x1af4", + "0x21f", + "0x220", + "0x221", + "0x1a6c", + "0x222", + "0x224", + "0x225", + "0x226", + "0x1a24", + "0x227", + "0x228", + "0x229", + "0x1a5a", + "0x22a", + "0x22b", + "0x22c", + "0x1a4a", + "0x22d", + "0x22e", + "0x1a3c", + "0x22f", + "0x230", + "0x232", + "0x233", + "0x234", + "0x235", + "0x237", + "0x238", + "0x239", + "0x23a", + "0x23b", + "0x23c", + "0x23d", + "0x23e", + "0x23f", + "0x240", + "0x241", + "0x242", + "0x243", + "0x244", + "0x245", + "0x246", + "0x247", + "0x1ac4", + "0x248", + "0x249", + "0x1ae8", + "0x24a", + "0x24b", + "0x1ae6", + "0x24d", + "0x1ae4", + "0x24e", + "0x24f", + "0x250", + "0x251", + "0x252", + "0x253", + "0x254", + "0x256", + "0x257", + "0x258", + "0x259", + "0x25a", + "0x25b", + "0x25c", + "0x25d", + "0x1b5f", + "0x1b57", + "0x1c21", + "0x1c18", + "0x1c11", + "0x1bae", + "0x1bbf", + "0x1bd8", + "0x1c03", + "0x1bf4", + "0x1c29", + "0x1c7d", + "0x1c76", + "0x1c6d", + "0x1c83", + "0x1dbf", + "0x1ca6", + "0x1cbd", + "0x1db0", + "0x1da0", + "0x1d93", + "0x1d81", + "0x1d74", + "0x1cf9", + "0x1d05", + "0x1d06", + "0x1d23", + "0x1d19", + "0x1d31", + "0x1d65", + "0x1d5f", + "0x1d6a", + "0x1f01", + "0x1de5", + "0x1dfb", + "0x1ef3", + "0x1ee4", + "0x1ed8", + "0x1ec7", + "0x1ebb", + "0x1e36", + "0x1e42", + "0x1e43", + "0x1e60", + "0x1e56", + "0x1e6c", + "0x1eb1", + "0x1ea2", + "0x1e9a", + "0x201a", + "0x200a", + "0x1f1f", + "0x1f24", + "0x1ff9", + "0x1f2d", + "0x1f32", + "0x1fe7", + "0x1f3b", + "0x1f40", + "0x1fd4", + "0x1f6f", + "0x1f5e", + "0x1f54", + "0x1fcf", + "0x1f9f", + "0x1f8e", + "0x1f84", + "0x1fcc", + "0x1fb0", + "0x1fc6", + "0x2046", + "0x203d", + "0x206c", + "0x2063", + "0x20e6", + "0x20dc", + "0x20ca", + "0x20c4", + "0x20d3", + "0x20f0", + "0x2102", + "0x2107", + "0x2161", + "0x210f", + "0x2114", + "0x2149", + "0x2144", + "0x2122", + "0x2127", + "0x213a", + "0x2134", + "0x2151", + "0x213e", + "0x214c", + "0x215a", + "0x220c", + "0x2203", + "0x21ee", + "0x21d9", + "0x21c7", + "0x21c1", + "0x21cf", + "0x2215", + "0x22b5", + "0x22a5", + "0x2235", + "0x2247", + "0x2243", + "0x224d", + "0x2262", + "0x2253", + "0x225f", + "0x2272", + "0x2294", + "0x228e", + "0x229c", + "0x2395", + "0x2383", + "0x237a", + "0x2367", + "0x2354", + "0x2342", + "0x233c", + "0x234b", + "0x238c", + "0x250b", + "0x23dc", + "0x24e9", + "0x24b6", + "0x2403", + "0x2400", + "0x23fd", + "0x2405", + "0x24a9", + "0x249f", + "0x2495", + "0x248b", + "0x2481", + "0x2471", + "0x2476", + "0x24db", + "0x24d8", + "0x24d5", + "0x24dd", + "0x2530", + "0x2532", + "0x253f", + "0x2544", + "0x2596", + "0x258d", + "0x2580", + "0x2571", + "0x2565", + "0x25ca", + "0x25af", + "0x25c0", + "0x2634", + "0x25e5", + "0x25ea", + "0x2629", + "0x25f6", + "0x25fb", + "0x2618", + "0x260d", + "0x26c3", + "0x264e", + "0x2653", + "0x26b8", + "0x265f", + "0x2664", + "0x26a7", + "0x269a", + "0x2686", + "0x269e", + "0x2692", + "0x2708", + "0x26dd", + "0x26e2", + "0x26fe", + "0x26f6", + "0x25f", + "0x260", + "0x261", + "0x279f", + "0x2770", + "0x276a", + "0x2764", + "0x262", + "0x275e", + "0x263", + "0x2758", + "0x264", + "0x2752", + "0x265", + "0x274e", + "0x266", + "0x267", + "0x269", + "0x2756", + "0x26a", + "0x275c", + "0x26b", + "0x2762", + "0x26c", + "0x2768", + "0x276e", + "0x26e", + "0x2774", + "0x26f", + "0x270", + "0x2787", + "0x271", + "0x278f", + "0x27a5", + "0x272", + "0x27c4", + "0x27b6", + "0x273", + "0x274", + "0x27d3", + "0x275", + "0x276", + "0x277", + "0x2833", + "0x2802", + "0x27f7", + "0x278", + "0x279", + "0x27a", + "0x27fe", + "0x27b", + "0x27c", + "0x27d", + "0x27e", + "0x2809", + "0x27f", + "0x280", + "0x281", + "0x282", + "0x2824", + "0x284", + "0x2815", + "0x283a", + "0x285", + "0x286", + "0x287", + "0x288", + "0x289", + "0x2886", + "0x28a", + "0x28b", + "0x28d", + "0x2879", + "0x28e", + "0x286c", + "0x285f", + "0x28f", + "0x290", + "0x28ca", + "0x291", + "0x292", + "0x28a1", + "0x293", + "0x294", + "0x28a7", + "0x296", + "0x297", + "0x28bf", + "0x298", + "0x299", + "0x28b5", + "0x29a", + "0x29b", + "0x29c", + "0x29d", + "0x29e", + "0x29f", + "0x2a0", + "0x28ee", + "0x28f7", + "0x29cc", + "0x2a1", + "0x2a2", + "0x2a3", + "0x291a", + "0x290b", + "0x2a4", + "0x2a5", + "0x29d3", + "0x2916", + "0x2921", + "0x2933", + "0x293c", + "0x29bc", + "0x295e", + "0x2950", + "0x29c3", + "0x295a", + "0x2965", + "0x2a6", + "0x2a7", + "0x29b3", + "0x2a8", + "0x29a3", + "0x2a9", + "0x2ab", + "0x299a", + "0x2ac", + "0x2ad", + "0x2ae", + "0x298e", + "0x2af", + "0x2b0", + "0x2b1", + "0x2b2", + "0x2b3", + "0x2b4", + "0x2b5", + "0x2b6", + "0x29ee", + "0x29f7", + "0x2b4d", + "0x2b7", + "0x2a1a", + "0x2a0b", + "0x2b54", + "0x2a16", + "0x2a21", + "0x2a33", + "0x2a3c", + "0x2a6b", + "0x2a60", + "0x2a4f", + "0x2a71", + "0x2a59", + "0x2b45", + "0x2b8", + "0x2b9", + "0x2ba", + "0x2bb", + "0x2b32", + "0x2bc", + "0x2bd", + "0x2be", + "0x2bf", + "0x2c0", + "0x2c1", + "0x2c2", + "0x2b22", + "0x2b14", + "0x2c3", + "0x2b08", + "0x2afd", + "0x2c4", + "0x2af3", + "0x2ae9", + "0x2ad1", + "0x2ae2", + "0x2ade", + "0x2c5", + "0x2c6", + "0x2c7", + "0x2c8", + "0x2b2a", + "0x2c9", + "0x2b55", + "0x2ca", + "0x2cb", + "0x2cc", + "0x2ce", + "0x2bb7", + "0x2bb2", + "0x2bad", + "0x2ba7", + "0x2bbb", + "0x2f15", + "0x2cf", + "0x2f04", + "0x2e8a", + "0x2e27", + "0x2e17", + "0x2d87", + "0x2ca8", + "0x2bea", + "0x2bee", + "0x2c94", + "0x2d0", + "0x2d1", + "0x2c88", + "0x2d2", + "0x2d3", + "0x2c08", + "0x2ca2", + "0x2c78", + "0x2c48", + "0x2c39", + "0x2c2d", + "0x2c53", + "0x2c75", + "0x2c6a", + "0x2d5", + "0x2c5e", + "0x2d6", + "0x2d2b", + "0x2d7", + "0x2d8", + "0x2d9", + "0x2cb1", + "0x2cb5", + "0x2d76", + "0x2ccb", + "0x2d81", + "0x2d66", + "0x2d59", + "0x2d48", + "0x2d16", + "0x2d07", + "0x2cfb", + "0x2d21", + "0x2d45", + "0x2d3a", + "0x2d2e", + "0x2da", + "0x2de0", + "0x2d8f", + "0x2d93", + "0x2e03", + "0x2dcb", + "0x2dbc", + "0x2db0", + "0x2dd6", + "0x2e00", + "0x2df5", + "0x2de9", + "0x2db", + "0x2dc", + "0x2e11", + "0x2e55", + "0x2e49", + "0x2e40", + "0x2e60", + "0x2e84", + "0x2e7c", + "0x2e70", + "0x2efa", + "0x2ec2", + "0x2eb4", + "0x2ea9", + "0x2ece", + "0x2ef4", + "0x2eea", + "0x2eda", + "0x2f49", + "0x2dd", + "0x2de", + "0x2f2a", + "0x2df", + "0x2e0", + "0x2e1", + "0x2f2f", + "0x2e2", + "0x2e3", + "0x2f3e", + "0x2e5", + "0x2e6", + "0x2e7", + "0x2e8", + "0x2e9", + "0x2ea", + "0x2eb", + "0x2f60", + "0x2f65", + "0x2fb6", + "0x2f6d", + "0x2f72", + "0x2fac", + "0x2fa7", + "0x2f83", + "0x2f88", + "0x2f9d", + "0x2f96", + "0x2ec", + "0x2ed", + "0x2ee", + "0x2fa2", + "0x2ef", + "0x2fb1", + "0x2f0", + "0x2f1", + "0x2ffb", + "0x2ff0", + "0x2fe1", + "0x2fd7", + "0x2fea", + "0x3005", + "0x303b", + "0x302f", + "0x3021", + "0x304f", + "0x305e", + "0x306d", + "0x2f2", + "0x307c", + "0x2f3", + "0x308b", + "0x2f4", + "0x309a", + "0x30a9", + "0x2f6", + "0x30b8", + "0x2f7", + "0x30c7", + "0x2f8", + "0x30d6", + "0x2f9", + "0x30e5", + "0x2fa", + "0x30f4", + "0x3103", + "0x2fb", + "0x3112", + "0x2fc", + "0x3121", + "0x312e", + "0x2fd", + "0x3226", + "0x321a", + "0x2fe", + "0x2ff", + "0x320a", + "0x31fc", + "0x300", + "0x31e8", + "0x3171", + "0x3177", + "0x317f", + "0x3191", + "0x3189", + "0x31d3", + "0x301", + "0x31c8", + "0x31be", + "0x302", + "0x31b5", + "0x303", + "0x304", + "0x305", + "0x307", + "0x308", + "0x3212", + "0x309", + "0x30a", + "0x3296", + "0x30c", + "0x30d", + "0x30e", + "0x30f", + "0x310", + "0x312", + "0x3286", + "0x327e", + "0x3278", + "0x313", + "0x314", + "0x315", + "0x316", + "0x328d", + "0x317", + "0x318", + "0x319", + "0x31a", + "0x32b2", + "0x31b", + "0x31c", + "0x32b7", + "0x31d", + "0x32c1", + "0x32c6", + "0x32cd", + "0x32d2", + "0x32db", + "0x32e0", + "0x31f", + "0x32ea", + "0x32ef", + "0x320", + "0x321", + "0x322", + "0x32f9", + "0x32fc", + "0x323", + "0x324", + "0x325", + "0x335a", + "0x326", + "0x327", + "0x328", + "0x330b", + "0x3310", + "0x3315", + "0x331a", + "0x331f", + "0x3324", + "0x3329", + "0x332e", + "0x3333", + "0x3338", + "0x333d", + "0x3342", + "0x3347", + "0x334c", + "0x3351", + "0x3355", + "0x329", + "0x32a", + "0x32b", + "0x32c", + "0x32d", + "0x32e", + "0x32f", + "0x330", + "0x331", + "0x332", + "0x333", + "0x334", + "0x335", + "0x336", + "0x337", + "0x338", + "0x339", + "0x33b", + "0x33c", + "0x33a0", + "0x3371", + "0x3376", + "0x3395", + "0x33d", + "0x338c", + "0x33f5", + "0x33ea", + "0x33da", + "0x33d0", + "0x33e3", + "0x33ff", + "0x3aa", + "0x4ae", + "0x599", + "0x69a", + "0x713", + "0x7d0", + "0x81c", + "0x943", + "0x993", + "0x9e3", + "0xa39", + "0xa89", + "0xb27", + "0xbbf", + "0xc01", + "0xc75", + "0xce9", + "0xdc5", + "0xe8b", + "0xeff", + "0xfa9", + "0xfff", + "0x107b", + "0x10f7", + "0x1158", + "0x11b9", + "0x123f", + "0x1300", + "0x139f", + "0x13e7", + "0x1440", + "0x14b0", + "0x1729", + "0x1b2b", + "0x1b6b", + "0x1b72", + "0x1c31", + "0x1c89", + "0x1dca", + "0x1f0b", + "0x2029", + "0x2054", + "0x207a", + "0x20f9", + "0x2168", + "0x221f", + "0x22c4", + "0x23a1", + "0x251f", + "0x2538", + "0x25a0", + "0x25d9", + "0x2642", + "0x26d1", + "0x2716", + "0x27e1", + "0x2895", + "0x28d9", + "0x29dc", + "0x2b5d", + "0x2bbf", + "0x2f1e", + "0x2f57", + "0x2fbd", + "0x300b", + "0x3049", + "0x3135", + "0x3232", + "0x32a2", + "0x3300", + "0x3365", + "0x33af", + "0x1afba", + "0x700900500400300a007009005004003008007006005004003002001000", + "0x300e00700900500400300d00700900500400300c00700900500400300b", + "0x500400301100700900500400301000700900500400300f007009005004", + "0x7009005004003014007009005004003013007009005004003012007009", + "0x19018007009005004003017007009005004003016007009005004003015", + "0x502000502000502000502000502000502000501f01b01e01d01c01b01a", + "0x21020005020005020005020005020005020005020005020005020005020", + "0x500400300700701b00702202102400701b00702202102300701b007022", + "0x2902800502702600500701b00702202101b007025005004003005007025", + "0x2f00202e02d00502d00501c01b02b01900900500900502c01b02b01902a", + "0x502d005035003034005033005004003032007006005004003031005030", + "0x500400303a00700900500400303900503800502d005035003037005036", + "0x700600500400303d00700900500400303c00700900500400303b007009", + "0x304100700600500400304000700600500400303f00700600500400303e", + "0x5004003044007006005004003043007006005004003042007006005004", + "0x7006005004003047007006005004003046007006005004003045007006", + "0x1902000504b00504a01b02b01d049005027026042005048005004003024", + "0x505000501c01b04f01900600504e04d04c01b01a01900900501c01b022", + "0x503500305600505500502d00503500305400505300505201b04f01d051", + "0x500400305a00700900500400305900700900500400305800505700502d", + "0x500900500900500900505e01b05d01905c00700900500400305b007009", + "0x506200502d00503500302d00502706106000503300500400300205f009", + "0x3066007009005004003065007009005004003064007006005004003063", + "0x1d06a00501c01b02201900600506901b02201902a068067007006005004", + "0x1b02201902000506f00506e01b02b01d02a06d05400506c00506b01b04f", + "0x2607400507300502d00503500305400507200507101b04f01d07000501c", + "0x500400307800700900500400302000507700507601b02b01d075005027", + "0x507b00507b00507b00507b00507b00501c01b01e01902a07a079007009", + "0x507b00507b00507b00507b00507b00507b00507b00507b00507b00507b", + "0x307d00700600500400307c00707b00500400304300707b00500400307b", + "0x500400308100700600500400308000707b00500400307f00507e005004", + "0x507e00500400301600707b00500400308300707b005004003082007006", + "0x308600507e00500400301700707b00500400308500707b005004003084", + "0x500400308800507e00500400301800707b00500400308700707b005004", + "0x708900500400308900502706102a08b07d00707b00500400308a007089", + "0x3015007089005004003016007089005004003017007089005004003018", + "0x5004003012007089005004003013007089005004003014007089005004", + "0x707b00500400304500707b00500400304400707b00500400308c007006", + "0x500400307b00502706108d00507e00500400304700707b005004003046", + "0x1d09000502702602000508f00508e01b02b01d02d00502702602000707b", + "0x1b02b01d00900508900500600509401b09301902000509200509101b02b", + "0x9c09b00509a09909800504e097096007006005004003020005090005095", + "0x30a000700600500400309f00501c01b09e01901b00709a09d09800504e", + "0x50a30050a201b04f01d02000505100501c01b04f0190a1007006005004", + "0x50a901b0a80190a70050a601b0220190a50050270a404900504e04d054", + "0x700600500400300700707b0050040030aa0050270a407b0050060050a5", + "0x50aa00501c01b04f0190ad0070060050040030ac0070060050040030ab", + "0x70060050040030b000707b0050040030540050af0050ae01b04f01d020", + "0x50b600509e0b50240070b40b30070070b40b30050070b40b302a0b20b1", + "0xbc00500709a09d0bb00509a0ba0b90050b600509e0b80470070b40b30b7", + "0x50bf0050bf0050be01b05d0190bd00701b0070220210b900509f00509e", + "0x210050070c40050040030c20050270c30c200504e0c10020c00bf0050bf", + "0x50270c601b00701b00702202101b0070c5005004003005007005007022", + "0x30c700700600500400302d0070060050040030450070bf0050040030c2", + "0x50cb0050cb00501c01b0ca0190020c90c200504e0970c8007006005004", + "0x1b09e0190c200504e09c0cc00509a0990240070bf0050040030cb0050cb", + "0x50040030bf0050bf0050bf0050bf00501c01b05d01902a0ce0cd00501c", + "0x503002f0020d10d000503002f0020cf0440070bf00500400301b0070bf", + "0x500400300500707b0050040030d400503002f0020d30aa00503002f0d2", + "0x6102a0d90d80070060050040030d700700600500400302a0d60d5007006", + "0x501c01b02b0190dc0070060050040030db0070060050040030da005027", + "0xe102a0e00050070df0050040030200050de0050dd01b02b01d009005009", + "0x30e50070060050040030060050e401b0220190e30050e201b02201902a", + "0x50040030e80070060050040030e70070060050040030e6007006005004", + "0x1b0220190200050200050ea01b02b01d02400707b0050040030e9007006", + "0x30ef0050ee00502d0050350030540050ed0050ec01b04f01d0eb00501c", + "0x30f30070090050040030f20070090050040030f10050f000502d005035", + "0x30f70050f600502d0050350030f50070090050040030f4007009005004", + "0x30fb0070090050040030fa0070090050040030f90050f800502d005035", + "0x30ff0050fe00502d0050350030fd0070090050040030fc007009005004", + "0x310300700900500400310200700900500400310100510000502d005035", + "0x310700510600502d005035003105007009005004003104007009005004", + "0x310b00700900500400310a00700900500400310900510800502d005035", + "0x11010f00510e00502d00503500310d00700900500400310c007009005004", + "0x511300511201b02b01d0bd00700900500400311100700900500400302a", + "0x511601b04f01d11500501c01b02201900600502000511401b02b01d020", + "0x511900502d0050350030eb00502d00502d00511801b093019054005117", + "0x700900500400311c00700900500400311b00501800502d00503500311a", + "0x512000502d00503500311f00700900500400311e00700900500400311d", + "0x3124007009005004003123007009005004003122007006005004003121", + "0x500400312600512500502d00503500300900502706103f005048005004", + "0x502d005035003129007009005004003128007009005004003127007006", + "0x500400312e00700900500400312d00512c00502d00503500312b00512a", + "0x700600500400313100700900500400313000700900500400312f007009", + "0x700900500400313500700600500400313400513300502d005035003132", + "0x502d00503500313900513800502d005035003137007009005004003136", + "0x507b00507b00507b00501c01b13b01913a00707b005004003139005139", + "0x1b02201913c0050270a407b00504e04d07b00507b00507b00507b00507b", + "0x514201b04f01d02000514100514000501c01b09301902a13f13e00513d", + "0x514b00514a005149005148005147005146005145005144003054005143", + "0x314f00707b00500400314e00707b00500400314500502702614d00514c", + "0x500400315200707b00500400315100707b00500400315000707b005004", + "0x501c01b04f01915500707b00500400315400707b00500400315300707b", + "0x500400315800707b00500400305400515700515601b04f01d02000513c", + "0x700600500400315b00700600500400315a007006005004003159007006", + "0x4d15f00700900500400315e00700600500400315d00700900500400315c", + "0x516000501c01b04f01916200516101b0220191600050270a408900504e", + "0x1b0220191650050270a402d00504e04d05400516400516301b04f01d020", + "0x516a00516901b04f01d02000516000516800501c01b0a8019167005166", + "0x300700700600500400300500700900500400301b007009005004003054", + "0x500400316d00700600500400316c00700600500400316b007006005004", + "0x1b0220191700050270a409000504e04d16f00700600500400316e007006", + "0x517500517401b04f01d0eb00517300517300501c01b093019172005171", + "0x517800517800501c01b09301917700517601b0220190510050270a4054", + "0x1902a17d17c00502702617b00502702605400517a00517901b04f01d0eb", + "0x1b18401918300502702600600518200518200518100518000517f01b17e", + "0x5009005173005006005006005006005178005009005182005006005185", + "0x503002f18700503002f00218617b00503002f17800507b00507b005178", + "0x1b04f01902000517000518901b04f01d02000517300518801b02b01d182", + "0x517800518d01b02b01d05400518c00518b01b04f01d18a00517800501c", + "0x503002f05400519000518f01b04f01d18e00517800501c01b02b019020", + "0x3192007006005004003005007089005004003191007006005004003178", + "0x500600519601b02b019195007006005004003002194193007006005004", + "0x1b01a01919a00700600500400300219902000519800519701b02b01d0de", + "0x500400305400519e00519d01b04f01d00600519c00501c01b02b01919b", + "0x1b04f01d02000519c00501c01b1a10191a000700600500400319f007006", + "0x1a70021a60060050b41a500600504e1a40060050270610540051a30051a2", + "0x1d02000501c01b1aa0191a90070060050040031a800700600500400302a", + "0x501c01b02b01902000517b0051ad01b02b01d0540051ac0051ab01b04f", + "0x50890050890051b101b0930190540051b00051af01b04f01d1ae005178", + "0x508900501c01b02b01917c00503002f02000517c0051b201b02b01d182", + "0x305100503002f01b0070890050040030540051b40051b301b04f01d020", + "0x517800501c01b04f0190200050510051b601b04f01d1b5007006005004", + "0x51bb0051ba01b02b01d0060050270260540051b90051b801b04f01d1b7", + "0x50040030050070060050040031bc00700600500400300600503002f020", + "0x70060050040031bd00700600500400302300700600500400301b007006", + "0x1c001b00707b00500400317800501c01b0220191bf0070060050040031be", + "0x1b02b01d02a1c41c30070060050040030540051c20051c101b04f01d02a", + "0x1b1cc1780050051cb01b1ca01b1c901b1c81c70021c60200050060051c5", + "0x1d20050071d10060050051d00060050051cf0060050051ce01b0050051cd", + "0x1d20050071d10200050051d401b1d31d20050051cd1770050051cd01b007", + "0x51d81bb0050051d81770050051d801b1d701b1d61d20050051d5005007", + "0x51dd0060050051cd1dc0050051db0060050051da0060050051d81d9005", + "0x1df0050051cd0050071de0050071d10540050051d40500050051d4006005", + "0x1e30050051db01b1e21e10050051cd01b1e01de0050051cd1870050051cd", + "0x510050051e701b1e601b1e507b0050051cd1d90050051e407b0050051e4", + "0x51cd01b0071de0050071d11c20050051d41780050051d40510050051d8", + "0x51db1e90050051db0200050051d81e80050051db07b0050051d8051005", + "0x51db1ed0050051db1ec0050051db1eb0050051db1780050051d81ea005", + "0x1b0071f30050071d101b1f20060050051f101b1f00060050051ef1ee005", + "0x51f41780050051cd1f30050051d50050071f30050071d11f30050051cd", + "0x71d11820050051d81b70050051cd1b90050051cb1f60050051d51f5024", + "0x51ef1f90050051d81f80050051db01b1f71b70050051d50050071b7005", + "0x1fc0050051db0510050051f11fb0050051d80890050051d801b1fa051005", + "0x1b40050051d81fd0050051d51920240051f40890050051cd0890050051e7", + "0x51f417c0050051f11ff0050051d50370240051f417c0050051ef01b1fe", + "0x51d817b0050051d81ae0050051d51b00050051cb2000050051d5039024", + "0x51cd17c0050051cd19c0050051d819c0050051e719c0050051d417c005", + "0x51db2020050051db1ac0050051d82010050051d50380240051f417b005", + "0x51f42060050051cd01b2072060050051d801b2052040050051d8203005", + "0x51f420c0050051cd00600500520b20a0050051cd01b20901b208036024", + "0x51d80eb0050051cd0050070eb0050071d101b20f20e0050051d820d024", + "0x2130240051f401b21201b2110eb0050051d801b0070eb0050071d1210005", + "0x2160240051f40310050051cd2150240051f41a30050051d82140050051d5", + "0x51d521b0240051f421a0050051db2190050051db01b2182170240051f4", + "0x51e421f0240051f421e0240051f421d0050051db19e0050051cb21c005", + "0x2230240051f42220240051f42210050051cd01b2201820050051e4006005", + "0x1980050051e72250240051f41980050051cd1980050051d82240050051d5", + "0x90050051d00de0050051cb0de0050051d81980050051cb1980050051e4", + "0x51db04b0240051f42290240051f42280050051cd2270050051db01b226", + "0x51f40d00050051cd0d40050051cd0d20050051cd22b0050051db22a005", + "0x51cd01b23001b22f22e00700522d0540050051cd0530240051f422c024", + "0x51cd01b0071f60050071d11b90050051d401b0071b70050071d11d9005", + "0x51e401b2310890050051d00890050051e40050071f60050071d11f6005", + "0x50071fd0050071d12350050051db01b2342330050051db01b232177005", + "0x71d117c0050051d401b0071fd0050071d11b40050051d41fd0050051cd", + "0x1b2361780050051ef0050071ff0050071d11ff0050051cd01b0071ff005", + "0x1780050051f118e0050051d51900050051cb2370050051d50500240051f4", + "0x18c0050051cb2380050051d50510240051f41700050051cd0900050051da", + "0x2390050071d11730050051d41700050051d81700050051e718a0050051d5", + "0x2000050071d10090050051d80050072390050071d12390050051cd01b007", + "0x1ae0050071d117b0050051d401b23a2390050051d52000050051cd005007", + "0x1ae0050071d11730050051d801b0072000050071d11b00050051d401b007", + "0x1b23c17b0050051ef1870050051ef1820050051ef23b0050051d8005007", + "0x17c0050051cf1800050051cd1830050051cb1830050051cf23d0050051cd", + "0x1810050051cd1870050051f117c0050051cb17c0050051e417c0050051e7", + "0x17b0050051cf1820050051d01810050051d823e0050051d81820050051f1", + "0x51d001b23f17b0050051cb17b0050051e417b0050051e717b0050051f1", + "0x2420050051d50540240051f401b2410060050052401780050051e4178005", + "0x1730050051d01df0050051d001b0050051d00eb0050051d517a0050051cb", + "0x2430240051f41730050051cd0900050052401730050051cb1730050051e4", + "0x2010050071d11ac0050051d407b0050051d01750050051cb2440050051d5", + "0x2460050051db0050072010050071d12450050051db2010050051cd01b007", + "0x24b0050051d824a0050051d82490050051db2480050051db2470050051db", + "0x51da20e0050051cd00600500524e24d0050051db01b24c2060050051e4", + "0x51dd02d0050051cd02d0050051d41390050051db1380050051db02d005", + "0x51cd1680050051d41650050051d81650050051e70890050051da02d005", + "0x51d816a0050051cb2500050051d524f0240051f41600050051cd168005", + "0x51d81600050051e71640050051cb2520050051d52510240051f4168005", + "0x90050051cd2550050051db02d0050051cb01b2542530050051d4160005", + "0x51dd2570050051db2140050051cd0050072140050071d12560050051db", + "0x51cd0060050052592580050051db02d0050051d82530050051cd089005", + "0x25b0050051db01b0072140050071d11a30050051d425a0050051db1bb005", + "0x25d0050051db07b0050051da0500050051d80540050051cb25c0050051db", + "0x26000500725f25e0050051d50560240051f413c0050051cd07b0050051dd", + "0x1400050051d413c0050051d813c0050051e71570050051cb01b26101b007", + "0x1430050051cb2620050051d50580240051f41410050051cd1400050051cd", + "0x51db1450050051cb1450050051cf2640050051cd01b2631400050051d8", + "0x700050051d80700050051e701b2682670050051db2660050051db265005", + "0x26a0050051db2690050051db06f0050051d80700050051d50700050051cd", + "0x51e701b26e02d0050051e426d0050051db26c0050051db26b0050051db", + "0x1b2720480050051cd2710050051db2700050051db26f0050051db02d005", + "0x51d42770050051db2760050051db2750050051db01b2742730050051db", + "0x51d50570240051f406a0050051cd2780050051cd06a0050051d4278005", + "0x27b0050051d827b0050051e701b27a1150050051d51170050051cb279005", + "0x27d0050051db27c0050051db1130050051d827b0050051d527b0050051cd", + "0x51db2820050051db2810050051db2800050051db01b27f27e0050051db", + "0x51d50550240051f41130050051cd2850050051db2840050051db283005", + "0x21c0050071d100600500528901b2882870050051db0ed0050051d8286005", + "0x51d41870050051d028b0050051db28a0050051db21c0050051cd005007", + "0x28e0050051db28d0050051db28c0050051db01b00721c0050071d119e005", + "0x1b29101b29028f0050051cb28f0050051d828f0050051e728f0050051d4", + "0xe30050051d02920050051cb2920050051d82920050051e72920050051d4", + "0x71d10de0050051d40e30050051d801b2942930050051db0e30050051e4", + "0x51d42950050051d50050072950050071d12950050051cd01b007295005", + "0x1b2960050072240050071d12240050051cd01b0072240050071d1198005", + "0x51db0da00500529b29a0050051cd01b2992980050051db2970050051db", + "0xda0050051d80da0050051cd01b29e0da0050051e429d0050051db29c005", + "0x29a0050051d801b2a401b2a32a20050051cd01b2a12a00050051db01b29f", + "0x2a80050051db1800050051d80e30050051cd2a700700522d01b2a601b2a5", + "0x2a90050051db0d00050051ef0d20050051ef0aa0050051ef0d40050051ef", + "0x51db0c20050052ad01b2ac2ab0050051cd2ab0050051d42aa0050051db", + "0x52b22b00050051cd2b10050051cd2b00050051d40bf0050052af2ae005", + "0x51d82b60050051d82b50050051d82b40050051d82b30050051d80c2005", + "0x51db2bb0050051db2ba0050051db2b90050051db2b80050051d82b7005", + "0x51cd0c50050051cd2bf0050051db2be0050051db0c20050052bd2bc005", + "0xd00050051f10d40050051f10cd0050c20050072c10c20050052c00c4005", + "0x1b2c40cb0050051cd01b2c30070070052c20240070052c20470070052c2", + "0x2c60240051f42c50050051cd2c50050051d42c50050051d82c50050051e7", + "0xaa0050051d42c80050051db2c70050051db0490050051da0d20050051f1", + "0x2cb0050051db0af0050051cb2ca0050051d52c90240051f40aa0050051cd", + "0xaa0050051e70aa0050051f12ce0050051db2cd0050051db2cc0050051db", + "0x490050052400a70050051e40aa0050052d02cf0050051e40aa0050051d8", + "0x51cb2d40050051d52d30240051f42d20050051cd2d20050051d401b2d1", + "0x1b2d72d60050051db2d50050051d82cf0050051d80a70050051d80a3005", + "0x980050052b22d90050051cd0980050052ad2d80050051db2b10050051d8", + "0x51d401b00718e0050071d10060050052db2d90050051d82da0050051d8", + "0x51db0050072370050071d12370050051cd01b0072370050071d1190005", + "0x71d118c0050051d401b00718a0050071d100500718e0050071d12dc005", + "0x900050051dd0870050051d50330240051f42380050051cd01b007238005", + "0x2420050071d117a0050051d40050072380050071d100500718a0050071d1", + "0x2dd0050071d10900050051ce0050072420050071d12420050051cd01b007", + "0x2dd0050051d50050072dd0050071d12dd0050051cd1720050051cd01b007", + "0x900050051d80900050051cb0900050051e40900050051cd0900050051cf", + "0x71d11720050051d82440050051cd01b0072440050071d11750050051d4", + "0x51cd01b0072de0050071d102d0050051ce1680050051cb005007244005", + "0x2d0050051cf2de0050051d50050072de0050071d12de0050051cd167005", + "0x51d42500050051cd0050072500050071d10600240051f402d0050051d0", + "0x7e0050051cd2df0050051db08900500524001b0072500050071d116a005", + "0x51db2e40050051db2e30050051db2e20050051db2e10050051db01b2e0", + "0x2e70050051db2e60050051db2520050051cd0050072520050071d12e5005", + "0x2ec0050051db2eb0050051db2ea0050051db2e90050051db2e80050051db", + "0x1640050051d42f00050051db2ef0240051f407f0050051db01b2ee01b2ed", + "0x51db0840050051db2f10050051db07b00500524001b0072520050071d1", + "0x51db07e0050051d02f40050051db0860050051db2f30050051db2f2005", + "0x1b2f907b0050890050072f801b2f72f60050051db0880050051db2f5005", + "0x51db2fb0050051db25e0050051cd00500725e0050071d12fa0050051db", + "0x51db2ff0050051db0630240051f42fe0050051db2fd0050051db2fc005", + "0x750050053011400050051cb01b00725e0050071d11570050051d4300005", + "0x50073020050071d13020050051cd13e0050051cd01b0073020050071d1", + "0x2620050051cd0050072620050071d101b3030770050051d03020050051d5", + "0x51cb2780050051e41410050051d801b0072620050071d11430050051d4", + "0x2780050051d806a0050051d801b3040090050051e40340050051db278005", + "0x3060240051f406f0050051cd0720050051cb3050050051d50620240051f4", + "0x1150050071d106a0050051cb06a0050051e706c0050051cb3070050051d5", + "0x3060050051db2790050051cd01b0072790050071d11170050051d401b007", + "0x600050051db2ef0050051db0050072790050071d10050071150050071d1", + "0x2d00500529b01b30901b3080330050051cd0330050051e42d30050051db", + "0x1b30b24f0050051db2510050051db2c60050051d801b30a0060240051f4", + "0x2860050071d12860050051cd01b0072860050071d10ed0050051d401b30c", + "0x51d00bf0050051d82c50050051cb2c50050051e40330050051d8005007", + "0x2430050051d506a0240051f40aa0050051cb0060050bf00500730d0bf005", + "0x510050051d00490050051dd01b30f0a50050051d801b30e0530050051cb", + "0x71d10af0050051d40aa0050051d02ca0050051cd0050072ca0050071d1", + "0x51cd01b00722c0050071d10490050051ce2d20050051cb01b0072ca005", + "0x490050051cf22c0050051d500500722c0050071d122c0050051cd0a7005", + "0x2d40050051cd01b0072d40050071d10a30050051d401b3100490050051d0", + "0x1b0070870050071d10900050051d40050072d40050071d12d20050051d8", + "0x890050090050072f82290050051db0050070870050071d10870050051cd", + "0x21e0050051db21f0050051db2220050051db2230050051db2250050051db", + "0x2130050051db2150050051db2160050051db2170050051db21b0050051db", + "0x1b31207c0050051db1f50050051db1920050051db01b31120d0050051db", + "0x51cd01b0073050050071d10720050051d401b0070700050071d101b313", + "0x51ef0050070700050071d10b00050051db0050073050050071d1305005", + "0x53140280050051cd0280050051d80280050051e70280050051d4031005", + "0x6c0050051d401b3160310050051f106c0240051f4028005005315028005", + "0x3170050051d80050073070050071d13070050051cd01b0073070050071d1", + "0x2500500731c31b0050051db0250050051cd31a0050051db01b31901b318", + "0x730d02500531d00500731c31d0050051cd00900531d00500730d025005", + "0x532031f00507b0050072f82c60050051cd2c60050051d400900531e005", + "0x51db0230050051db07d0050051db3210050051d53210050051cd321005", + "0x51db0410050051db0400050051db1930050051db03f0050051db03e005", + "0x51db0460050051db0450050051db0440050051db0430050051db042005", + "0x1b0072430050071d10530050051d40070050051db0240050051db047005", + "0x1b3223070240051f40050072430050071d10050050051db2430050051cd", + "0x1b0440450072c504604700732300700501b00700501b01b32300501b01b", + "0x1b01b32300501b04701b04300532300502400502401b01b32300501b007", + "0x1b04000503e04104200732300704300504501b047005323005047005046", + "0x532300519300504301b19300532300504100504401b01b32300501b007", + "0x504001b02300532300504200504101b03e00532300503f00504201b03f", + "0x1b03f01b01b32300501b00701b01b31f00501b19301b07d00532300503e", + "0x2300532300504000504101b32100532300502000503e01b020005323005", + "0x1b31e0052cc31f00532300707d00502301b07d00532300532100504001b", + "0x701b31a0050aa31b31d00732300731f04700707d01b01b32300501b007", + "0x2500732300702300504501b31d00532300531d00504601b01b32300501b", + "0x4301b02d00532300532400504401b01b32300501b00701b00900507c324", + "0x32300502500504101b03100532300502800504201b02800532300502d005", + "0x501b00701b01b03800501b19301b0b000532300503100504001b317005", + "0x504101b1f500532300507c00503e01b07c00532300501b03f01b01b323", + "0x53230070b000502301b0b00053230051f500504001b317005323005009", + "0x24f03803900732300731700504501b01b32300501b00701b037005092192", + "0x32300503900532101b01b32300501b02001b01b32300501b00701b036005", + "0x519200531d01b01b32300531b00531e01b01b32300503800531f01b01b", + "0x21300502501b21300532300501b31a01b20d00532300501b31b01b01b323", + "0x21600532300501b00901b21500532300521320d00732401b213005323005", + "0x504601b21b00532300521700502801b21700532300521521600702d01b", + "0x532300500700531701b04600532300504600503101b31d00532300531d", + "0x32300501b00701b21b00704631d04700521b00532300521b0050b001b007", + "0x521e0051f501b21e00532300501b07c01b01b32300503600532101b01b", + "0x701b2252230072eb22221f00732300721e04631d02419201b21e005323", + "0x4b22900732300522900503901b22900532300501b03701b01b32300501b", + "0x504601b04b00532300504b00503601b22c31b00732300531b00503801b", + "0x242fa05005300732300719222c04b00722204620d01b21f00532300521f", + "0x503601b05300532300505300503101b01b32300501b00701b243054051", + "0x242ff05625124f02432300731b22905005304721301b229005323005229", + "0x32300501b31b01b01b32300501b02001b01b32300501b00701b055057058", + "0x1b2c90053230050562c600732401b05600532300505600502501b2c6005", + "0x503300521701b01b3230052d300521601b0332d30073230052c9005215", + "0x1b0630053230052ef00521e01b2ef00532300506000521b01b060005323", + "0x525100531701b24f00532300524f00503101b21f00532300521f005046", + "0x1b00701b06325124f21f0470050630053230050630050b001b251005323", + "0x1b30600532300505700531701b06200532300505800503101b01b323005", + "0x1b01b32300501b00701b01b2f300501b19301b00600532300505500521f", + "0x532300505100503101b01b32300522900522201b01b32300531b00531e", + "0x1b02001b00600532300524300521f01b30600532300505400531701b062", + "0x1b06c00532300500606a00702d01b06a00532300501b00901b01b323005", + "0x506200503101b21f00532300521f00504601b30700532300506c005028", + "0x53070053230053070050b001b30600532300530600531701b062005323", + "0x531e01b01b32300501b02001b01b32300501b00701b30730606221f047", + "0x22301b06f00532300501b31b01b01b32300519200531d01b01b32300531b", + "0x32300507006f00732401b07000532300507000502501b07000532300501b", + "0x2801b03400532300507230500702d01b30500532300501b00901b072005", + "0x32300522500503101b22300532300522300504601b077005323005034005", + "0x470050770053230050770050b001b00700532300500700531701b225005", + "0x3700522501b01b32300501b02001b01b32300501b00701b077007225223", + "0x1b31b01b01b32300531700532101b01b32300531b00531e01b01b323005", + "0x1b07400532300507400502501b07400532300501b22901b302005323005", + "0x7307b00702d01b07b00532300501b00901b073005323005074302007324", + "0x31d00532300531d00504601b30000532300507500502801b075005323005", + "0x3000050b001b00700532300500700531701b04600532300504600503101b", + "0x2300532101b01b32300501b00701b30000704631d047005300005323005", + "0x1b00701b01b2c800501b19301b2ff00532300531a00504601b01b323005", + "0x504601b01b32300502300532101b01b32300531e00522501b01b323005", + "0x4b01b2fe00532300501b31b01b01b32300501b02001b2ff005323005047", + "0x3230052fd2fe00732401b2fd0053230052fd00502501b2fd00532300501b", + "0x2801b2fa0053230052fc2fb00702d01b2fb00532300501b00901b2fc005", + "0x32300504600503101b2ff0053230052ff00504601b2f60053230052fa005", + "0x470052f60053230052f60050b001b00700532300500700531701b046005", + "0x1b31b01b01b32300502400522c01b01b32300501b00701b2f60070462ff", + "0x1b2f50053230052f500502501b2f500532300501b22301b088005323005", + "0x2f408600702d01b08600532300501b00901b2f40053230052f5088007324", + "0x4500532300504500504601b2f20053230052f300502801b2f3005323005", + "0x2f20050b001b00700532300500700531701b04400532300504400503101b", + "0x1b00700501b01b32300501b01b01b2f20070440450470052f2005323005", + "0x2400502401b01b32300501b00701b044045007133046047007323007005", + "0x4200732300704300504501b04700532300504700504601b043005323005", + "0x531f01b01b32300504200532101b01b32300501b00701b04000529c041", + "0x2501b03f00532300501b31a01b19300532300501b31b01b01b323005041", + "0x32300501b00901b03e00532300503f19300732401b03f00532300503f005", + "0x1b02000532300507d00502801b07d00532300503e02300702d01b023005", + "0x500700531701b04600532300504600503101b047005323005047005046", + "0x1b00701b0200070460470470050200053230050200050b001b007005323", + "0x51f501b32100532300501b07c01b01b32300504000532101b01b323005", + "0x31b31d00726f31e31f00732300732104604702419201b321005323005321", + "0x532300531a00502501b31a00532300501b05301b01b32300501b00701b", + "0x1b32300501b00701b00900511532402500732300731a31f00707d01b31a", + "0x32300502d00503901b02800532300501b05001b02d00532300501b03701b", + "0x3100532300503100503601b31732400732300532400503801b03102d007", + "0x31e04620d01b02500532300502500504601b02800532300502800502501b", + "0x1b32300501b00701b0371921f502410907c0b0007323007028317031007", + "0x502d00503601b0b00053230050b000503101b03900532300501b05101b", + "0x703932402d07c0b004620d01b03900532300503900502501b02d005323", + "0x32300501b31b01b01b32300501b00701b21521320d024101036038007323", + "0x21701b01b32300521700521601b21b21700732300521600521501b216005", + "0x32300521f00521e01b21f00532300521e00521b01b21e00532300521b005", + "0x31701b03800532300503800503101b02500532300502500504601b222005", + "0x2220360380250470052220053230052220050b001b036005323005036005", + "0x32300520d00503101b22300532300502500504601b01b32300501b00701b", + "0x19301b04b00532300521500521f01b22900532300521300531701b225005", + "0x531e01b01b32300502d00522201b01b32300501b00701b01b11900501b", + "0x2250053230051f500503101b22300532300502500504601b01b323005324", + "0x501b19301b04b00532300503700521f01b22900532300519200531701b", + "0x32300501b05401b22c00532300501b31b01b01b32300501b00701b01b119", + "0x1b05000532300505322c00732401b05300532300505300502501b053005", + "0x500700531701b22500532300531e00503101b223005323005009005046", + "0x2d01b05100532300501b00901b04b00532300505000521f01b229005323", + "0x522300504601b24300532300505400502801b05400532300504b051007", + "0x1b22900532300522900531701b22500532300522500503101b223005323", + "0x1b01b32300501b00701b2432292252230470052430053230052430050b0", + "0x532300525100502501b25100532300501b22301b24f00532300501b31b", + "0x702d01b05800532300501b00901b05600532300525124f00732401b251", + "0x32300531d00504601b05500532300505700502801b057005323005056058", + "0xb001b00700532300500700531701b31b00532300531b00503101b31d005", + "0x22c01b01b32300501b00701b05500731b31d047005055005323005055005", + "0x1b2c900532300501b22301b2c600532300501b31b01b01b323005024005", + "0x501b00901b2d30053230052c92c600732401b2c90053230052c9005025", + "0x2ef00532300506000502801b0600053230052d303300702d01b033005323", + "0x700531701b04400532300504400503101b04500532300504500504601b", + "0x24301b2ef0070440450470052ef0053230052ef0050b001b007005323005", + "0x1b01b01b32300501b24f01b04400532300501b24301b04600532300501b", + "0x701b04004100732504204300732300700501b00700501b01b32300501b", + "0x4601b01b32300501b04701b19300532300502400502401b01b32300501b", + "0x701b02300516003e03f00732300719300504501b043005323005043005", + "0x2000532300507d00504301b07d00532300503e00504401b01b32300501b", + "0x32100504001b31f00532300503f00504101b32100532300502000504201b", + "0x501b03f01b01b32300501b00701b01b16500501b19301b31e005323005", + "0x1b31f00532300502300504101b31b00532300531d00503e01b31d005323", + "0x701b31a00532604500532300731e00502301b31e00532300531b005040", + "0x32300704504300705601b04500532300504504400725101b01b32300501b", + "0x2500532300502500504601b01b32300501b00701b009005327324025007", + "0x4401b01b32300501b00701b03100517202802d00732300731f00504501b", + "0x3230050b000504201b0b000532300531700504301b317005323005028005", + "0x19301b19200532300507c00504001b1f500532300502d00504101b07c005", + "0x503e01b03700532300501b03f01b01b32300501b00701b01b17800501b", + "0x532300503900504001b1f500532300503100504101b039005323005037", + "0x25101b01b32300501b00701b03800532804700532300719200502301b192", + "0x1b21300523e20d0360073230071f500504501b047005323005047046007", + "0x532300503600504101b21500532300520d00505801b01b32300501b007", + "0x32300501b00701b01b18a00501b19301b21700532300521500505701b216", + "0x21300504101b21e00532300521b00505501b21b00532300501b03f01b01b", + "0x21f0053230072170052c601b21700532300521e00505701b216005323005", + "0x521f00504401b01b32300501b02001b01b32300501b00701b2220051ac", + "0x4301b22900532300521600521701b22500532300501b31b01b223005323", + "0x32300504200503101b02500532300502500504601b04b005323005223005", + "0x2501b22500532300522500521f01b2290053230052290052c901b042005", + "0x5005322c02432300504b2252290420250462d301b04b00532300504b005", + "0x506001b01b32300501b00701b0540051a305100532300705000503301b", + "0x32300522c00504601b25100532300524300502401b24f243007323005051", + "0x2ef01b05700532300525100504101b05800532300505300503101b056005", + "0x6301b01b32300501b00701b01b1fd00501b19301b05500532300524f005", + "0x2c600532300505400502801b01b32300504700531d01b01b323005324005", + "0x700531701b05300532300505300503101b22c00532300522c00504601b", + "0x701b2c600705322c0470052c60053230052c60050b001b007005323005", + "0x1b03f01b01b32300522200522501b01b32300501b02001b01b32300501b", + "0x5600532300502500504601b2d30053230052c900506201b2c9005323005", + "0x2d30052ef01b05700532300521600504101b05800532300504200503101b", + "0x32300501b00701b06000532903300532300705500530601b055005323005", + "0x1b01b32300501b00701b0620051dc0632ef00732300705700504501b01b", + "0x1b32300503300521601b01b32300506300531f01b01b3230052ef005321", + "0x532300501b31b01b01b32300532400506301b01b32300504700531d01b", + "0x30600732401b00600532300500600502501b00600532300501b31a01b306", + "0x532300506a06c00702d01b06c00532300501b00901b06a005323005006", + "0x503101b05600532300505600504601b06f00532300530700502801b307", + "0x532300506f0050b001b00700532300500700531701b058005323005058", + "0x1b32300506200532101b01b32300501b00701b06f00705805604700506f", + "0x5805602419201b0700053230050700051f501b07000532300501b07c01b", + "0x3300521501b01b32300501b00701b07703400732a305072007323007070", + "0x7300532300507400521701b01b32300530200521601b074302007323005", + "0x7b02432300707304732400730504600601b07200532300507200504601b", + "0x532300530000521b01b01b32300501b00701b2fd2fe2ff02432b300075", + "0x503101b07200532300507200504601b2fb0053230052fc00521e01b2fc", + "0x53230052fb0050b001b07500532300507500531701b07b00532300507b", + "0x2fa00532300501b00901b01b32300501b00701b2fb07507b0720470052fb", + "0x504601b0880053230052f600502801b2f60053230052fd2fa00702d01b", + "0x53230052fe00531701b2ff0053230052ff00503101b072005323005072", + "0x32300501b00701b0882fe2ff0720470050880053230050880050b001b2fe", + "0x532400506301b01b32300504700531d01b01b32300503300521601b01b", + "0x2f400502501b2f400532300501b22301b2f500532300501b31b01b01b323", + "0x2f300532300501b00901b0860053230052f42f500732401b2f4005323005", + "0x504601b0840053230052f200502801b2f20053230050862f300702d01b", + "0x532300500700531701b07700532300507700503101b034005323005034", + "0x32300501b00701b0840070770340470050840053230050840050b001b007", + "0x504700531d01b01b32300505700532101b01b32300506000522501b01b", + "0x501b06a01b2f100532300501b31b01b01b32300532400506301b01b323", + "0x7f0053230052f02f100732401b2f00053230052f000502501b2f0005323", + "0x32c00502801b32c00532300507f08900702d01b08900532300501b00901b", + "0x5800532300505800503101b05600532300505600504601b2ec005323005", + "0x580560470052ec0053230052ec0050b001b00700532300500700531701b", + "0x32300503800522501b01b32300501b02001b01b32300501b00701b2ec007", + "0x504600506c01b01b32300532400506301b01b3230051f500532101b01b", + "0x2ea00502501b2ea00532300501b22901b2eb00532300501b31b01b01b323", + "0x2e800532300501b00901b2e90053230052ea2eb00732401b2ea005323005", + "0x504601b2e60053230052e700502801b2e70053230052e92e800702d01b", + "0x532300500700531701b04200532300504200503101b025005323005025", + "0x32300501b00701b2e60070420250470052e60053230052e60050b001b007", + "0x500900504601b01b32300531f00532101b01b32300504600506c01b01b", + "0x531a00522501b01b32300501b00701b01b32d00501b19301b2e5005323", + "0x4400506c01b01b32300531f00532101b01b32300504600506c01b01b323", + "0x1b31b01b01b32300501b02001b2e500532300504300504601b01b323005", + "0x1b2e30053230052e300502501b2e300532300501b04b01b2e4005323005", + "0x2e22e100702d01b2e100532300501b00901b2e20053230052e32e4007324", + "0x2e50053230052e500504601b07e0053230052df00502801b2df005323005", + "0x7e0050b001b00700532300500700531701b04200532300504200503101b", + "0x4600506c01b01b32300501b00701b07e0070422e504700507e005323005", + "0x1b31b01b01b32300504400506c01b01b32300502400522c01b01b323005", + "0x1b08f00532300508f00502501b08f00532300501b22301b08d005323005", + "0x2de09200702d01b09200532300501b00901b2de00532300508f08d007324", + "0x4100532300504100504601b0900053230052dd00502801b2dd005323005", + "0x900050b001b00700532300500700531701b04000532300504000503101b", + "0x1b30701b04600532300501b24301b090007040041047005090005323005", + "0x1b00700501b01b32300501b01b01b01b32300501b24f01b044005323005", + "0x2400502401b01b32300501b00701b04004100732e042043007323007005", + "0x4501b04300532300504300504601b01b32300501b04701b193005323005", + "0x3e00505801b01b32300501b00701b02300532f03e03f007323007193005", + "0x32100532300507d00505701b02000532300503f00504101b07d005323005", + "0x1b31f00532300501b03f01b01b32300501b00701b01b33000501b19301b", + "0x531e00505701b02000532300502300504101b31e00532300531f005055", + "0x1b32300501b00701b31b00533131d0053230073210052c601b321005323", + "0x504301b04700532300504704600725101b04700532300531d00504401b", + "0x701b00900533232402500732300731a04300706f01b31a005323005047", + "0x2d00732300702000504501b02500532300502500504601b01b32300501b", + "0x4101b31700532300502800505801b01b32300501b00701b031005333028", + "0x1b33400501b19301b07c00532300531700505701b0b000532300502d005", + "0x53230051f500505501b1f500532300501b03f01b01b32300501b00701b", + "0x52c601b07c00532300519200505701b0b000532300503100504101b192", + "0x1b32300501b02001b01b32300501b00701b03900533503700532300707c", + "0x50b000521701b03600532300501b31b01b03800532300503700504401b", + "0x1b02500532300502500504601b21300532300503800504301b20d005323", + "0x503600521f01b20d00532300520d0052c901b042005323005042005031", + "0x521303620d0420250462d301b21300532300521300502501b036005323", + "0x501b00701b21e00533621b00532300721700503301b217216215024323", + "0x1b22300532300521f00502401b22221f00732300521b00506001b01b323", + "0x522300504101b22900532300521600503101b225005323005215005046", + "0x1b00701b01b33700501b19301b22c0053230052220052ef01b04b005323", + "0x502801b01b32300504400507201b01b32300532400507001b01b323005", + "0x532300521600503101b21500532300521500504601b05300532300521e", + "0x2150470050530053230050530050b001b00700532300500700531701b216", + "0x503900522501b01b32300501b02001b01b32300501b00701b053007216", + "0x504601b05100532300505000506201b05000532300501b03f01b01b323", + "0x53230050b000504101b22900532300504200503101b225005323005025", + "0x5400533804500532300722c00530601b22c0053230050510052ef01b04b", + "0x532300504504400730501b01b32300501b04701b01b32300501b00701b", + "0x1b01b32300501b00701b25100533924f24300732300704b00504501b045", + "0x505600505701b05800532300524300504101b05600532300524f005058", + "0x32300501b03f01b01b32300501b00701b01b33a00501b19301b057005323", + "0x5701b05800532300525100504101b2c600532300505500505501b055005", + "0x1b00701b2d300533b2c90053230070570052c601b0570053230052c6005", + "0x1b31b01b0330053230052c900504401b01b32300501b02001b01b323005", + "0x6300532300503300504301b2ef00532300505800521701b060005323005", + "0x2ef0052c901b22900532300522900503101b22500532300522500504601b", + "0x6300532300506300502501b06000532300506000521f01b2ef005323005", + "0x32300700600503301b0063060620243230050630602ef2292250462d301b", + "0x6f30700732300506a00506001b01b32300501b00701b06c00533c06a005", + "0x30600503101b07200532300506200504601b07000532300530700502401b", + "0x7700532300506f0052ef01b03400532300507000504101b305005323005", + "0x1b01b32300504500521601b01b32300501b00701b01b33d00501b19301b", + "0x32300506200504601b30200532300506c00502801b01b323005324005070", + "0xb001b00700532300500700531701b30600532300530600503101b062005", + "0x2001b01b32300501b00701b302007306062047005302005323005302005", + "0x6201b07400532300501b03f01b01b3230052d300522501b01b32300501b", + "0x32300522900503101b07200532300522500504601b073005323005074005", + "0x30601b0770053230050730052ef01b03400532300505800504101b305005", + "0x703400504501b01b32300501b00701b07500533e07b005323007077005", + "0x1b32300530000532101b01b32300501b00701b2fe00533f2ff300007323", + "0x32300532400507001b01b32300504500521601b01b3230052ff00531f01b", + "0x32300501b31a01b2fd00532300501b31b01b01b32300507b00521601b01b", + "0x1b2fb0053230052fc2fd00732401b2fc0053230052fc00502501b2fc005", + "0x52f600502801b2f60053230052fb2fa00702d01b2fa00532300501b009", + "0x1b30500532300530500503101b07200532300507200504601b088005323", + "0x73050720470050880053230050880050b001b007005323005007005317", + "0x532300501b07c01b01b3230052fe00532101b01b32300501b00701b088", + "0x862f40073230072f530507202419201b2f50053230052f50051f501b2f5", + "0x521501b08400532300501b03401b01b32300501b00701b2f22f3007340", + "0x732300532400507701b01b3230052f100521601b2f02f100732300507b", + "0x21601b2ec32c00732300504500521501b01b32300507f00507001b08907f", + "0x532300508600503101b2f40053230052f400504601b01b32300532c005", + "0x504101b08400532300508400530201b00700532300500700531701b086", + "0x53230052ec00504101b08900532300508900530201b2f00053230052f0", + "0x7301b2e82e92ea2eb0473230052ec0892f00840070862f404407401b2ec", + "0x52e700507b01b01b32300501b00701b2e60053412e70053230072e8005", + "0x21601b2e32e40073230052e500521501b2e500532300501b31b01b01b323", + "0x53230052e200521b01b2e20053230052e300521701b01b3230052e4005", + "0x503101b2eb0053230052eb00504601b2df0053230052e100521e01b2e1", + "0x53230052df0050b001b2e90053230052e900531701b2ea0053230052ea", + "0x53230052e600502801b01b32300501b00701b2df2e92ea2eb0470052df", + "0x531701b2ea0053230052ea00503101b2eb0053230052eb00504601b07e", + "0x1b07e2e92ea2eb04700507e00532300507e0050b001b2e90053230052e9", + "0x1b01b32300532400507001b01b32300504500521601b01b32300501b007", + "0x8f00532300501b22301b08d00532300501b31b01b01b32300507b005216", + "0x1b00901b2de00532300508f08d00732401b08f00532300508f00502501b", + "0x53230052dd00502801b2dd0053230052de09200702d01b092005323005", + "0x531701b2f20053230052f200503101b2f30053230052f300504601b090", + "0x1b0900072f22f30470050900053230050900050b001b007005323005007", + "0x1b01b32300504500521601b01b32300507500522501b01b32300501b007", + "0x8700532300501b31b01b01b32300503400532101b01b323005324005070", + "0x2dc08700732401b2dc0053230052dc00502501b2dc00532300501b06a01b", + "0x2d90053230052da09800702d01b09800532300501b00901b2da005323005", + "0x30500503101b07200532300507200504601b09f0053230052d900502801b", + "0x9f00532300509f0050b001b00700532300500700531701b305005323005", + "0x1b01b32300505400522501b01b32300501b00701b09f007305072047005", + "0x1b32300504400507201b01b32300504b00532101b01b323005324005070", + "0x3230052d800502501b2d800532300501b22901b09b00532300501b31b01b", + "0x2d01b0a300532300501b00901b2d60053230052d809b00732401b2d8005", + "0x522500504601b0a50053230052d400502801b2d40053230052d60a3007", + "0x1b00700532300500700531701b22900532300522900503101b225005323", + "0x1b01b32300501b00701b0a50072292250470050a50053230050a50050b0", + "0x532300500900504601b01b32300502000532101b01b323005044005072", + "0x1b32300531b00522501b01b32300501b00701b01b34200501b19301b0a7", + "0x32300504600506c01b01b32300502000532101b01b32300504400507201b", + "0x32300501b31b01b01b32300501b02001b0a700532300504300504601b01b", + "0x732401b0aa0053230050aa00502501b0aa00532300501b04b01b2d2005", + "0x3230052cf2ce00702d01b2ce00532300501b00901b2cf0053230050aa2d2", + "0x3101b0a70053230050a700504601b2cc0053230052cd00502801b2cd005", + "0x3230052cc0050b001b00700532300500700531701b042005323005042005", + "0x32300502400522c01b01b32300501b00701b2cc0070420a70470052cc005", + "0x32300501b31b01b01b32300504600506c01b01b32300504400507201b01b", + "0x732401b0af0053230050af00502501b0af00532300501b22301b2cb005", + "0x3230052ca2c800702d01b2c800532300501b00901b2ca0053230050af2cb", + "0x3101b04100532300504100504601b0490053230052c700502801b2c7005", + "0x3230050490050b001b00700532300500700531701b040005323005040005", + "0x700501b00700501b01b32300501b01b01b049007040041047005049005", + "0x32300502400502401b01b32300501b00701b044045007343046047007323", + "0x4300504501b04700532300504700504601b01b32300501b04701b043005", + "0x32300504100505801b01b32300501b00701b040005344041042007323007", + "0x19301b03e00532300519300505701b03f00532300504200504101b193005", + "0x505501b02300532300501b03f01b01b32300501b00701b01b34500501b", + "0x532300507d00505701b03f00532300504000504101b07d005323005023", + "0x4401b01b32300501b00701b32100534602000532300703e0052c601b03e", + "0x32300531e00502501b31e00532300531f00504301b31f005323005020005", + "0x32300501b00701b31a00534731b31d00732300731e04700706f01b31e005", + "0x534832402500732300703f00504501b31d00532300531d00504601b01b", + "0x1b32300502500532101b01b32300501b02001b01b32300501b00701b009", + "0x532300501b31b01b01b32300531b00507001b01b32300532400531f01b", + "0x2d00732401b02800532300502800502501b02800532300501b31a01b02d", + "0x532300503131700702d01b31700532300501b00901b031005323005028", + "0x503101b31d00532300531d00504601b07c0053230050b000502801b0b0", + "0x532300507c0050b001b00700532300500700531701b046005323005046", + "0x1b01b32300501b02001b01b32300501b00701b07c00704631d04700507c", + "0x53230051f50051f501b1f500532300501b07c01b01b323005009005321", + "0x501b00701b0380390073490371920073230071f504631d02419201b1f5", + "0x3602432300731b00703702407501b19200532300519200504601b01b323", + "0x21b00532300501b31b01b01b32300501b00701b21721621502434a21320d", + "0x521501b21e00532300521321b00732401b21300532300521300502501b", + "0x532300522200521701b01b32300521f00521601b22221f00732300521e", + "0x504601b22900532300522500521e01b22500532300522300521b01b223", + "0x532300520d00531701b03600532300503600503101b192005323005192", + "0x32300501b00701b22920d0361920470052290053230052290050b001b20d", + "0x502801b22c00532300521704b00702d01b04b00532300501b00901b01b", + "0x532300521500503101b19200532300519200504601b05300532300522c", + "0x1920470050530053230050530050b001b21600532300521600531701b215", + "0x501b31b01b01b32300531b00507001b01b32300501b00701b053216215", + "0x32401b05100532300505100502501b05100532300501b22301b050005323", + "0x505424300702d01b24300532300501b00901b054005323005051050007", + "0x1b03900532300503900504601b25100532300524f00502801b24f005323", + "0x52510050b001b00700532300500700531701b038005323005038005031", + "0x503f00532101b01b32300501b00701b251007038039047005251005323", + "0x501b00701b01b34b00501b19301b05600532300531a00504601b01b323", + "0x4700504601b01b32300503f00532101b01b32300532100522501b01b323", + "0x1b04b01b05800532300501b31b01b01b32300501b02001b056005323005", + "0x532300505705800732401b05700532300505700502501b057005323005", + "0x502801b2c90053230050552c600702d01b2c600532300501b00901b055", + "0x532300504600503101b05600532300505600504601b2d30053230052c9", + "0x560470052d30053230052d30050b001b00700532300500700531701b046", + "0x501b31b01b01b32300502400522c01b01b32300501b00701b2d3007046", + "0x32401b06000532300506000502501b06000532300501b22301b033005323", + "0x52ef06300702d01b06300532300501b00901b2ef005323005060033007", + "0x1b04500532300504500504601b30600532300506200502801b062005323", + "0x53060050b001b00700532300500700531701b044005323005044005031", + "0x501b24f01b04600532300501b30001b306007044045047005306005323", + "0x734c04404500732300700501b00700501b01b32300501b01b01b01b323", + "0x240052c901b04500532300504500504601b01b32300501b00701b042043", + "0x71930052fe01b1930400410243230050240450072ff01b024005323005", + "0x4100532300504100504601b01b32300501b00701b03f00534d047005323", + "0x460072fd01b0400053230050400052c901b04400532300504400503101b", + "0x52fb01b07d02303e0243230050400440410242fc01b047005323005047", + "0x3230050200052fa01b01b32300501b00701b32100534e02000532300707d", + "0x1b32300501b00701b31b00534f31d00532300731e0052f601b31e31f007", + "0x32300731a00504501b01b32300501b04701b31a00532300531f00502401b", + "0x2d00532300532400504401b01b32300501b00701b009005350324025007", + "0x2500504101b03100532300502800504201b02800532300502d00504301b", + "0x701b01b35100501b19301b0b000532300503100504001b317005323005", + "0x1b1f500532300507c00503e01b07c00532300501b03f01b01b32300501b", + "0x70b000502301b0b00053230051f500504001b317005323005009005041", + "0x3900732300731700504501b01b32300501b00701b037005352192005323", + "0x4301b20d00532300503800504401b01b32300501b00701b036005353038", + "0x32300503900504101b21500532300521300504201b21300532300520d005", + "0x501b00701b01b35400501b19301b21700532300521500504001b216005", + "0x504101b21e00532300521b00503e01b21b00532300501b03f01b01b323", + "0x532300721700502301b21700532300521e00504001b216005323005036", + "0x35622522300732300721600504501b01b32300501b00701b22200535521f", + "0x4b00504301b04b00532300522500504401b01b32300501b00701b229005", + "0x5000532300522300504101b05300532300522c00504201b22c005323005", + "0x1b32300501b00701b01b35700501b19301b05100532300505300504001b", + "0x522900504101b24300532300505400503e01b05400532300501b03f01b", + "0x35824f00532300705100502301b05100532300524300504001b050005323", + "0x5700535905805600732300705000504501b01b32300501b00701b251005", + "0x1b01b32300505600532101b01b32300501b02001b01b32300501b00701b", + "0x1b32300521f00531d01b01b32300524f00531d01b01b32300505800531f", + "0x3230050470052f501b01b32300531d00508801b01b32300519200531d01b", + "0x52c600502501b2c600532300501b31a01b05500532300501b31b01b01b", + "0x1b2d300532300501b00901b2c90053230052c605500732401b2c6005323", + "0x3e00504601b06000532300503300502801b0330053230052c92d300702d", + "0x700532300500700531701b02300532300502300503101b03e005323005", + "0x1b32300501b00701b06000702303e0470050600053230050600050b001b", + "0x3230052ef0051f501b2ef00532300501b07c01b01b32300505700532101b", + "0x1b00701b00630600735a0620630073230072ef02303e02419201b2ef005", + "0x6a00508601b06a00532300501b2f401b01b32300501b02001b01b323005", + "0x6300532300506300504601b01b32300506c0052f301b30706c007323005", + "0x470052f201b00700532300500700531701b06200532300506200503101b", + "0x19200532300519200502501b31d00532300531d00508401b047005323005", + "0x630422f101b24f00532300524f00502501b21f00532300521f00502501b", + "0x73050052f001b30507207006f04732300524f21f19231d047307007062", + "0x1b01b32300503400507f01b01b32300501b00701b07700535b034005323", + "0x507400521601b07307400732300530200521501b30200532300501b31b", + "0x21e01b07500532300507b00521b01b07b00532300507300521701b01b323", + "0x32300507000503101b06f00532300506f00504601b300005323005075005", + "0x470053000053230053000050b001b07200532300507200531701b070005", + "0x4601b2ff00532300507700502801b01b32300501b00701b30007207006f", + "0x32300507200531701b07000532300507000503101b06f00532300506f005", + "0x501b00701b2ff07207006f0470052ff0053230052ff0050b001b072005", + "0x521f00531d01b01b32300524f00531d01b01b32300501b02001b01b323", + "0x470052f501b01b32300531d00508801b01b32300519200531d01b01b323", + "0x502501b2fd00532300501b22301b2fe00532300501b31b01b01b323005", + "0x532300501b00901b2fc0053230052fd2fe00732401b2fd0053230052fd", + "0x4601b2f60053230052fa00502801b2fa0053230052fc2fb00702d01b2fb", + "0x32300500700531701b00600532300500600503101b306005323005306005", + "0x501b00701b2f60070063060470052f60053230052f60050b001b007005", + "0x505000532101b01b32300525100522501b01b32300501b02001b01b323", + "0x31d00508801b01b32300519200531d01b01b32300521f00531d01b01b323", + "0x1b08901b08800532300501b31b01b01b3230050470052f501b01b323005", + "0x53230052f508800732401b2f50053230052f500502501b2f5005323005", + "0x502801b2f30053230052f408600702d01b08600532300501b00901b2f4", + "0x532300502300503101b03e00532300503e00504601b2f20053230052f3", + "0x3e0470052f20053230052f20050b001b00700532300500700531701b023", + "0x522200522501b01b32300501b02001b01b32300501b00701b2f2007023", + "0x19200531d01b01b32300521600532101b01b3230050470052f501b01b323", + "0x1b32c01b08400532300501b31b01b01b32300531d00508801b01b323005", + "0x53230052f108400732401b2f10053230052f100502501b2f1005323005", + "0x502801b0890053230052f007f00702d01b07f00532300501b00901b2f0", + "0x532300502300503101b03e00532300503e00504601b32c005323005089", + "0x3e04700532c00532300532c0050b001b00700532300500700531701b023", + "0x503700522501b01b32300501b02001b01b32300501b00701b32c007023", + "0x31700532101b01b32300531d00508801b01b3230050470052f501b01b323", + "0x502501b2eb00532300501b06a01b2ec00532300501b31b01b01b323005", + "0x532300501b00901b2ea0053230052eb2ec00732401b2eb0053230052eb", + "0x4601b2e70053230052e800502801b2e80053230052ea2e900702d01b2e9", + "0x32300500700531701b02300532300502300503101b03e00532300503e005", + "0x501b00701b2e700702303e0470052e70053230052e70050b001b007005", + "0x31f00522c01b01b3230050470052f501b01b32300531b00522501b01b323", + "0x502501b2e500532300501b22901b2e600532300501b31b01b01b323005", + "0x532300501b00901b2e40053230052e52e600732401b2e50053230052e5", + "0x4601b2e10053230052e200502801b2e20053230052e42e300702d01b2e3", + "0x32300500700531701b02300532300502300503101b03e00532300503e005", + "0x501b00701b2e100702303e0470052e10053230052e10050b001b007005", + "0x504601b2df00532300532100502801b01b3230050470052f501b01b323", + "0x532300500700531701b02300532300502300503101b03e00532300503e", + "0x32300501b00701b2df00702303e0470052df0053230052df0050b001b007", + "0x50460052ec01b01b32300504000522c01b01b32300503f00522501b01b", + "0x8d00502501b08d00532300501b04b01b07e00532300501b31b01b01b323", + "0x2de00532300501b00901b08f00532300508d07e00732401b08d005323005", + "0x504601b2dd00532300509200502801b09200532300508f2de00702d01b", + "0x532300500700531701b04400532300504400503101b041005323005041", + "0x32300501b00701b2dd0070440410470052dd0053230052dd0050b001b007", + "0x32300501b31b01b01b3230050460052ec01b01b32300502400522c01b01b", + "0x732401b08700532300508700502501b08700532300501b22301b090005", + "0x3230052dc2da00702d01b2da00532300501b00901b2dc005323005087090", + "0x3101b04300532300504300504601b2d900532300509800502801b098005", + "0x3230052d90050b001b00700532300500700531701b042005323005042005", + "0x32300501b24301b04600532300501b24301b2d90070420430470052d9005", + "0x700501b00700501b01b32300501b01b01b01b32300501b24f01b044005", + "0x32300502400502401b01b32300501b00701b04004100735c042043007323", + "0x19300504501b04300532300504300504601b01b32300501b04701b193005", + "0x32300503e00504401b01b32300501b00701b02300535d03e03f007323007", + "0x4101b32100532300502000504201b02000532300507d00504301b07d005", + "0x1b35e00501b19301b31e00532300532100504001b31f00532300503f005", + "0x532300531d00503e01b31d00532300501b03f01b01b32300501b00701b", + "0x502301b31e00532300531b00504001b31f00532300502300504101b31b", + "0x504504400725101b01b32300501b00701b31a00535f04500532300731e", + "0x501b00701b0090053603240250073230070450430072eb01b045005323", + "0x36102802d00732300731f00504501b02500532300502500504601b01b323", + "0x31700504301b31700532300502800504401b01b32300501b00701b031005", + "0x1f500532300502d00504101b07c0053230050b000504201b0b0005323005", + "0x1b32300501b00701b01b36200501b19301b19200532300507c00504001b", + "0x503100504101b03900532300503700503e01b03700532300501b03f01b", + "0x36304700532300719200502301b19200532300503900504001b1f5005323", + "0x504501b04700532300504704600725101b01b32300501b00701b038005", + "0x520d00505801b01b32300501b00701b21300536420d0360073230071f5", + "0x1b21700532300521500505701b21600532300503600504101b215005323", + "0x5501b21b00532300501b03f01b01b32300501b00701b01b36500501b193", + "0x32300521e00505701b21600532300521300504101b21e00532300521b005", + "0x1b01b32300501b00701b22200536621f0053230072170052c601b217005", + "0x22500532300501b31b01b22300532300521f00504401b01b32300501b020", + "0x2500504601b04b00532300522300504301b22900532300521600521701b", + "0x2290053230052290052c901b04200532300504200503101b025005323005", + "0x250462d301b04b00532300504b00502501b22500532300522500521f01b", + "0x536705100532300705000503301b05005322c02432300504b225229042", + "0x24300502401b24f24300732300505100506001b01b32300501b00701b054", + "0x5800532300505300503101b05600532300522c00504601b251005323005", + "0x501b19301b05500532300524f0052ef01b05700532300525100504101b", + "0x504700531d01b01b3230053240052ea01b01b32300501b00701b01b368", + "0x3101b22c00532300522c00504601b2c600532300505400502801b01b323", + "0x3230052c60050b001b00700532300500700531701b053005323005053005", + "0x1b32300501b02001b01b32300501b00701b2c600705322c0470052c6005", + "0x3230052c900506201b2c900532300501b03f01b01b32300522200522501b", + "0x4101b05800532300504200503101b05600532300502500504601b2d3005", + "0x32300705500530601b0550053230052d30052ef01b057005323005216005", + "0x632ef00732300705700504501b01b32300501b00701b060005369033005", + "0x6300531f01b01b3230052ef00532101b01b32300501b00701b06200536a", + "0x52ea01b01b32300504700531d01b01b32300503300521601b01b323005", + "0x2501b00600532300501b31a01b30600532300501b31b01b01b323005324", + "0x32300501b00901b06a00532300500630600732401b006005323005006005", + "0x1b06f00532300530700502801b30700532300506a06c00702d01b06c005", + "0x500700531701b05800532300505800503101b056005323005056005046", + "0x1b00701b06f00705805604700506f00532300506f0050b001b007005323", + "0x51f501b07000532300501b07c01b01b32300506200532101b01b323005", + "0x7703400736b30507200732300707005805602419201b070005323005070", + "0x530200521601b07430200732300503300521501b01b32300501b00701b", + "0x2e901b07200532300507200504601b07300532300507400521701b01b323", + "0x1b00701b2fd2fe2ff02436c30007507b024323007073047324007305046", + "0x1b2fb0053230052fc00521e01b2fc00532300530000521b01b01b323005", + "0x507500531701b07b00532300507b00503101b072005323005072005046", + "0x1b00701b2fb07507b0720470052fb0053230052fb0050b001b075005323", + "0x1b2f60053230052fd2fa00702d01b2fa00532300501b00901b01b323005", + "0x52ff00503101b07200532300507200504601b0880053230052f6005028", + "0x50880053230050880050b001b2fe0053230052fe00531701b2ff005323", + "0x31d01b01b32300503300521601b01b32300501b00701b0882fe2ff072047", + "0x1b2f500532300501b31b01b01b3230053240052ea01b01b323005047005", + "0x52f42f500732401b2f40053230052f400502501b2f400532300501b223", + "0x1b2f20053230050862f300702d01b2f300532300501b00901b086005323", + "0x507700503101b03400532300503400504601b0840053230052f2005028", + "0x50840053230050840050b001b00700532300500700531701b077005323", + "0x32101b01b32300506000522501b01b32300501b00701b084007077034047", + "0x1b01b3230053240052ea01b01b32300504700531d01b01b323005057005", + "0x53230052f000502501b2f000532300501b06a01b2f100532300501b31b", + "0x702d01b08900532300501b00901b07f0053230052f02f100732401b2f0", + "0x32300505600504601b2ec00532300532c00502801b32c00532300507f089", + "0xb001b00700532300500700531701b05800532300505800503101b056005", + "0x2001b01b32300501b00701b2ec0070580560470052ec0053230052ec005", + "0x2ea01b01b3230051f500532101b01b32300503800522501b01b32300501b", + "0x1b2eb00532300501b31b01b01b32300504600506c01b01b323005324005", + "0x52ea2eb00732401b2ea0053230052ea00502501b2ea00532300501b229", + "0x1b2e70053230052e92e800702d01b2e800532300501b00901b2e9005323", + "0x504200503101b02500532300502500504601b2e60053230052e7005028", + "0x52e60053230052e60050b001b00700532300500700531701b042005323", + "0x32101b01b32300504600506c01b01b32300501b00701b2e6007042025047", + "0x1b01b36d00501b19301b2e500532300500900504601b01b32300531f005", + "0x1b01b32300504600506c01b01b32300531a00522501b01b32300501b007", + "0x532300504300504601b01b32300504400506c01b01b32300531f005321", + "0x532300501b04b01b2e400532300501b31b01b01b32300501b02001b2e5", + "0x901b2e20053230052e32e400732401b2e30053230052e300502501b2e3", + "0x3230052df00502801b2df0053230052e22e100702d01b2e100532300501b", + "0x31701b04200532300504200503101b2e50053230052e500504601b07e005", + "0x7e0070422e504700507e00532300507e0050b001b007005323005007005", + "0x1b32300502400522c01b01b32300504600506c01b01b32300501b00701b", + "0x532300501b22301b08d00532300501b31b01b01b32300504400506c01b", + "0x901b2de00532300508f08d00732401b08f00532300508f00502501b08f", + "0x3230052dd00502801b2dd0053230052de09200702d01b09200532300501b", + "0x31701b04000532300504000503101b04100532300504100504601b090005", + "0x900070400410470050900053230050900050b001b007005323005007005", + "0x4404500736e04604700732300700501b00700501b01b32300501b01b01b", + "0x1b32300501b04701b04300532300502400502401b01b32300501b00701b", + "0x4000536f04104200732300704300504501b04700532300504700504601b", + "0x32300519300504301b19300532300504100504401b01b32300501b00701b", + "0x4001b02300532300504200504101b03e00532300503f00504201b03f005", + "0x3f01b01b32300501b00701b01b37000501b19301b07d00532300503e005", + "0x532300504000504101b32100532300502000503e01b02000532300501b", + "0x31e00537131f00532300707d00502301b07d00532300532100504001b023", + "0x1b31a00537231b31d00732300731f0470072eb01b01b32300501b00701b", + "0x732300702300504501b31d00532300531d00504601b01b32300501b007", + "0x1b02d00532300532400504401b01b32300501b00701b009005373324025", + "0x502500504101b03100532300502800504201b02800532300502d005043", + "0x1b00701b01b37400501b19301b0b000532300503100504001b317005323", + "0x4101b1f500532300507c00503e01b07c00532300501b03f01b01b323005", + "0x3230070b000502301b0b00053230051f500504001b317005323005009005", + "0x3803900732300731700504501b01b32300501b00701b037005375192005", + "0x504301b20d00532300503800504401b01b32300501b00701b036005376", + "0x532300503900504101b21500532300521300504201b21300532300520d", + "0x32300501b00701b01b37700501b19301b21700532300521500504001b216", + "0x3600504101b21e00532300521b00503e01b21b00532300501b03f01b01b", + "0x21f00532300721700502301b21700532300521e00504001b216005323005", + "0x537922522300732300721600504501b01b32300501b00701b222005378", + "0x504b00504301b04b00532300522500504401b01b32300501b00701b229", + "0x1b05000532300522300504101b05300532300522c00504201b22c005323", + "0x1b01b32300501b00701b01b37a00501b19301b051005323005053005040", + "0x32300522900504101b24300532300505400503e01b05400532300501b03f", + "0x537b24f00532300705100502301b05100532300524300504001b050005", + "0x1b05700537c05805600732300705000504501b01b32300501b00701b251", + "0x532300505500504301b05500532300505800504401b01b32300501b007", + "0x504001b2d300532300505600504101b2c90053230052c600504201b2c6", + "0x1b03f01b01b32300501b00701b01b37d00501b19301b0330053230052c9", + "0x2d300532300505700504101b2ef00532300506000503e01b060005323005", + "0x1b06200537e06300532300703300502301b0330053230052ef00504001b", + "0x1b00701b06a00537f0063060073230072d300504501b01b32300501b007", + "0x600531f01b01b32300530600532101b01b32300501b02001b01b323005", + "0x531d01b01b32300524f00531d01b01b32300506300531d01b01b323005", + "0x31b01b01b32300531b0052ea01b01b32300519200531d01b01b32300521f", + "0x30700532300530700502501b30700532300501b31a01b06c00532300501b", + "0x7000702d01b07000532300501b00901b06f00532300530706c00732401b", + "0x532300531d00504601b30500532300507200502801b07200532300506f", + "0x50b001b00700532300500700531701b04600532300504600503101b31d", + "0x532101b01b32300501b00701b30500704631d047005305005323005305", + "0x1b0340053230050340051f501b03400532300501b07c01b01b32300506a", + "0x1b32300501b00701b07307400738030207700732300703404631d024192", + "0x732300507b00508601b07b00532300501b2f401b01b32300501b02001b", + "0x531701b30200532300530200503101b01b3230050750052f301b300075", + "0x532300519200502501b31b00532300531b0052e801b007005323005007", + "0x502501b24f00532300524f00502501b21f00532300521f00502501b192", + "0x2ff02432300506324f21f19231b3000073020432e701b063005323005063", + "0x31701b2ff0053230052ff00503101b07700532300507700504601b2fd2fe", + "0x2fd2fe2ff0770470052fd0053230052fd0050b001b2fe0053230052fe005", + "0x1b01b32300506300531d01b01b32300501b02001b01b32300501b00701b", + "0x1b32300519200531d01b01b32300521f00531d01b01b32300524f00531d", + "0x532300501b22301b2fc00532300501b31b01b01b32300531b0052ea01b", + "0x901b2fa0053230052fb2fc00732401b2fb0053230052fb00502501b2fb", + "0x32300508800502801b0880053230052fa2f600702d01b2f600532300501b", + "0x31701b07300532300507300503101b07400532300507400504601b2f5005", + "0x2f50070730740470052f50053230052f50050b001b007005323005007005", + "0x1b01b32300506200522501b01b32300501b02001b01b32300501b00701b", + "0x1b32300521f00531d01b01b32300524f00531d01b01b3230052d3005321", + "0x532300501b31b01b01b32300531b0052ea01b01b32300519200531d01b", + "0x2f400732401b08600532300508600502501b08600532300501b08901b2f4", + "0x53230052f32f200702d01b2f200532300501b00901b2f3005323005086", + "0x503101b31d00532300531d00504601b2f100532300508400502801b084", + "0x53230052f10050b001b00700532300500700531701b046005323005046", + "0x1b01b32300501b02001b01b32300501b00701b2f100704631d0470052f1", + "0x1b32300505000532101b01b32300531b0052ea01b01b323005251005225", + "0x532300501b31b01b01b32300519200531d01b01b32300521f00531d01b", + "0x2f000732401b07f00532300507f00502501b07f00532300501b32c01b2f0", + "0x532300508932c00702d01b32c00532300501b00901b08900532300507f", + "0x503101b31d00532300531d00504601b2eb0053230052ec00502801b2ec", + "0x53230052eb0050b001b00700532300500700531701b046005323005046", + "0x1b01b32300501b02001b01b32300501b00701b2eb00704631d0470052eb", + "0x1b32300519200531d01b01b32300531b0052ea01b01b323005222005225", + "0x532300501b06a01b2ea00532300501b31b01b01b32300521600532101b", + "0x901b2e80053230052e92ea00732401b2e90053230052e900502501b2e9", + "0x3230052e600502801b2e60053230052e82e700702d01b2e700532300501b", + "0x31701b04600532300504600503101b31d00532300531d00504601b2e5005", + "0x2e500704631d0470052e50053230052e50050b001b007005323005007005", + "0x1b01b32300503700522501b01b32300501b02001b01b32300501b00701b", + "0x2e400532300501b31b01b01b32300531700532101b01b32300531b0052ea", + "0x2e32e400732401b2e30053230052e300502501b2e300532300501b22901b", + "0x2df0053230052e22e100702d01b2e100532300501b00901b2e2005323005", + "0x4600503101b31d00532300531d00504601b07e0053230052df00502801b", + "0x7e00532300507e0050b001b00700532300500700531701b046005323005", + "0x1b01b32300502300532101b01b32300501b00701b07e00704631d047005", + "0x1b01b32300501b00701b01b38100501b19301b08d00532300531a005046", + "0x532300504700504601b01b32300502300532101b01b32300531e005225", + "0x532300501b04b01b08f00532300501b31b01b01b32300501b02001b08d", + "0x901b0920053230052de08f00732401b2de0053230052de00502501b2de", + "0x32300509000502801b0900053230050922dd00702d01b2dd00532300501b", + "0x31701b04600532300504600503101b08d00532300508d00504601b087005", + "0x8700704608d0470050870053230050870050b001b007005323005007005", + "0x2dc00532300501b31b01b01b32300502400522c01b01b32300501b00701b", + "0x2da2dc00732401b2da0053230052da00502501b2da00532300501b22301b", + "0x9f0053230050982d900702d01b2d900532300501b00901b098005323005", + "0x4400503101b04500532300504500504601b09b00532300509f00502801b", + "0x9b00532300509b0050b001b00700532300500700531701b044005323005", + "0x732300700501b00700501b01b32300501b01b01b09b007044045047005", + "0x4300532300502400502401b01b32300501b00701b044045007382046047", + "0x32300704300504501b04700532300504700504601b01b32300501b04701b", + "0x19300532300504100504401b01b32300501b00701b040005383041042007", + "0x4200504101b03e00532300503f00504201b03f00532300519300504301b", + "0x701b01b38400501b19301b07d00532300503e00504001b023005323005", + "0x1b32100532300502000503e01b02000532300501b03f01b01b32300501b", + "0x707d00502301b07d00532300532100504001b023005323005040005041", + "0x732300731f0470072eb01b01b32300501b00701b31e00538531f005323", + "0x1b31d00532300531d00504601b01b32300501b00701b31a00538631b31d", + "0x1b02001b01b32300501b00701b009005387324025007323007023005045", + "0x52ea01b01b32300532400531f01b01b32300502500532101b01b323005", + "0x2501b02800532300501b31a01b02d00532300501b31b01b01b32300531b", + "0x32300501b00901b03100532300502802d00732401b028005323005028005", + "0x1b07c0053230050b000502801b0b000532300503131700702d01b317005", + "0x500700531701b04600532300504600503101b31d00532300531d005046", + "0x1b00701b07c00704631d04700507c00532300507c0050b001b007005323", + "0x501b07c01b01b32300500900532101b01b32300501b02001b01b323005", + "0x73230071f504631d02419201b1f50053230051f50051f501b1f5005323", + "0x19200532300519200504601b01b32300501b00701b038039007388037192", + "0x501b00701b21621521302438920d03600732300731b0070370242e601b", + "0x21601b21e21b00732300521700521501b21700532300501b31b01b01b323", + "0x532300521f00521b01b21f00532300521e00521701b01b32300521b005", + "0x503101b19200532300519200504601b22300532300522200521e01b222", + "0x53230052230050b001b20d00532300520d00531701b036005323005036", + "0x22500532300501b00901b01b32300501b00701b22320d036192047005223", + "0x504601b04b00532300522900502801b22900532300521622500702d01b", + "0x532300521500531701b21300532300521300503101b192005323005192", + "0x32300501b00701b04b21521319204700504b00532300504b0050b001b215", + "0x32300501b22301b22c00532300501b31b01b01b32300531b0052ea01b01b", + "0x1b05000532300505322c00732401b05300532300505300502501b053005", + "0x505400502801b05400532300505005100702d01b05100532300501b009", + "0x1b03800532300503800503101b03900532300503900504601b243005323", + "0x70380390470052430053230052430050b001b007005323005007005317", + "0x32300531a00504601b01b32300502300532101b01b32300501b00701b243", + "0x32300531e00522501b01b32300501b00701b01b38a00501b19301b24f005", + "0x501b02001b24f00532300504700504601b01b32300502300532101b01b", + "0x5600502501b05600532300501b04b01b25100532300501b31b01b01b323", + "0x5700532300501b00901b05800532300505625100732401b056005323005", + "0x504601b2c600532300505500502801b05500532300505805700702d01b", + "0x532300500700531701b04600532300504600503101b24f00532300524f", + "0x32300501b00701b2c600704624f0470052c60053230052c60050b001b007", + "0x32300501b22301b2c900532300501b31b01b01b32300502400522c01b01b", + "0x1b0330053230052d32c900732401b2d30053230052d300502501b2d3005", + "0x52ef00502801b2ef00532300503306000702d01b06000532300501b009", + "0x1b04400532300504400503101b04500532300504500504601b063005323", + "0x70440450470050630053230050630050b001b007005323005007005317", + "0x1b32300501b01b01b01b32300501b24f01b04600532300501b24301b063", + "0x1b32300501b00701b04204300738b04404500732300700501b00700501b", + "0x32300504500504601b01b32300501b04701b04100532300502400502401b", + "0x1b32300501b00701b03f00538c19304000732300704100504501b045005", + "0x2300504201b02300532300503e00504301b03e00532300519300504401b", + "0x32100532300507d00504001b02000532300504000504101b07d005323005", + "0x1b31f00532300501b03f01b01b32300501b00701b01b38d00501b19301b", + "0x531e00504001b02000532300503f00504101b31e00532300531f00503e", + "0x1b32300501b00701b31d00538e04700532300732100502301b321005323", + "0x538f31a31b00732300702000504501b04700532300504704600725101b", + "0x531b00504101b32400532300531a00505801b01b32300501b00701b025", + "0x1b00701b01b39000501b19301b02d00532300532400505701b009005323", + "0x4101b03100532300502800505501b02800532300501b03f01b01b323005", + "0x32300702d0052c601b02d00532300503100505701b009005323005025005", + "0x504401b01b32300501b02001b01b32300501b00701b0b0005391317005", + "0x19200532300500900521701b1f500532300501b31b01b07c005323005317", + "0x4400503101b04500532300504500504601b03700532300507c00504301b", + "0x1f50053230051f500521f01b1920053230051920052c901b044005323005", + "0x390243230050371f51920440450462d301b03700532300503700502501b", + "0x1b01b32300501b00701b21300539220d00532300703600503301b036038", + "0x3900504601b21700532300521500502401b21621500732300520d005060", + "0x21f00532300521700504101b21e00532300503800503101b21b005323005", + "0x1b32300501b00701b01b39300501b19301b2220053230052160052ef01b", + "0x503900504601b22300532300521300502801b01b32300504700531d01b", + "0x1b00700532300500700531701b03800532300503800503101b039005323", + "0x1b01b32300501b00701b2230070380390470052230053230052230050b0", + "0x1b22500532300501b03f01b01b3230050b000522501b01b32300501b020", + "0x504400503101b21b00532300504500504601b229005323005225005062", + "0x1b2220053230052290052ef01b21f00532300500900504101b21e005323", + "0x21f00504501b01b32300501b00701b22c00539404b005323007222005306", + "0x32300505300532101b01b32300501b00701b051005395050053007323007", + "0x504700531d01b01b32300504b00521601b01b32300505000531f01b01b", + "0x24300502501b24300532300501b31a01b05400532300501b31b01b01b323", + "0x25100532300501b00901b24f00532300524305400732401b243005323005", + "0x504601b05800532300505600502801b05600532300524f25100702d01b", + "0x532300500700531701b21e00532300521e00503101b21b00532300521b", + "0x32300501b00701b05800721e21b0470050580053230050580050b001b007", + "0x50570051f501b05700532300501b07c01b01b32300505100532101b01b", + "0x701b2d32c90073962c605500732300705721e21b02419201b057005323", + "0x1b32300503300521601b06003300732300504b00521501b01b32300501b", + "0x2c60472e501b05500532300505500504601b2ef00532300506000521701b", + "0x1b01b32300501b00701b06a0063060243970620630073230072ef047007", + "0x530700521601b06f30700732300506c00521501b06c00532300501b31b", + "0x21e01b07200532300507000521b01b07000532300506f00521701b01b323", + "0x32300506300503101b05500532300505500504601b305005323005072005", + "0x470053050053230053050050b001b06200532300506200531701b063005", + "0x702d01b03400532300501b00901b01b32300501b00701b305062063055", + "0x32300505500504601b30200532300507700502801b07700532300506a034", + "0xb001b00600532300500600531701b30600532300530600503101b055005", + "0x21601b01b32300501b00701b302006306055047005302005323005302005", + "0x1b07400532300501b31b01b01b32300504700531d01b01b32300504b005", + "0x507307400732401b07300532300507300502501b07300532300501b223", + "0x1b30000532300507b07500702d01b07500532300501b00901b07b005323", + "0x52d300503101b2c90053230052c900504601b2ff005323005300005028", + "0x52ff0053230052ff0050b001b00700532300500700531701b2d3005323", + "0x32101b01b32300522c00522501b01b32300501b00701b2ff0072d32c9047", + "0x1b2fe00532300501b31b01b01b32300504700531d01b01b32300521f005", + "0x52fd2fe00732401b2fd0053230052fd00502501b2fd00532300501b229", + "0x1b2fa0053230052fc2fb00702d01b2fb00532300501b00901b2fc005323", + "0x521e00503101b21b00532300521b00504601b2f60053230052fa005028", + "0x52f60053230052f60050b001b00700532300500700531701b21e005323", + "0x522501b01b32300501b02001b01b32300501b00701b2f600721e21b047", + "0x31b01b01b32300504600506c01b01b32300502000532101b01b32300531d", + "0x2f50053230052f500502501b2f500532300501b04b01b08800532300501b", + "0x8600702d01b08600532300501b00901b2f40053230052f508800732401b", + "0x532300504500504601b2f20053230052f300502801b2f30053230052f4", + "0x50b001b00700532300500700531701b04400532300504400503101b045", + "0x506c01b01b32300501b00701b2f20070440450470052f20053230052f2", + "0x22301b08400532300501b31b01b01b32300502400522c01b01b323005046", + "0x3230052f108400732401b2f10053230052f100502501b2f100532300501b", + "0x2801b0890053230052f007f00702d01b07f00532300501b00901b2f0005", + "0x32300504200503101b04300532300504300504601b32c005323005089005", + "0x4700532c00532300532c0050b001b00700532300500700531701b042005", + "0x4504600732300700701b00700501b01b32300501b01b01b32c007042043", + "0x4601b04200532300504700502401b01b32300501b00701b043044007398", + "0x701b19300539904004100732300704200504501b046005323005046005", + "0x31b01b01b32300504000531f01b01b32300504100532101b01b32300501b", + "0x3e00532300503e00502501b03e00532300501b31a01b03f00532300501b", + "0x7d00702d01b07d00532300501b00901b02300532300503e03f00732401b", + "0x532300504600504601b32100532300502000502801b020005323005023", + "0x531701b04500532300504500503101b0050053230050050052e401b046", + "0x3210240450050460460053210053230053210050b001b024005323005024", + "0x31f00532300501b07c01b01b32300519300532101b01b32300501b00701b", + "0x39a31d31e00732300731f04504602419201b31f00532300531f0051f501b", + "0x4601b3240250073230050050052e301b01b32300501b00701b31a31b007", + "0x32300531d00503101b0250053230050250052e401b31e00532300531e005", + "0x4732300532431d02531e0472e101b3240053230053240052e201b31d005", + "0x21501b31700532300501b31b01b01b3230050310052df01b03102802d009", + "0x32300507c00521701b01b3230050b000521601b07c0b0007323005317005", + "0x4601b03700532300519200521e01b1920053230051f500521b01b1f5005", + "0x32300502800503101b02d00532300502d0052e401b009005323005009005", + "0x460050370053230050370050b001b02400532300502400531701b028005", + "0x22301b03900532300501b31b01b01b32300501b00701b03702402802d009", + "0x32300503803900732401b03800532300503800502501b03800532300501b", + "0x2801b21300532300503620d00702d01b20d00532300501b00901b036005", + "0x3230050050052e401b31b00532300531b00504601b215005323005213005", + "0xb001b02400532300502400531701b31a00532300531a00503101b005005", + "0x1b01b32300501b00701b21502431a00531b046005215005323005215005", + "0x21700532300501b22301b21600532300501b31b01b01b32300504700522c", + "0x1b00901b21b00532300521721600732401b21700532300521700502501b", + "0x532300521f00502801b21f00532300521b21e00702d01b21e005323005", + "0x503101b0050053230050050052e401b04400532300504400504601b222", + "0x53230052220050b001b02400532300502400531701b043005323005043", + "0x32300501b24301b04600532300501b24301b222024043005044046005222", + "0x700501b00700501b01b32300501b01b01b01b32300501b24f01b044005", + "0x32300502400502401b01b32300501b00701b04004100739b042043007323", + "0x19300504501b04300532300504300504601b01b32300501b04701b193005", + "0x32300503e00504401b01b32300501b00701b02300539c03e03f007323007", + "0x4101b32100532300502000504201b02000532300507d00504301b07d005", + "0x1b39d00501b19301b31e00532300532100504001b31f00532300503f005", + "0x532300531d00503e01b31d00532300501b03f01b01b32300501b00701b", + "0x502301b31e00532300531b00504001b31f00532300502300504101b31b", + "0x504504400725101b01b32300501b00701b31a00539e04500532300731e", + "0x501b00701b00900539f3240250073230070450430072eb01b045005323", + "0x3a002802d00732300731f00504501b02500532300502500504601b01b323", + "0x31700504301b31700532300502800504401b01b32300501b00701b031005", + "0x1f500532300502d00504101b07c0053230050b000504201b0b0005323005", + "0x1b32300501b00701b01b3a100501b19301b19200532300507c00504001b", + "0x503100504101b03900532300503700503e01b03700532300501b03f01b", + "0x3a204700532300719200502301b19200532300503900504001b1f5005323", + "0x504501b04700532300504704600725101b01b32300501b00701b038005", + "0x520d00505801b01b32300501b00701b2130053a320d0360073230071f5", + "0x1b21700532300521500505701b21600532300503600504101b215005323", + "0x5501b21b00532300501b03f01b01b32300501b00701b01b3a400501b193", + "0x32300521e00505701b21600532300521300504101b21e00532300521b005", + "0x1b01b32300501b00701b2220053a521f0053230072170052c601b217005", + "0x22500532300501b31b01b22300532300521f00504401b01b32300501b020", + "0x2500504601b04b00532300522300504301b22900532300521600521701b", + "0x2290053230052290052c901b04200532300504200503101b025005323005", + "0x250462d301b04b00532300504b00502501b22500532300522500521f01b", + "0x53a605100532300705000503301b05005322c02432300504b225229042", + "0x24300502401b24f24300732300505100506001b01b32300501b00701b054", + "0x5800532300505300503101b05600532300522c00504601b251005323005", + "0x501b19301b05500532300524f0052ef01b05700532300525100504101b", + "0x504700531d01b01b3230053240052ea01b01b32300501b00701b01b3a7", + "0x3101b22c00532300522c00504601b2c600532300505400502801b01b323", + "0x3230052c60050b001b00700532300500700531701b053005323005053005", + "0x1b32300501b02001b01b32300501b00701b2c600705322c0470052c6005", + "0x3230052c900506201b2c900532300501b03f01b01b32300522200522501b", + "0x4101b05800532300504200503101b05600532300502500504601b2d3005", + "0x32300705500530601b0550053230052d30052ef01b057005323005216005", + "0x504501b01b32300501b04701b01b32300501b00701b0600053a8033005", + "0x506300505801b01b32300501b00701b0620053a90632ef007323007057", + "0x1b06a00532300530600505701b0060053230052ef00504101b306005323", + "0x5501b06c00532300501b03f01b01b32300501b00701b01b3aa00501b193", + "0x32300530700505701b00600532300506200504101b30700532300506c005", + "0x1b01b32300501b00701b0700053ab06f00532300706a0052c601b06a005", + "0x530500502501b30500532300507200504301b07200532300506f005044", + "0x1b01b32300501b00701b0340053ac01b32300730500507e01b305005323", + "0x32300530200508f01b30200532300507700508d01b07700532300501b03f", + "0x3230050340052de01b01b32300501b00701b01b3ad00501b19301b074005", + "0x7b00508f01b07b00532300507300509201b07300532300501b03f01b01b", + "0x501b00701b2ff0053ae30007500732300700600504501b074005323005", + "0x530000531f01b01b32300507500532101b01b32300501b02001b01b323", + "0x4700531d01b01b32300503300521601b01b3230050740052dd01b01b323", + "0x1b31a01b2fe00532300501b31b01b01b3230053240052ea01b01b323005", + "0x53230052fd2fe00732401b2fd0053230052fd00502501b2fd005323005", + "0x502801b2fa0053230052fc2fb00702d01b2fb00532300501b00901b2fc", + "0x532300505800503101b05600532300505600504601b2f60053230052fa", + "0x560470052f60053230052f60050b001b00700532300500700531701b058", + "0x501b07c01b01b3230052ff00532101b01b32300501b00701b2f6007058", + "0x732300708805805602419201b0880053230050880051f501b088005323", + "0x9001b01b32300501b02001b01b32300501b00701b2f30860073af2f42f5", + "0x508400521601b2f108400732300503300521501b2f2005323005074005", + "0x4601b2f20053230052f200508f01b2f00053230052f100521701b01b323", + "0x8907f0473230072f22f00473240072f404508701b2f50053230052f5005", + "0x1b32300532c00506301b01b32300501b00701b2e92ea2eb0243b02ec32c", + "0x3230052e800521501b2e800532300501b31b01b01b3230052ec00522c01b", + "0x21b01b2e50053230052e600521701b01b3230052e700521601b2e62e7007", + "0x3230052f500504601b2e30053230052e400521e01b2e40053230052e5005", + "0xb001b08900532300508900531701b07f00532300507f00503101b2f5005", + "0x901b01b32300501b00701b2e308907f2f50470052e30053230052e3005", + "0x3230052e100502801b2e10053230052e92e200702d01b2e200532300501b", + "0x31701b2eb0053230052eb00503101b2f50053230052f500504601b2df005", + "0x2df2ea2eb2f50470052df0053230052df0050b001b2ea0053230052ea005", + "0x1b01b3230050740052dd01b01b32300501b02001b01b32300501b00701b", + "0x1b3230053240052ea01b01b32300504700531d01b01b323005033005216", + "0x32300508d00502501b08d00532300501b22301b07e00532300501b31b01b", + "0x2d01b2de00532300501b00901b08f00532300508d07e00732401b08d005", + "0x508600504601b2dd00532300509200502801b09200532300508f2de007", + "0x1b00700532300500700531701b2f30053230052f300503101b086005323", + "0x1b01b32300501b00701b2dd0072f30860470052dd0053230052dd0050b0", + "0x1b01b32300500600532101b01b32300507000522501b01b32300501b020", + "0x1b3230053240052ea01b01b32300504700531d01b01b323005033005216", + "0x32300508700502501b08700532300501b32c01b09000532300501b31b01b", + "0x2d01b2da00532300501b00901b2dc00532300508709000732401b087005", + "0x505600504601b2d900532300509800502801b0980053230052dc2da007", + "0x1b00700532300500700531701b05800532300505800503101b056005323", + "0x1b01b32300501b00701b2d90070580560470052d90053230052d90050b0", + "0x1b32300505700532101b01b3230053240052ea01b01b323005060005225", + "0x532300501b06a01b09f00532300501b31b01b01b32300504700531d01b", + "0x901b2d800532300509b09f00732401b09b00532300509b00502501b09b", + "0x3230050a300502801b0a30053230052d82d600702d01b2d600532300501b", + "0x31701b05800532300505800503101b05600532300505600504601b2d4005", + "0x2d40070580560470052d40053230052d40050b001b007005323005007005", + "0x1b01b32300503800522501b01b32300501b02001b01b32300501b00701b", + "0x1b32300504600506c01b01b3230053240052ea01b01b3230051f5005321", + "0x3230050a700502501b0a700532300501b22901b0a500532300501b31b01b", + "0x2d01b0aa00532300501b00901b2d20053230050a70a500732401b0a7005", + "0x502500504601b2ce0053230052cf00502801b2cf0053230052d20aa007", + "0x1b00700532300500700531701b04200532300504200503101b025005323", + "0x1b01b32300501b00701b2ce0070420250470052ce0053230052ce0050b0", + "0x532300500900504601b01b32300531f00532101b01b32300504600506c", + "0x1b32300531a00522501b01b32300501b00701b01b3b100501b19301b2cd", + "0x32300504400506c01b01b32300531f00532101b01b32300504600506c01b", + "0x32300501b31b01b01b32300501b02001b2cd00532300504300504601b01b", + "0x732401b2cb0053230052cb00502501b2cb00532300501b04b01b2cc005", + "0x3230050af2ca00702d01b2ca00532300501b00901b0af0053230052cb2cc", + "0x3101b2cd0053230052cd00504601b2c70053230052c800502801b2c8005", + "0x3230052c70050b001b00700532300500700531701b042005323005042005", + "0x32300504600506c01b01b32300501b00701b2c70070422cd0470052c7005", + "0x32300501b31b01b01b32300504400506c01b01b32300502400522c01b01b", + "0x732401b3b20053230053b200502501b3b200532300501b22301b049005", + "0x3230053b33b400702d01b3b400532300501b00901b3b30053230053b2049", + "0x3101b04100532300504100504601b3b50053230050cd00502801b0cd005", + "0x3230053b50050b001b00700532300500700531701b040005323005040005", + "0x700501b00700501b01b32300501b01b01b3b50070400410470053b5005", + "0x32300502400502401b01b32300501b00701b0440450073b6046047007323", + "0x3b704104200732300704300504501b04700532300504700504601b043005", + "0x504100531f01b01b32300504200532101b01b32300501b00701b040005", + "0x3f00502501b03f00532300501b31a01b19300532300501b31b01b01b323", + "0x2300532300501b00901b03e00532300503f19300732401b03f005323005", + "0x504601b02000532300507d00502801b07d00532300503e02300702d01b", + "0x532300500700531701b04600532300504600503101b047005323005047", + "0x32300501b00701b0200070460470470050200053230050200050b001b007", + "0x53210051f501b32100532300501b07c01b01b32300504000532101b01b", + "0x701b31b31d0073b831e31f00732300732104604702419201b321005323", + "0x1b31f00532300531f00504601b31a00532300501b2f401b01b32300501b", + "0x31e31f0472dc01b00700532300500700531701b31e00532300531e005031", + "0x310053b902800532300702d0052da01b02d00932402504732300531a007", + "0x31700532300501b31b01b01b32300502800509801b01b32300501b00701b", + "0x7c00521701b01b3230050b000521601b07c0b000732300531700521501b", + "0x3700532300519200521e01b1920053230051f500521b01b1f5005323005", + "0x900531701b32400532300532400503101b02500532300502500504601b", + "0x701b0370093240250470050370053230050370050b001b009005323005", + "0x2500532300502500504601b03900532300503100502801b01b32300501b", + "0x390050b001b00900532300500900531701b32400532300532400503101b", + "0x501b31b01b01b32300501b00701b039009324025047005039005323005", + "0x32401b03600532300503600502501b03600532300501b22301b038005323", + "0x520d21300702d01b21300532300501b00901b20d005323005036038007", + "0x1b31d00532300531d00504601b21600532300521500502801b215005323", + "0x52160050b001b00700532300500700531701b31b00532300531b005031", + "0x502400522c01b01b32300501b00701b21600731b31d047005216005323", + "0x21b00502501b21b00532300501b22301b21700532300501b31b01b01b323", + "0x21f00532300501b00901b21e00532300521b21700732401b21b005323005", + "0x504601b22300532300522200502801b22200532300521e21f00702d01b", + "0x532300500700531701b04400532300504400503101b045005323005045", + "0x32300501b01b01b2230070440450470052230053230052230050b001b007", + "0x32300501b00701b0440450073ba04604700732300700501b00700501b01b", + "0x504501b04700532300504700504601b04300532300502400502401b01b", + "0x504200532101b01b32300501b00701b0400053bb041042007323007043", + "0x501b31a01b19300532300501b31b01b01b32300504100531f01b01b323", + "0x3e00532300503f19300732401b03f00532300503f00502501b03f005323", + "0x7d00502801b07d00532300503e02300702d01b02300532300501b00901b", + "0x4600532300504600503101b04700532300504700504601b020005323005", + "0x460470470050200053230050200050b001b00700532300500700531701b", + "0x32300501b07c01b01b32300504000532101b01b32300501b00701b020007", + "0x31f00732300732104604702419201b3210053230053210051f501b321005", + "0x4601b31a00532300501b2f401b01b32300501b00701b31b31d0073bc31e", + "0x32300500700531701b31e00532300531e00503101b31f00532300531f005", + "0x2d0052da01b02d00932402504732300531a00731e31f0472d901b007005", + "0x1b32300502800509801b01b32300501b00701b0310053bd028005323007", + "0xb000521601b07c0b000732300531700521501b31700532300501b31b01b", + "0x1b1920053230051f500521b01b1f500532300507c00521701b01b323005", + "0x532400503101b02500532300502500504601b03700532300519200521e", + "0x50370053230050370050b001b00900532300500900531701b324005323", + "0x1b03900532300503100502801b01b32300501b00701b037009324025047", + "0x500900531701b32400532300532400503101b025005323005025005046", + "0x1b00701b0390093240250470050390053230050390050b001b009005323", + "0x502501b03600532300501b22301b03800532300501b31b01b01b323005", + "0x532300501b00901b20d00532300503603800732401b036005323005036", + "0x4601b21600532300521500502801b21500532300520d21300702d01b213", + "0x32300500700531701b31b00532300531b00503101b31d00532300531d005", + "0x501b00701b21600731b31d0470052160053230052160050b001b007005", + "0x501b22301b21700532300501b31b01b01b32300502400522c01b01b323", + "0x21e00532300521b21700732401b21b00532300521b00502501b21b005323", + "0x22200502801b22200532300521e21f00702d01b21f00532300501b00901b", + "0x4400532300504400503101b04500532300504500504601b223005323005", + "0x440450470052230053230052230050b001b00700532300500700531701b", + "0x73be04504600732300700701b00700501b01b32300501b01b01b223007", + "0x4600504601b04200532300504700502401b01b32300501b00701b043044", + "0x501b00701b1930053bf04004100732300704200504501b046005323005", + "0x501b31b01b01b32300504000531f01b01b32300504100532101b01b323", + "0x32401b03e00532300503e00502501b03e00532300501b31a01b03f005323", + "0x502307d00702d01b07d00532300501b00901b02300532300503e03f007", + "0x1b04600532300504600504601b32100532300502000502801b020005323", + "0x502400531701b04500532300504500503101b00500532300500500509f", + "0x701b3210240450050460460053210053230053210050b001b024005323", + "0x1f501b31f00532300501b07c01b01b32300519300532101b01b32300501b", + "0x31b0073c031d31e00732300731f04504602419201b31f00532300531f005", + "0x32300531e00504601b02500532300501b2f401b01b32300501b00701b31a", + "0x31701b00500532300500500509f01b31d00532300531d00503101b31e005", + "0x2d00932404632300502502400531d31e04609b01b024005323005024005", + "0x1b01b32300501b00701b0b00053c13170053230070310052da01b031028", + "0x732300507c00521501b07c00532300501b31b01b01b323005317005098", + "0x521b01b03700532300519200521701b01b3230051f500521601b1921f5", + "0x532300532400504601b03800532300503900521e01b039005323005037", + "0x531701b00900532300500900503101b02d00532300502d00509f01b324", + "0x3802800902d3240460050380053230050380050b001b028005323005028", + "0x32300532400504601b0360053230050b000502801b01b32300501b00701b", + "0x31701b00900532300500900503101b02d00532300502d00509f01b324005", + "0x2800902d3240460050360053230050360050b001b028005323005028005", + "0x532300501b22301b20d00532300501b31b01b01b32300501b00701b036", + "0x901b21500532300521320d00732401b21300532300521300502501b213", + "0x32300521700502801b21700532300521521600702d01b21600532300501b", + "0x3101b00500532300500500509f01b31b00532300531b00504601b21b005", + "0x32300521b0050b001b02400532300502400531701b31a00532300531a005", + "0x504700522c01b01b32300501b00701b21b02431a00531b04600521b005", + "0x21f00502501b21f00532300501b22301b21e00532300501b31b01b01b323", + "0x22300532300501b00901b22200532300521f21e00732401b21f005323005", + "0x504601b22900532300522500502801b22500532300522222300702d01b", + "0x532300504300503101b00500532300500500509f01b044005323005044", + "0x440460052290053230052290050b001b02400532300502400531701b043", + "0x4604700732300700501b00700501b01b32300501b01b01b229024043005", + "0x4601b04300532300502400502401b01b32300501b00701b0440450073c2", + "0x701b0400053c304104200732300704300504501b047005323005047005", + "0x31b01b01b32300504100531f01b01b32300504200532101b01b32300501b", + "0x3f00532300503f00502501b03f00532300501b31a01b19300532300501b", + "0x2300702d01b02300532300501b00901b03e00532300503f19300732401b", + "0x532300504700504601b02000532300507d00502801b07d00532300503e", + "0x50b001b00700532300500700531701b04600532300504600503101b047", + "0x532101b01b32300501b00701b020007046047047005020005323005020", + "0x1b3210053230053210051f501b32100532300501b07c01b01b323005040", + "0x1b32300501b00701b31b31d0073c431e31f007323007321046047024192", + "0x531e00503101b31f00532300531f00504601b31a00532300501b2f401b", + "0x32300531a00731e31f0472d801b00700532300500700531701b31e005323", + "0x501b00701b0310053c502800532300702d0052da01b02d009324025047", + "0x31700521501b31700532300501b31b01b01b32300502800509801b01b323", + "0x1f500532300507c00521701b01b3230050b000521601b07c0b0007323005", + "0x2500504601b03700532300519200521e01b1920053230051f500521b01b", + "0x900532300500900531701b32400532300532400503101b025005323005", + "0x1b32300501b00701b0370093240250470050370053230050370050b001b", + "0x32400503101b02500532300502500504601b03900532300503100502801b", + "0x390053230050390050b001b00900532300500900531701b324005323005", + "0x1b03800532300501b31b01b01b32300501b00701b039009324025047005", + "0x503603800732401b03600532300503600502501b03600532300501b223", + "0x1b21500532300520d21300702d01b21300532300501b00901b20d005323", + "0x531b00503101b31d00532300531d00504601b216005323005215005028", + "0x52160053230052160050b001b00700532300500700531701b31b005323", + "0x31b01b01b32300502400522c01b01b32300501b00701b21600731b31d047", + "0x21b00532300521b00502501b21b00532300501b22301b21700532300501b", + "0x21f00702d01b21f00532300501b00901b21e00532300521b21700732401b", + "0x532300504500504601b22300532300522200502801b22200532300521e", + "0x50b001b00700532300500700531701b04400532300504400503101b045", + "0x700501b01b32300501b01b01b223007044045047005223005323005223", + "0x502401b01b32300501b00701b0440450073c604604700732300700501b", + "0x1b04700532300504700504601b01b32300501b04701b043005323005024", + "0x504401b01b32300501b00701b0400053c7041042007323007043005045", + "0x532300503f00504201b03f00532300519300504301b193005323005041", + "0x1b19301b07d00532300503e00504001b02300532300504200504101b03e", + "0x2000503e01b02000532300501b03f01b01b32300501b00701b01b3c8005", + "0x7d00532300532100504001b02300532300504000504101b321005323005", + "0x504501b01b32300501b00701b31e0053c931f00532300707d00502301b", + "0x531b00504401b01b32300501b00701b31a0053ca31b31d007323007023", + "0x1b00900532300532400504201b32400532300502500504301b025005323", + "0x3cb00501b19301b02800532300500900504001b02d00532300531d005041", + "0x32300503100503e01b03100532300501b03f01b01b32300501b00701b01b", + "0x2301b02800532300531700504001b02d00532300531a00504101b317005", + "0x702d00504501b01b32300501b00701b07c0053cc0b0005323007028005", + "0x1b01b32300501b02001b01b32300501b00701b0370053cd1921f5007323", + "0x1b32300531f00531d01b01b32300519200531f01b01b3230051f5005321", + "0x532300501b31a01b03900532300501b31b01b01b3230050b000531d01b", + "0x901b03600532300503803900732401b03800532300503800502501b038", + "0x32300521300502801b21300532300503620d00702d01b20d00532300501b", + "0x31701b04600532300504600503101b04700532300504700504601b215005", + "0x2150070460470470052150053230052150050b001b007005323005007005", + "0x21600532300501b07c01b01b32300503700532101b01b32300501b00701b", + "0x3ce21b21700732300721604604702419201b2160053230052160051f501b", + "0xb031f0072d601b01b32300501b02001b01b32300501b00701b21f21e007", + "0x21700532300521700504601b22200532300522200502501b222005323005", + "0x501b31b01b01b32300501b00701b2230053cf01b32300722200507e01b", + "0x32401b22900532300522900502501b22900532300501b0a301b225005323", + "0x22c00521601b05322c00732300504b00521501b04b005323005229225007", + "0x1b05100532300505000521b01b05000532300505300521701b01b323005", + "0x521b00503101b21700532300521700504601b05400532300505100521e", + "0x50540053230050540050b001b00700532300500700531701b21b005323", + "0x31b01b01b3230052230052de01b01b32300501b00701b05400721b217047", + "0x24f00532300524f00502501b24f00532300501b2d401b24300532300501b", + "0x5600702d01b05600532300501b00901b25100532300524f24300732401b", + "0x532300521700504601b05700532300505800502801b058005323005251", + "0x50b001b00700532300500700531701b21b00532300521b00503101b217", + "0x1b02001b01b32300501b00701b05700721b217047005057005323005057", + "0x1b31b01b01b3230050b000531d01b01b32300531f00531d01b01b323005", + "0x1b2c60053230052c600502501b2c600532300501b22301b055005323005", + "0x2c92d300702d01b2d300532300501b00901b2c90053230052c6055007324", + "0x21e00532300521e00504601b06000532300503300502801b033005323005", + "0x600050b001b00700532300500700531701b21f00532300521f00503101b", + "0x501b02001b01b32300501b00701b06000721f21e047005060005323005", + "0x2d00532101b01b32300531f00531d01b01b32300507c00522501b01b323", + "0x502501b06300532300501b22901b2ef00532300501b31b01b01b323005", + "0x532300501b00901b0620053230050632ef00732401b063005323005063", + "0x4601b06a00532300500600502801b00600532300506230600702d01b306", + "0x32300500700531701b04600532300504600503101b047005323005047005", + "0x501b00701b06a00704604704700506a00532300506a0050b001b007005", + "0x502300532101b01b32300531e00522501b01b32300501b02001b01b323", + "0x30700502501b30700532300501b04b01b06c00532300501b31b01b01b323", + "0x7000532300501b00901b06f00532300530706c00732401b307005323005", + "0x504601b30500532300507200502801b07200532300506f07000702d01b", + "0x532300500700531701b04600532300504600503101b047005323005047", + "0x32300501b00701b3050070460470470053050053230053050050b001b007", + "0x32300501b22301b03400532300501b31b01b01b32300502400522c01b01b", + "0x1b30200532300507703400732401b07700532300507700502501b077005", + "0x507300502801b07300532300530207400702d01b07400532300501b009", + "0x1b04400532300504400503101b04500532300504500504601b07b005323", + "0x704404504700507b00532300507b0050b001b007005323005007005317", + "0x450073d004604700732300700501b00700501b01b32300501b01b01b07b", + "0x32300501b04701b04300532300502400502401b01b32300501b00701b044", + "0x53d104104200732300704300504501b04700532300504700504601b01b", + "0x504200504101b19300532300504100505801b01b32300501b00701b040", + "0x1b00701b01b3d200501b19301b03e00532300519300505701b03f005323", + "0x4101b07d00532300502300505501b02300532300501b03f01b01b323005", + "0x32300703e0052c601b03e00532300507d00505701b03f005323005040005", + "0x504401b01b32300501b02001b01b32300501b00701b3210053d3020005", + "0x31d00532300503f00521701b31e00532300501b31b01b31f005323005020", + "0x4600503101b04700532300504700504601b31b00532300531f00504301b", + "0x31e00532300531e00521f01b31d00532300531d0052c901b046005323005", + "0x31a02432300531b31e31d0460470462d301b31b00532300531b00502501b", + "0x1b01b32300501b00701b02d0053d400900532300732400503301b324025", + "0x31a00504601b31700532300502800502401b031028007323005009005060", + "0x1f500532300531700504101b07c00532300502500503101b0b0005323005", + "0x1b32300501b00701b01b3d500501b19301b1920053230050310052ef01b", + "0x2500503101b31a00532300531a00504601b03700532300502d00502801b", + "0x370053230050370050b001b00700532300500700531701b025005323005", + "0x22501b01b32300501b02001b01b32300501b00701b03700702531a047005", + "0x3800532300503900506201b03900532300501b03f01b01b323005321005", + "0x3f00504101b07c00532300504600503101b0b000532300504700504601b", + "0x3600532300719200530601b1920053230050380052ef01b1f5005323005", + "0x53d72152130073230071f500504501b01b32300501b00701b20d0053d6", + "0x32300521500531f01b01b32300521300532101b01b32300501b00701b216", + "0x32300501b31a01b21700532300501b31b01b01b32300503600521601b01b", + "0x1b21e00532300521b21700732401b21b00532300521b00502501b21b005", + "0x522200502801b22200532300521e21f00702d01b21f00532300501b009", + "0x1b07c00532300507c00503101b0b00053230050b000504601b223005323", + "0x707c0b00470052230053230052230050b001b007005323005007005317", + "0x532300501b07c01b01b32300521600532101b01b32300501b00701b223", + "0x4b22900732300722507c0b002419201b2250053230052250051f501b225", + "0x504601b05000532300501b2f401b01b32300501b00701b05322c0073d8", + "0x532300500700531701b04b00532300504b00503101b229005323005229", + "0x4732300503605000704b2290460a501b03600532300503600521f01b007", + "0x32300501b00701b0560053d925100532300724f0050a701b24f243054051", + "0x52f301b0550570073230052510052d201b05800532300501b31b01b01b", + "0x73230052c600521501b2c600532300505505800732401b01b323005057", + "0x521b01b0330053230052d300521701b01b3230052c900521601b2d32c9", + "0x532300505100504601b2ef00532300506000521e01b060005323005033", + "0x50b001b24300532300524300531701b05400532300505400503101b051", + "0x502801b01b32300501b00701b2ef2430540510470052ef0053230052ef", + "0x532300505400503101b05100532300505100504601b063005323005056", + "0x510470050630053230050630050b001b24300532300524300531701b054", + "0x501b31b01b01b32300503600521601b01b32300501b00701b063243054", + "0x32401b30600532300530600502501b30600532300501b22301b062005323", + "0x500606a00702d01b06a00532300501b00901b006005323005306062007", + "0x1b22c00532300522c00504601b30700532300506c00502801b06c005323", + "0x53070050b001b00700532300500700531701b053005323005053005031", + "0x520d00522501b01b32300501b00701b30700705322c047005307005323", + "0x501b04b01b06f00532300501b31b01b01b3230051f500532101b01b323", + "0x7200532300507006f00732401b07000532300507000502501b070005323", + "0x3400502801b03400532300507230500702d01b30500532300501b00901b", + "0x7c00532300507c00503101b0b00053230050b000504601b077005323005", + "0x7c0b00470050770053230050770050b001b00700532300500700531701b", + "0x32300501b31b01b01b32300502400522c01b01b32300501b00701b077007", + "0x732401b07400532300507400502501b07400532300501b22301b302005", + "0x32300507307b00702d01b07b00532300501b00901b073005323005074302", + "0x3101b04500532300504500504601b30000532300507500502801b075005", + "0x3230053000050b001b00700532300500700531701b044005323005044005", + "0x700501b00700501b01b32300501b01b01b300007044045047005300005", + "0x32300502400502401b01b32300501b00701b0440450073da046047007323", + "0x3db04104200732300704300504501b04700532300504700504601b043005", + "0x504100531f01b01b32300504200532101b01b32300501b00701b040005", + "0x3f00502501b03f00532300501b31a01b19300532300501b31b01b01b323", + "0x2300532300501b00901b03e00532300503f19300732401b03f005323005", + "0x504601b02000532300507d00502801b07d00532300503e02300702d01b", + "0x532300500700531701b04600532300504600503101b047005323005047", + "0x32300501b00701b0200070460470470050200053230050200050b001b007", + "0x53210051f501b32100532300501b07c01b01b32300504000532101b01b", + "0x701b31b31d0073dc31e31f00732300732104604702419201b321005323", + "0x2501b02500532300501b0aa01b31a00532300501b31b01b01b32300501b", + "0x32300501b00901b32400532300502531a00732401b025005323005025005", + "0x1b02800532300502d00502801b02d00532300532400900702d01b009005", + "0x500700531701b31e00532300531e00503101b31f00532300531f005046", + "0x1b00701b02800731e31f0470050280053230050280050b001b007005323", + "0x502501b31700532300501b22301b03100532300501b31b01b01b323005", + "0x532300501b00901b0b000532300531703100732401b317005323005317", + "0x4601b1920053230051f500502801b1f50053230050b007c00702d01b07c", + "0x32300500700531701b31b00532300531b00503101b31d00532300531d005", + "0x501b00701b19200731b31d0470051920053230051920050b001b007005", + "0x501b22301b03700532300501b31b01b01b32300502400522c01b01b323", + "0x3800532300503903700732401b03900532300503900502501b039005323", + "0x20d00502801b20d00532300503803600702d01b03600532300501b00901b", + "0x4400532300504400503101b04500532300504500504601b213005323005", + "0x440450470052130053230052130050b001b00700532300500700531701b", + "0x73dd04604700732300700501b00700501b01b32300501b01b01b213007", + "0x501b04701b04300532300502400502401b01b32300501b00701b044045", + "0x3de04104200732300704300504501b04700532300504700504601b01b323", + "0x19300504301b19300532300504100504401b01b32300501b00701b040005", + "0x2300532300504200504101b03e00532300503f00504201b03f005323005", + "0x1b32300501b00701b01b3df00501b19301b07d00532300503e00504001b", + "0x504000504101b32100532300502000503e01b02000532300501b03f01b", + "0x3e031f00532300707d00502301b07d00532300532100504001b023005323", + "0x31a0053e131b31d00732300702300504501b01b32300501b00701b31e005", + "0x1b01b32300531d00532101b01b32300501b02001b01b32300501b00701b", + "0x2500532300501b31b01b01b32300531f00531d01b01b32300531b00531f", + "0x32402500732401b32400532300532400502501b32400532300501b31a01b", + "0x2800532300500902d00702d01b02d00532300501b00901b009005323005", + "0x4600503101b04700532300504700504601b03100532300502800502801b", + "0x310053230050310050b001b00700532300500700531701b046005323005", + "0x32101b01b32300501b02001b01b32300501b00701b031007046047047005", + "0x3170053230053170051f501b31700532300501b07c01b01b32300531a005", + "0x32300501b00701b1921f50073e207c0b000732300731704604702419201b", + "0x7c00503101b0b00053230050b000504601b03700532300501b2f401b01b", + "0x531f03707c0b00472cf01b31f00532300531f00502501b07c005323005", + "0x501b00701b2130053e320d0053230070360052da01b036038039024323", + "0x21500521501b21500532300501b31b01b01b32300520d00509801b01b323", + "0x21b00532300521700521701b01b32300521600521601b217216007323005", + "0x3900504601b21f00532300521e00521e01b21e00532300521b00521b01b", + "0x700532300500700531701b03800532300503800503101b039005323005", + "0x1b32300501b00701b21f00703803904700521f00532300521f0050b001b", + "0x3800503101b03900532300503900504601b22200532300521300502801b", + "0x2220053230052220050b001b00700532300500700531701b038005323005", + "0x1b01b32300531f00531d01b01b32300501b00701b222007038039047005", + "0x532300522500502501b22500532300501b22301b22300532300501b31b", + "0x702d01b04b00532300501b00901b22900532300522522300732401b225", + "0x3230051f500504601b05300532300522c00502801b22c00532300522904b", + "0xb001b00700532300500700531701b19200532300519200503101b1f5005", + "0x2001b01b32300501b00701b0530071921f5047005053005323005053005", + "0x31b01b01b32300502300532101b01b32300531e00522501b01b32300501b", + "0x5100532300505100502501b05100532300501b04b01b05000532300501b", + "0x24300702d01b24300532300501b00901b05400532300505105000732401b", + "0x532300504700504601b25100532300524f00502801b24f005323005054", + "0x50b001b00700532300500700531701b04600532300504600503101b047", + "0x522c01b01b32300501b00701b251007046047047005251005323005251", + "0x2501b05800532300501b22301b05600532300501b31b01b01b323005024", + "0x32300501b00901b05700532300505805600732401b058005323005058005", + "0x1b2c90053230052c600502801b2c600532300505705500702d01b055005", + "0x500700531701b04400532300504400503101b045005323005045005046", + "0x1b01b01b2c90070440450470052c90053230052c90050b001b007005323", + "0x1b00701b0440450073e404604700732300700501b00700501b01b323005", + "0x504601b01b32300501b04701b04300532300502400502401b01b323005", + "0x1b00701b0400053e504104200732300704300504501b047005323005047", + "0x1b03f00532300519300504301b19300532300504100504401b01b323005", + "0x503e00504001b02300532300504200504101b03e00532300503f005042", + "0x32300501b03f01b01b32300501b00701b01b3e600501b19301b07d005323", + "0x4001b02300532300504000504101b32100532300502000503e01b020005", + "0x1b00701b31e0053e731f00532300707d00502301b07d005323005321005", + "0x32300501b00701b31a0053e831b31d00732300702300504501b01b323005", + "0x32300531b00531f01b01b32300531d00532101b01b32300501b02001b01b", + "0x32300501b31a01b02500532300501b31b01b01b32300531f00531d01b01b", + "0x1b00900532300532402500732401b32400532300532400502501b324005", + "0x502800502801b02800532300500902d00702d01b02d00532300501b009", + "0x1b04600532300504600503101b04700532300504700504601b031005323", + "0x70460470470050310053230050310050b001b007005323005007005317", + "0x1b32300531a00532101b01b32300501b02001b01b32300501b00701b031", + "0x4604702419201b3170053230053170051f501b31700532300501b07c01b", + "0x501b2f401b01b32300501b00701b1921f50073e907c0b0007323007317", + "0x1b07c00532300507c00503101b0b00053230050b000504601b037005323", + "0x3603803902432300531f03707c0b00472ce01b31f00532300531f005025", + "0x509801b01b32300501b00701b2130053ea20d0053230070360052da01b", + "0x21721600732300521500521501b21500532300501b31b01b01b32300520d", + "0x521b00521b01b21b00532300521700521701b01b32300521600521601b", + "0x1b03900532300503900504601b21f00532300521e00521e01b21e005323", + "0x521f0050b001b00700532300500700531701b038005323005038005031", + "0x521300502801b01b32300501b00701b21f00703803904700521f005323", + "0x1b03800532300503800503101b03900532300503900504601b222005323", + "0x70380390470052220053230052220050b001b007005323005007005317", + "0x532300501b31b01b01b32300531f00531d01b01b32300501b00701b222", + "0x22300732401b22500532300522500502501b22500532300501b22301b223", + "0x532300522904b00702d01b04b00532300501b00901b229005323005225", + "0x503101b1f50053230051f500504601b05300532300522c00502801b22c", + "0x53230050530050b001b00700532300500700531701b192005323005192", + "0x1b01b32300501b02001b01b32300501b00701b0530071921f5047005053", + "0x5000532300501b31b01b01b32300502300532101b01b32300531e005225", + "0x5105000732401b05100532300505100502501b05100532300501b04b01b", + "0x24f00532300505424300702d01b24300532300501b00901b054005323005", + "0x4600503101b04700532300504700504601b25100532300524f00502801b", + "0x2510053230052510050b001b00700532300500700531701b046005323005", + "0x1b01b32300502400522c01b01b32300501b00701b251007046047047005", + "0x532300505800502501b05800532300501b22301b05600532300501b31b", + "0x702d01b05500532300501b00901b05700532300505805600732401b058", + "0x32300504500504601b2c90053230052c600502801b2c6005323005057055", + "0xb001b00700532300500700531701b04400532300504400503101b045005", + "0x501b01b32300501b01b01b2c90070440450470052c90053230052c9005", + "0x2401b01b32300501b00701b0440450073eb04604700732300700501b007", + "0x4700532300504700504601b01b32300501b04701b043005323005024005", + "0x4401b01b32300501b00701b0400053ec04104200732300704300504501b", + "0x32300503f00504201b03f00532300519300504301b193005323005041005", + "0x19301b07d00532300503e00504001b02300532300504200504101b03e005", + "0x503e01b02000532300501b03f01b01b32300501b00701b01b3ed00501b", + "0x532300532100504001b02300532300504000504101b321005323005020", + "0x5601b01b32300501b00701b31e0053ee31f00532300707d00502301b07d", + "0x504601b01b32300501b00701b31a0053ef31b31d00732300731f047007", + "0x1b00701b0090053f032402500732300702300504501b31d00532300531d", + "0x1b02800532300502d00504301b02d00532300532400504401b01b323005", + "0x503100504001b31700532300502500504101b031005323005028005042", + "0x32300501b03f01b01b32300501b00701b01b3f100501b19301b0b0005323", + "0x4001b31700532300500900504101b1f500532300507c00503e01b07c005", + "0x1b00701b0370053f21920053230070b000502301b0b00053230051f5005", + "0x32300501b00701b0360053f303803900732300731700504501b01b323005", + "0x504201b21300532300520d00504301b20d00532300503800504401b01b", + "0x532300521500504001b21600532300503900504101b215005323005213", + "0x21b00532300501b03f01b01b32300501b00701b01b3f400501b19301b217", + "0x21e00504001b21600532300503600504101b21e00532300521b00503e01b", + "0x32300501b00701b2220053f521f00532300721700502301b217005323005", + "0x1b01b32300501b00701b2290053f622522300732300721600504501b01b", + "0x1b01b32300522500531f01b01b32300522300532101b01b32300501b020", + "0x1b32300519200531d01b01b32300531b00506301b01b32300521f00531d", + "0x32300522c00502501b22c00532300501b31a01b04b00532300501b31b01b", + "0x2d01b05000532300501b00901b05300532300522c04b00732401b22c005", + "0x531d00504601b05400532300505100502801b051005323005053050007", + "0x1b00700532300500700531701b04600532300504600503101b31d005323", + "0x1b01b32300501b00701b05400704631d0470050540053230050540050b0", + "0x53230052430051f501b24300532300501b07c01b01b323005229005321", + "0x501b00701b0580560073f725124f00732300724304631d02419201b243", + "0x1b24f00532300524f00504601b05721f00732300521f0052cd01b01b323", + "0x519200531d01b01b32300501b00701b0550053f801b32300705700507e", + "0x25100503101b01b32300521f00531d01b01b32300531b00506301b01b323", + "0x701b01b3f900501b19301b2c900532300500700531701b2c6005323005", + "0x2cc01b2d300532300501b31b01b01b3230050550052de01b01b32300501b", + "0x602d300732401b0600053230050330052cb01b03331b00732300531b005", + "0x3230050632ef00732401b0631920073230051920052cd01b2ef005323005", + "0x2501b00600532300530621f0072d601b30600532300501b05101b062005", + "0x506a00521501b06a00532300500606200732401b006005323005006005", + "0x1b06f00532300530700521701b01b32300506c00521601b30706c007323", + "0x7207002432300706f19231b00725104600601b06f00532300506f0052c9", + "0x1b01b32300530500522c01b01b32300501b00701b3020770340243fa305", + "0x32300501b02001b2c900532300507200531701b2c6005323005070005031", + "0x521601b07b07300732300507400521501b07400532300501b31b01b01b", + "0x30000532300507500521b01b07500532300507b00521701b01b323005073", + "0x2c600503101b24f00532300524f00504601b2ff00532300530000521e01b", + "0x2ff0053230052ff0050b001b2c90053230052c900531701b2c6005323005", + "0x901b01b32300501b02001b01b32300501b00701b2ff2c92c624f047005", + "0x3230052fd00502801b2fd0053230053022fe00702d01b2fe00532300501b", + "0x31701b03400532300503400503101b24f00532300524f00504601b2fc005", + "0x2fc07703424f0470052fc0053230052fc0050b001b077005323005077005", + "0x1b01b32300521f00531d01b01b32300501b02001b01b32300501b00701b", + "0x2fb00532300501b31b01b01b32300519200531d01b01b32300531b005063", + "0x2fa2fb00732401b2fa0053230052fa00502501b2fa00532300501b22301b", + "0x2f50053230052f608800702d01b08800532300501b00901b2f6005323005", + "0x5800503101b05600532300505600504601b2f40053230052f500502801b", + "0x2f40053230052f40050b001b00700532300500700531701b058005323005", + "0x22501b01b32300501b02001b01b32300501b00701b2f4007058056047005", + "0x1b01b32300531b00506301b01b32300521600532101b01b323005222005", + "0x2f300532300501b06a01b08600532300501b31b01b01b32300519200531d", + "0x1b00901b2f20053230052f308600732401b2f30053230052f300502501b", + "0x53230052f100502801b2f10053230052f208400702d01b084005323005", + "0x531701b04600532300504600503101b31d00532300531d00504601b2f0", + "0x1b2f000704631d0470052f00053230052f00050b001b007005323005007", + "0x32101b01b32300503700522501b01b32300501b02001b01b32300501b007", + "0x1b07f00532300501b31b01b01b32300531b00506301b01b323005317005", + "0x508907f00732401b08900532300508900502501b08900532300501b229", + "0x1b2eb00532300532c2ec00702d01b2ec00532300501b00901b32c005323", + "0x504600503101b31d00532300531d00504601b2ea0053230052eb005028", + "0x52ea0053230052ea0050b001b00700532300500700531701b046005323", + "0x4601b01b32300502300532101b01b32300501b00701b2ea00704631d047", + "0x22501b01b32300501b00701b01b3fb00501b19301b2e900532300531a005", + "0x2e900532300504700504601b01b32300502300532101b01b32300531e005", + "0x2e700532300501b04b01b2e800532300501b31b01b01b32300501b02001b", + "0x1b00901b2e60053230052e72e800732401b2e70053230052e700502501b", + "0x53230052e400502801b2e40053230052e62e500702d01b2e5005323005", + "0x531701b04600532300504600503101b2e90053230052e900504601b2e3", + "0x1b2e30070462e90470052e30053230052e30050b001b007005323005007", + "0x1b2e200532300501b31b01b01b32300502400522c01b01b32300501b007", + "0x52e12e200732401b2e10053230052e100502501b2e100532300501b223", + "0x1b08d0053230052df07e00702d01b07e00532300501b00901b2df005323", + "0x504400503101b04500532300504500504601b08f00532300508d005028", + "0x508f00532300508f0050b001b00700532300500700531701b044005323", + "0x4600732300700700500700501b01b32300501b01b01b08f007044045047", + "0x1b04200532300504700502401b01b32300501b00701b0430440073fc045", + "0x732300704200504501b04600532300504600504601b01b32300501b047", + "0x1b03f00532300504000504401b01b32300501b00701b1930053fd040041", + "0x504100504101b02300532300503e00504201b03e00532300503f005043", + "0x1b00701b01b3fe00501b19301b02000532300502300504001b07d005323", + "0x4101b31f00532300532100503e01b32100532300501b03f01b01b323005", + "0x32300702000502301b02000532300531f00504001b07d005323005193005", + "0x31a31b00732300707d00504501b01b32300501b00701b31d0053ff31e005", + "0x504301b32400532300531a00504401b01b32300501b00701b025005400", + "0x532300531b00504101b02d00532300500900504201b009005323005324", + "0x32300501b00701b01b40100501b19301b03100532300502d00504001b028", + "0x2500504101b0b000532300531700503e01b31700532300501b03f01b01b", + "0x7c00532300703100502301b0310053230050b000504001b028005323005", + "0x540303719200732300702800504501b01b32300501b00701b1f5005402", + "0x503800504301b03800532300503700504401b01b32300501b00701b039", + "0x1b21300532300519200504101b20d00532300503600504201b036005323", + "0x1b01b32300501b00701b01b40400501b19301b21500532300520d005040", + "0x32300503900504101b21700532300521600503e01b21600532300501b03f", + "0x540521b00532300721500502301b21500532300521700504001b213005", + "0x1b22300540622221f00732300721300504501b01b32300501b00701b21e", + "0x31f01b01b32300521f00532101b01b32300501b02001b01b32300501b007", + "0x1b01b32300507c00531d01b01b32300521b00531d01b01b323005222005", + "0x22900532300501b31a01b22500532300501b31b01b01b32300531e00531d", + "0x1b00901b04b00532300522922500732401b22900532300522900502501b", + "0x532300505300502801b05300532300504b22c00702d01b22c005323005", + "0x503101b04600532300504600504601b01b00532300501b0050af01b050", + "0x53230050500050b001b02400532300502400531701b045005323005045", + "0x32300522300532101b01b32300501b00701b05002404504601b046005050", + "0x4602419201b0510053230050510051f501b05100532300501b07c01b01b", + "0x1b02001b01b32300501b00701b25124f007407243054007323007051045", + "0x3101b05400532300505400504601b05600532300501b2f401b01b323005", + "0x32300502400531701b01b00532300501b0050af01b243005323005243005", + "0x2501b07c00532300507c00502501b31e00532300531e00502501b024005", + "0x4632300521b07c31e05602401b2430540432ca01b21b00532300521b005", + "0x501b00701b0330054082d30053230072c90052da01b2c92c6055057058", + "0x6000521501b06000532300501b31b01b01b3230052d300509801b01b323", + "0x6200532300506300521701b01b3230052ef00521601b0632ef007323005", + "0x550050af01b00600532300530600521e01b30600532300506200521b01b", + "0x5700532300505700503101b05800532300505800504601b055005323005", + "0x580550460050060053230050060050b001b2c60053230052c600531701b", + "0x50af01b06a00532300503300502801b01b32300501b00701b0062c6057", + "0x532300505700503101b05800532300505800504601b055005323005055", + "0x5504600506a00532300506a0050b001b2c60053230052c600531701b057", + "0x21b00531d01b01b32300501b02001b01b32300501b00701b06a2c6057058", + "0x1b31b01b01b32300531e00531d01b01b32300507c00531d01b01b323005", + "0x1b30700532300530700502501b30700532300501b22301b06c005323005", + "0x6f07000702d01b07000532300501b00901b06f00532300530706c007324", + "0x1b00532300501b0050af01b30500532300507200502801b072005323005", + "0x2400531701b25100532300525100503101b24f00532300524f00504601b", + "0x1b30502425124f01b0460053050053230053050050b001b024005323005", + "0x32101b01b32300521e00522501b01b32300501b02001b01b32300501b007", + "0x1b01b32300531e00531d01b01b32300507c00531d01b01b323005213005", + "0x532300507700502501b07700532300501b06a01b03400532300501b31b", + "0x702d01b07400532300501b00901b30200532300507703400732401b077", + "0x32300501b0050af01b07b00532300507300502801b073005323005302074", + "0x31701b04500532300504500503101b04600532300504600504601b01b005", + "0x2404504601b04600507b00532300507b0050b001b024005323005024005", + "0x1b3230051f500522501b01b32300501b02001b01b32300501b00701b07b", + "0x532300501b31b01b01b32300502800532101b01b32300531e00531d01b", + "0x7500732401b30000532300530000502501b30000532300501b22901b075", + "0x53230052ff2fe00702d01b2fe00532300501b00901b2ff005323005300", + "0x504601b01b00532300501b0050af01b2fc0053230052fd00502801b2fd", + "0x532300502400531701b04500532300504500503101b046005323005046", + "0x501b00701b2fc02404504601b0460052fc0053230052fc0050b001b024", + "0x507d00532101b01b32300531d00522501b01b32300501b02001b01b323", + "0x2fa00502501b2fa00532300501b04b01b2fb00532300501b31b01b01b323", + "0x8800532300501b00901b2f60053230052fa2fb00732401b2fa005323005", + "0x50af01b2f40053230052f500502801b2f50053230052f608800702d01b", + "0x532300504500503101b04600532300504600504601b01b00532300501b", + "0x1b0460052f40053230052f40050b001b02400532300502400531701b045", + "0x1b31b01b01b32300504700522c01b01b32300501b00701b2f4024045046", + "0x1b2f30053230052f300502501b2f300532300501b22301b086005323005", + "0x2f208400702d01b08400532300501b00901b2f20053230052f3086007324", + "0x1b00532300501b0050af01b2f00053230052f100502801b2f1005323005", + "0x2400531701b04300532300504300503101b04400532300504400504601b", + "0x1b2f002404304401b0460052f00053230052f00050b001b024005323005", + "0x1b04204300740904404500732300702400500700501b01b32300501b01b", + "0x53230050460052c901b04500532300504500504601b01b32300501b007", + "0x3f0053230071930052c701b1930400410243230050460450072c801b046", + "0x504501b02300532300504000502401b01b32300501b00701b03e00540a", + "0x507d00532101b01b32300501b00701b32100540b02007d007323007023", + "0x501b31b01b01b32300503f00504901b01b32300502000531f01b01b323", + "0x32401b31e00532300531e00502501b31e00532300501b31a01b31f005323", + "0x531d31b00702d01b31b00532300501b00901b31d00532300531e31f007", + "0x1b01b00532300501b0050af01b02500532300531a00502801b31a005323", + "0x504400503101b00700532300500700509f01b041005323005041005046", + "0x50250053230050250050b001b04700532300504700531701b044005323", + "0x1b32300532100532101b01b32300501b00701b02504704400704101b045", + "0x4404102419201b3240053230053240051f501b32400532300501b07c01b", + "0x501b2f401b01b32300501b00701b03102800740c02d009007323007324", + "0x1b02d00532300502d00503101b00900532300500900504601b317005323", + "0x504700531701b01b00532300501b0050af01b00700532300500700509f", + "0x31704701b00702d0090443b301b03f00532300503f0053b201b047005323", + "0x540d0380053230070390052da01b0390371921f507c0b004532300503f", + "0x532300501b31b01b01b32300503800509801b01b32300501b00701b036", + "0x521701b01b32300521300521601b21521300732300520d00521501b20d", + "0x532300521700521e01b21700532300521600521b01b216005323005215", + "0x509f01b0b00053230050b000504601b1920053230051920050af01b21b", + "0x532300503700531701b07c00532300507c00503101b1f50053230051f5", + "0x1b00701b21b03707c1f50b019204500521b00532300521b0050b001b037", + "0x1b1920053230051920050af01b21e00532300503600502801b01b323005", + "0x507c00503101b1f50053230051f500509f01b0b00053230050b0005046", + "0x521e00532300521e0050b001b03700532300503700531701b07c005323", + "0x1b32300503f00504901b01b32300501b00701b21e03707c1f50b0192045", + "0x32300522200502501b22200532300501b22301b21f00532300501b31b01b", + "0x2d01b22500532300501b00901b22300532300522221f00732401b222005", + "0x501b0050af01b04b00532300522900502801b229005323005223225007", + "0x1b00700532300500700509f01b02800532300502800504601b01b005323", + "0x504b0050b001b04700532300504700531701b031005323005031005031", + "0x522501b01b32300501b00701b04b04703100702801b04500504b005323", + "0x4b01b22c00532300501b31b01b01b32300504000522c01b01b32300503e", + "0x32300505322c00732401b05300532300505300502501b05300532300501b", + "0x2801b05400532300505005100702d01b05100532300501b00901b050005", + "0x32300504100504601b01b00532300501b0050af01b243005323005054005", + "0x31701b04400532300504400503101b00700532300500700509f01b041005", + "0x4400704101b0450052430053230052430050b001b047005323005047005", + "0x32300501b31b01b01b32300504600522c01b01b32300501b00701b243047", + "0x732401b25100532300525100502501b25100532300501b22301b24f005", + "0x32300505605800702d01b05800532300501b00901b05600532300525124f", + "0x4601b01b00532300501b0050af01b05500532300505700502801b057005", + "0x32300504200503101b00700532300500700509f01b043005323005043005", + "0x450050550053230050550050b001b04700532300504700531701b042005", + "0x732300700501b00700501b01b32300501b01b01b05504704200704301b", + "0x4300532300502400502401b01b32300501b00701b04404500740e046047", + "0x32300704300504501b04700532300504700504601b01b32300501b04701b", + "0x19300532300504100504401b01b32300501b00701b04000540f041042007", + "0x4200504101b03e00532300503f00504201b03f00532300519300504301b", + "0x701b01b41000501b19301b07d00532300503e00504001b023005323005", + "0x1b32100532300502000503e01b02000532300501b03f01b01b32300501b", + "0x707d00502301b07d00532300532100504001b023005323005040005041", + "0x732300731f04700705601b01b32300501b00701b31e00541131f005323", + "0x1b02500532300502300521701b01b32300501b00701b31a00541231b31d", + "0x2531d0072c801b0250053230050250052c901b31d00532300531d005046", + "0x1b00701b03100541302800532300702d0052c701b02d009324024323005", + "0x7c0b000732300731700504501b31700532300500900502401b01b323005", + "0x50b000532101b01b32300501b02001b01b32300501b00701b1f5005414", + "0x31b00506301b01b32300502800504901b01b32300507c00531f01b01b323", + "0x502501b03700532300501b31a01b19200532300501b31b01b01b323005", + "0x532300501b00901b03900532300503719200732401b037005323005037", + "0x4601b20d00532300503600502801b03600532300503903800702d01b038", + "0x32300500700531701b04600532300504600503101b324005323005324005", + "0x501b00701b20d00704632404700520d00532300520d0050b001b007005", + "0x32300501b07c01b01b3230051f500532101b01b32300501b02001b01b323", + "0x21500732300721304632402419201b2130053230052130051f501b213005", + "0x3b401b21e00532300501b31b01b01b32300501b00701b21b217007415216", + "0x3230052220050cd01b01b32300521f00504901b22221f007323005028005", + "0x1b01b3230052290050b701b2292250073230052230053b501b223222007", + "0x2220053b501b22c00532300504b21e00732401b04b005323005225005043", + "0x510073230050500050b601b01b32300505300531d01b050053007323005", + "0x732401b24f0053230052430050bb01b2430053230050510050b901b054", + "0x3230050560050bb01b0560053230050540050b901b25100532300524f22c", + "0x21501b05500532300501b0bf01b05700532300505825100732401b058005", + "0x3230052c900521701b01b3230052c600521601b2c92c6007323005057005", + "0x4601b2d30053230052d30052c901b05500532300505500502501b2d3005", + "0x2ef0600330243230072d305531b00721604600601b215005323005215005", + "0x31b01b01b3230052ef00522c01b01b32300501b00701b306062063024416", + "0x32300506a00521601b06c06a00732300500600521501b00600532300501b", + "0x521e01b06f00532300530700521b01b30700532300506c00521701b01b", + "0x532300503300503101b21500532300521500504601b07000532300506f", + "0x2150470050700053230050700050b001b06000532300506000531701b033", + "0x7200702d01b07200532300501b00901b01b32300501b00701b070060033", + "0x532300521500504601b03400532300530500502801b305005323005306", + "0x50b001b06200532300506200531701b06300532300506300503101b215", + "0x504901b01b32300501b00701b034062063215047005034005323005034", + "0x22301b07700532300501b31b01b01b32300531b00506301b01b323005028", + "0x32300530207700732401b30200532300530200502501b30200532300501b", + "0x2801b07b00532300507407300702d01b07300532300501b00901b074005", + "0x32300521b00503101b21700532300521700504601b07500532300507b005", + "0x470050750053230050750050b001b00700532300500700531701b21b005", + "0x3100522501b01b32300501b02001b01b32300501b00701b07500721b217", + "0x1b31b01b01b32300531b00506301b01b32300500900522c01b01b323005", + "0x1b2ff0053230052ff00502501b2ff00532300501b22901b300005323005", + "0x2fe2fd00702d01b2fd00532300501b00901b2fe0053230052ff300007324", + "0x32400532300532400504601b2fb0053230052fc00502801b2fc005323005", + "0x2fb0050b001b00700532300500700531701b04600532300504600503101b", + "0x2300532101b01b32300501b00701b2fb0070463240470052fb005323005", + "0x1b00701b01b41700501b19301b2fa00532300531a00504601b01b323005", + "0x504601b01b32300502300532101b01b32300531e00522501b01b323005", + "0x4b01b2f600532300501b31b01b01b32300501b02001b2fa005323005047", + "0x3230050882f600732401b08800532300508800502501b08800532300501b", + "0x2801b0860053230052f52f400702d01b2f400532300501b00901b2f5005", + "0x32300504600503101b2fa0053230052fa00504601b2f3005323005086005", + "0x470052f30053230052f30050b001b00700532300500700531701b046005", + "0x1b31b01b01b32300502400522c01b01b32300501b00701b2f30070462fa", + "0x1b08400532300508400502501b08400532300501b22301b2f2005323005", + "0x2f12f000702d01b2f000532300501b00901b2f10053230050842f2007324", + "0x4500532300504500504601b08900532300507f00502801b07f005323005", + "0x890050b001b00700532300500700531701b04400532300504400503101b", + "0x1b00700501b01b32300501b01b01b089007044045047005089005323005", + "0x4700502401b01b32300501b00701b043044007418045046007323007007", + "0x4100732300704200504501b04600532300504600504601b042005323005", + "0x531f01b01b32300504100532101b01b32300501b00701b193005419040", + "0x2501b03e00532300501b31a01b03f00532300501b31b01b01b323005040", + "0x32300501b00901b02300532300503e03f00732401b03e00532300503e005", + "0x1b32100532300502000502801b02000532300502307d00702d01b07d005", + "0x504500503101b0050053230050050052c501b046005323005046005046", + "0x53210053230053210050b001b02400532300502400531701b045005323", + "0x1b01b32300519300532101b01b32300501b00701b321024045005046046", + "0x31f04504602419201b31f00532300531f0051f501b31f00532300501b07c", + "0x32300501b2f401b01b32300501b00701b31a31b00741a31d31e007323007", + "0x3101b0050053230050050052c501b31e00532300531e00504601b025005", + "0x31d00531e04641b01b02400532300502400531701b31d00532300531d005", + "0x541c3170053230070310052da01b03102802d009324046323005025024", + "0x532300501b31b01b01b32300531700509801b01b32300501b00701b0b0", + "0x521701b01b3230051f500521601b1921f500732300507c00521501b07c", + "0x532300503900521e01b03900532300503700521b01b037005323005192", + "0x503101b0090053230050090052c501b32400532300532400504601b038", + "0x53230050380050b001b02800532300502800531701b02d00532300502d", + "0x3230050b000502801b01b32300501b00701b03802802d009324046005038", + "0x3101b0090053230050090052c501b32400532300532400504601b036005", + "0x3230050360050b001b02800532300502800531701b02d00532300502d005", + "0x32300501b31b01b01b32300501b00701b03602802d009324046005036005", + "0x732401b21300532300521300502501b21300532300501b22301b20d005", + "0x32300521521600702d01b21600532300501b00901b21500532300521320d", + "0x2c501b31b00532300531b00504601b21b00532300521700502801b217005", + "0x32300502400531701b31a00532300531a00503101b005005323005005005", + "0x1b00701b21b02431a00531b04600521b00532300521b0050b001b024005", + "0x1b22301b21e00532300501b31b01b01b32300504700522c01b01b323005", + "0x532300521f21e00732401b21f00532300521f00502501b21f005323005", + "0x502801b22500532300522222300702d01b22300532300501b00901b222", + "0x53230050050052c501b04400532300504400504601b229005323005225", + "0x50b001b02400532300502400531701b04300532300504300503101b005", + "0x501b01b32300501b01b01b229024043005044046005229005323005229", + "0x2401b01b32300501b00701b04304400741d045046007323007007005007", + "0x4600532300504600504601b01b32300501b04701b042005323005047005", + "0x4401b01b32300501b00701b19300541e04004100732300704200504501b", + "0x32300503e00504201b03e00532300503f00504301b03f005323005040005", + "0x19301b02000532300502300504001b07d00532300504100504101b023005", + "0x503e01b32100532300501b03f01b01b32300501b00701b01b41f00501b", + "0x532300531f00504001b07d00532300519300504101b31f005323005321", + "0x4501b01b32300501b00701b31d00542031e00532300702000502301b020", + "0x501b02001b01b32300501b00701b02500542131a31b00732300707d005", + "0x31e00531d01b01b32300531a00531f01b01b32300531b00532101b01b323", + "0x502501b00900532300501b31a01b32400532300501b31b01b01b323005", + "0x532300501b00901b02d00532300500932400732401b009005323005009", + "0xaf01b31700532300503100502801b03100532300502d02800702d01b028", + "0x32300504500503101b04600532300504600504601b01b00532300501b005", + "0x460053170053230053170050b001b02400532300502400531701b045005", + "0x532101b01b32300501b02001b01b32300501b00701b31702404504601b", + "0x1b0b00053230050b00051f501b0b000532300501b07c01b01b323005025", + "0x1b32300501b00701b0371920074221f507c0073230070b0045046024192", + "0x51f500503101b07c00532300507c00504601b03900532300501b2f401b", + "0x1b02400532300502400531701b01b00532300501b0050af01b1f5005323", + "0x3804632300531e03902401b1f507c0452d501b31e00532300531e005025", + "0x32300501b00701b2170054232160053230072150052da01b21521320d036", + "0x521b00521501b21b00532300501b31b01b01b32300521600509801b01b", + "0x1b22200532300521f00521701b01b32300521e00521601b21f21e007323", + "0x520d0050af01b22500532300522300521e01b22300532300522200521b", + "0x1b03600532300503600503101b03800532300503800504601b20d005323", + "0x3603820d0460052250053230052250050b001b213005323005213005317", + "0x20d0050af01b22900532300521700502801b01b32300501b00701b225213", + "0x3600532300503600503101b03800532300503800504601b20d005323005", + "0x3820d0460052290053230052290050b001b21300532300521300531701b", + "0x501b31b01b01b32300531e00531d01b01b32300501b00701b229213036", + "0x32401b22c00532300522c00502501b22c00532300501b22301b04b005323", + "0x505305000702d01b05000532300501b00901b05300532300522c04b007", + "0x1b01b00532300501b0050af01b05400532300505100502801b051005323", + "0x502400531701b03700532300503700503101b192005323005192005046", + "0x701b05402403719201b0460050540053230050540050b001b024005323", + "0x532101b01b32300531d00522501b01b32300501b02001b01b32300501b", + "0x2501b24f00532300501b04b01b24300532300501b31b01b01b32300507d", + "0x32300501b00901b25100532300524f24300732401b24f00532300524f005", + "0x1b05700532300505800502801b05800532300525105600702d01b056005", + "0x504500503101b04600532300504600504601b01b00532300501b0050af", + "0x50570053230050570050b001b02400532300502400531701b045005323", + "0x1b01b32300504700522c01b01b32300501b00701b05702404504601b046", + "0x53230052c600502501b2c600532300501b22301b05500532300501b31b", + "0x702d01b2d300532300501b00901b2c90053230052c605500732401b2c6", + "0x32300501b0050af01b06000532300503300502801b0330053230052c92d3", + "0x31701b04300532300504300503101b04400532300504400504601b01b005", + "0x2404304401b0460050600053230050600050b001b024005323005024005", + "0x4500742404604700732300700501b00700501b01b32300501b01b01b060", + "0x32300501b04701b04300532300502400502401b01b32300501b00701b044", + "0x542504104200732300704300504501b04700532300504700504601b01b", + "0x519300504301b19300532300504100504401b01b32300501b00701b040", + "0x1b02300532300504200504101b03e00532300503f00504201b03f005323", + "0x1b01b32300501b00701b01b42600501b19301b07d00532300503e005040", + "0x32300504000504101b32100532300502000503e01b02000532300501b03f", + "0x542731f00532300707d00502301b07d00532300532100504001b023005", + "0x1b31a00542831b31d00732300702300504501b01b32300501b00701b31e", + "0x31f01b01b32300531d00532101b01b32300501b02001b01b32300501b007", + "0x1b02500532300501b31b01b01b32300531f00531d01b01b32300531b005", + "0x532402500732401b32400532300532400502501b32400532300501b31a", + "0x1b02800532300500902d00702d01b02d00532300501b00901b009005323", + "0x504600503101b04700532300504700504601b031005323005028005028", + "0x50310053230050310050b001b00700532300500700531701b046005323", + "0x532101b01b32300501b02001b01b32300501b00701b031007046047047", + "0x1b3170053230053170051f501b31700532300501b07c01b01b32300531a", + "0x1b32300501b00701b1921f500742907c0b0007323007317046047024192", + "0x32300503900502501b03900532300501b42a01b03700532300501b31b01b", + "0x2501b03600532300501b2bf01b03800532300503903700732401b039005", + "0x520d00521501b20d00532300503603800732401b036005323005036005", + "0x1b21600532300521500521701b01b32300521300521601b215213007323", + "0x707c0472e501b0b00053230050b000504601b2160053230052160052c9", + "0x31b01b01b32300501b00701b22221f21e02442b21b21700732300721631f", + "0x32300522500521601b22922500732300522300521501b22300532300501b", + "0x521e01b22c00532300504b00521b01b04b00532300522900521701b01b", + "0x532300521700503101b0b00053230050b000504601b05300532300522c", + "0xb00470050530053230050530050b001b21b00532300521b00531701b217", + "0x5000702d01b05000532300501b00901b01b32300501b00701b05321b217", + "0x53230050b000504601b05400532300505100502801b051005323005222", + "0x50b001b21f00532300521f00531701b21e00532300521e00503101b0b0", + "0x531d01b01b32300501b00701b05421f21e0b0047005054005323005054", + "0x2501b24f00532300501b22301b24300532300501b31b01b01b32300531f", + "0x32300501b00901b25100532300524f24300732401b24f00532300524f005", + "0x1b05700532300505800502801b05800532300525105600702d01b056005", + "0x500700531701b19200532300519200503101b1f50053230051f5005046", + "0x1b00701b0570071921f50470050570053230050570050b001b007005323", + "0x2300532101b01b32300531e00522501b01b32300501b02001b01b323005", + "0x502501b2c600532300501b04b01b05500532300501b31b01b01b323005", + "0x532300501b00901b2c90053230052c605500732401b2c60053230052c6", + "0x4601b06000532300503300502801b0330053230052c92d300702d01b2d3", + "0x32300500700531701b04600532300504600503101b047005323005047005", + "0x501b00701b0600070460470470050600053230050600050b001b007005", + "0x501b22301b2ef00532300501b31b01b01b32300502400522c01b01b323", + "0x620053230050632ef00732401b06300532300506300502501b063005323", + "0x600502801b00600532300506230600702d01b30600532300501b00901b", + "0x4400532300504400503101b04500532300504500504601b06a005323005", + "0x4404504700506a00532300506a0050b001b00700532300500700531701b", + "0x742c04304400732300704701b00700501b01b32300501b01b01b06a007", + "0x4400504601b04000532300504500502401b01b32300501b00701b041042", + "0x501b00701b03e00542d03f19300732300704000504501b044005323005", + "0x501b31b01b01b32300503f00531f01b01b32300519300532101b01b323", + "0x32401b07d00532300507d00502501b07d00532300501b31a01b023005323", + "0x502032100702d01b32100532300501b00901b02000532300507d023007", + "0x1b04400532300504400504601b31e00532300531f00502801b31f005323", + "0x50240050c501b0070053230050070052be01b0050053230050050050c4", + "0x1b04600532300504600531701b04300532300504300503101b024005323", + "0x501b00701b31e04604302400700504404400531e00532300531e0050b0", + "0x31d0051f501b31d00532300501b07c01b01b32300503e00532101b01b323", + "0x1b32402500742e31a31b00732300731d04304402419201b31d005323005", + "0x31b00532300531b00504601b00900532300501b2f401b01b32300501b007", + "0x50050c401b0240053230050240050c501b0070053230050070052be01b", + "0x31a00502400731b04542f01b31a00532300531a00503101b005005323005", + "0x54301f500532300707c0052da01b07c0b031703102802d045323005009", + "0x532300501b31b01b01b3230051f500509801b01b32300501b00701b192", + "0x521701b01b32300503900521601b03803900732300503700521501b037", + "0x532300520d00521e01b20d00532300503600521b01b036005323005038", + "0x52be01b3170053230053170050c401b02d00532300502d00504601b213", + "0x53230050b000503101b0310053230050310050c501b028005323005028", + "0x2d0440052130053230052130050b001b04600532300504600531701b0b0", + "0x21500532300519200502801b01b32300501b00701b2130460b0031028317", + "0x280052be01b3170053230053170050c401b02d00532300502d00504601b", + "0xb00053230050b000503101b0310053230050310050c501b028005323005", + "0x31702d0440052150053230052150050b001b04600532300504600531701b", + "0x22301b21600532300501b31b01b01b32300501b00701b2150460b0031028", + "0x32300521721600732401b21700532300521700502501b21700532300501b", + "0x2801b21f00532300521b21e00702d01b21e00532300501b00901b21b005", + "0x3230050050050c401b02500532300502500504601b22200532300521f005", + "0x3101b0240053230050240050c501b0070053230050070052be01b005005", + "0x3230052220050b001b04600532300504600531701b324005323005324005", + "0x522c01b01b32300501b00701b222046324024007005025044005222005", + "0x2501b22500532300501b22301b22300532300501b31b01b01b323005045", + "0x32300501b00901b22900532300522522300732401b225005323005225005", + "0x1b05300532300522c00502801b22c00532300522904b00702d01b04b005", + "0x50070052be01b0050053230050050050c401b042005323005042005046", + "0x1b04100532300504100503101b0240053230050240050c501b007005323", + "0x70050420440050530053230050530050b001b046005323005046005317", + "0x4504600732300700701b00700501b01b32300501b01b01b053046041024", + "0x4601b04200532300504700502401b01b32300501b00701b043044007431", + "0x701b19300543204004100732300704200504501b046005323005046005", + "0x31b01b01b32300504000531f01b01b32300504100532101b01b32300501b", + "0x3e00532300503e00502501b03e00532300501b31a01b03f00532300501b", + "0x7d00702d01b07d00532300501b00901b02300532300503e03f00732401b", + "0x532300504600504601b32100532300502000502801b020005323005023", + "0x531701b04500532300504500503101b0050053230050050050c401b046", + "0x3210240450050460460053210053230053210050b001b024005323005024", + "0x31f00532300501b07c01b01b32300519300532101b01b32300501b00701b", + "0x43331d31e00732300731f04504602419201b31f00532300531f0051f501b", + "0x52bc01b0050053230050050050c401b01b32300501b00701b31a31b007", + "0x31e00532300531e00504601b01b32300501b04701b324025007323005005", + "0x507f01b01b32300501b00701b02d0054340090053230073240052f001b", + "0x280073230050250052bc01b0250053230050250050c401b01b323005009", + "0x2001b01b32300501b00701b0b00054353170053230070310052f001b031", + "0x21501b07c00532300501b31b01b01b32300531700507f01b01b32300501b", + "0x32300519200521701b01b3230051f500521601b1921f500732300507c005", + "0x4601b03800532300503900521e01b03900532300503700521b01b037005", + "0x32300531d00503101b0280053230050280050c401b31e00532300531e005", + "0x460050380053230050380050b001b02400532300502400531701b31d005", + "0x1b0360053230050280050c401b01b32300501b00701b03802431d02831e", + "0x1b01b32300501b00701b01b43600501b19301b20d0053230050b00052bb", + "0x32300501b02001b20d00532300502d0052bb01b0360053230050250050c4", + "0x50c401b31e00532300531e00504601b21300532300520d00502801b01b", + "0x532300502400531701b31d00532300531d00503101b036005323005036", + "0x501b00701b21302431d03631e0460052130053230052130050b001b024", + "0x21600502501b21600532300501b22301b21500532300501b31b01b01b323", + "0x21b00532300501b00901b21700532300521621500732401b216005323005", + "0x504601b21f00532300521e00502801b21e00532300521721b00702d01b", + "0x532300531a00503101b0050053230050050050c401b31b00532300531b", + "0x31b04600521f00532300521f0050b001b02400532300502400531701b31a", + "0x1b31b01b01b32300504700522c01b01b32300501b00701b21f02431a005", + "0x1b22300532300522300502501b22300532300501b22301b222005323005", + "0x22522900702d01b22900532300501b00901b225005323005223222007324", + "0x4400532300504400504601b22c00532300504b00502801b04b005323005", + "0x2400531701b04300532300504300503101b0050053230050050050c401b", + "0x1b22c02404300504404600522c00532300522c0050b001b024005323005", + "0x1b04404500743704604700732300700501b00700501b01b32300501b01b", + "0x1b01b32300501b04701b04300532300502400502401b01b32300501b007", + "0x1b04000543804104200732300704300504501b047005323005047005046", + "0x532300519300504301b19300532300504100504401b01b32300501b007", + "0x504001b02300532300504200504101b03e00532300503f00504201b03f", + "0x1b03f01b01b32300501b00701b01b43900501b19301b07d00532300503e", + "0x2300532300504000504101b32100532300502000503e01b020005323005", + "0x1b31e00543a31f00532300707d00502301b07d00532300532100504001b", + "0x31d00732300702300504501b01b32300531f00531d01b01b32300501b007", + "0x4301b02500532300531b00504401b01b32300501b00701b31a00543b31b", + "0x32300531d00504101b00900532300532400504201b324005323005025005", + "0x501b00701b01b43c00501b19301b02800532300500900504001b02d005", + "0x504101b31700532300503100503e01b03100532300501b03f01b01b323", + "0x532300702800502301b02800532300531700504001b02d00532300531a", + "0x43e1921f500732300702d00504501b01b32300501b00701b07c00543d0b0", + "0x3230051f500532101b01b32300501b02001b01b32300501b00701b037005", + "0x32300501b31b01b01b3230050b000531d01b01b32300519200531f01b01b", + "0x732401b03800532300503800502501b03800532300501b31a01b039005", + "0x32300503620d00702d01b20d00532300501b00901b036005323005038039", + "0x3101b04700532300504700504601b21500532300521300502801b213005", + "0x3230052150050b001b00700532300500700531701b046005323005046005", + "0x1b32300501b02001b01b32300501b00701b215007046047047005215005", + "0x3230052160051f501b21600532300501b07c01b01b32300503700532101b", + "0x1b00701b21f21e00743f21b21700732300721604604702419201b216005", + "0x1b2230053230050b022200732401b22200532300501b31b01b01b323005", + "0x522900521701b01b32300522500521601b229225007323005223005215", + "0x1b05300532300522c00521e01b22c00532300504b00521b01b04b005323", + "0x500700531701b21b00532300521b00503101b217005323005217005046", + "0x1b00701b05300721b2170470050530053230050530050b001b007005323", + "0x1b22301b05000532300501b31b01b01b3230050b000531d01b01b323005", + "0x532300505105000732401b05100532300505100502501b051005323005", + "0x502801b24f00532300505424300702d01b24300532300501b00901b054", + "0x532300521f00503101b21e00532300521e00504601b25100532300524f", + "0x21e0470052510053230052510050b001b00700532300500700531701b21f", + "0x507c00522501b01b32300501b02001b01b32300501b00701b25100721f", + "0x501b22901b05600532300501b31b01b01b32300502d00532101b01b323", + "0x5700532300505805600732401b05800532300505800502501b058005323", + "0x2c600502801b2c600532300505705500702d01b05500532300501b00901b", + "0x4600532300504600503101b04700532300504700504601b2c9005323005", + "0x460470470052c90053230052c90050b001b00700532300500700531701b", + "0x32300531e00522501b01b32300501b02001b01b32300501b00701b2c9007", + "0x32300501b04b01b2d300532300501b31b01b01b32300502300532101b01b", + "0x1b0600053230050332d300732401b03300532300503300502501b033005", + "0x506300502801b0630053230050602ef00702d01b2ef00532300501b009", + "0x1b04600532300504600503101b04700532300504700504601b062005323", + "0x70460470470050620053230050620050b001b007005323005007005317", + "0x532300501b31b01b01b32300502400522c01b01b32300501b00701b062", + "0x30600732401b00600532300500600502501b00600532300501b22301b306", + "0x532300506a06c00702d01b06c00532300501b00901b06a005323005006", + "0x503101b04500532300504500504601b06f00532300530700502801b307", + "0x532300506f0050b001b00700532300500700531701b044005323005044", + "0x32300700501b00700501b01b32300501b01b01b06f00704404504700506f", + "0x532300502400502401b01b32300501b00701b044045007440046047007", + "0x704300504501b04700532300504700504601b01b32300501b04701b043", + "0x532300504100504401b01b32300501b00701b040005441041042007323", + "0x504101b03e00532300503f00504201b03f00532300519300504301b193", + "0x1b01b44200501b19301b07d00532300503e00504001b023005323005042", + "0x32100532300502000503e01b02000532300501b03f01b01b32300501b007", + "0x7d00502301b07d00532300532100504001b02300532300504000504101b", + "0x1b32300531f00531d01b01b32300501b00701b31e00544331f005323007", + "0x4401b01b32300501b00701b31a00544431b31d00732300702300504501b", + "0x32300532400504201b32400532300502500504301b02500532300531b005", + "0x19301b02800532300500900504001b02d00532300531d00504101b009005", + "0x503e01b03100532300501b03f01b01b32300501b00701b01b44500501b", + "0x532300531700504001b02d00532300531a00504101b317005323005031", + "0x7d01b01b32300501b00701b07c0054460b000532300702800502301b028", + "0x504601b01b32300501b00701b0370054471921f50073230070b0047007", + "0x1b00701b03600544803803900732300702d00504501b1f50053230051f5", + "0x1b21300532300520d00504301b20d00532300503800504401b01b323005", + "0x521500504001b21600532300503900504101b215005323005213005042", + "0x32300501b03f01b01b32300501b00701b01b44900501b19301b217005323", + "0x4001b21600532300503600504101b21e00532300521b00503e01b21b005", + "0x1b00701b22200544a21f00532300721700502301b21700532300521e005", + "0x32300501b00701b22900544b22522300732300721600504501b01b323005", + "0x32300522500531f01b01b32300522300532101b01b32300501b02001b01b", + "0x32300501b31b01b01b32300519200531e01b01b32300521f00531d01b01b", + "0x732401b22c00532300522c00502501b22c00532300501b31a01b04b005", + "0x32300505305000702d01b05000532300501b00901b05300532300522c04b", + "0x3101b1f50053230051f500504601b05400532300505100502801b051005", + "0x3230050540050b001b00700532300500700531701b046005323005046005", + "0x32300522900532101b01b32300501b00701b0540070461f5047005054005", + "0x1f502419201b2430053230052430051f501b24300532300501b07c01b01b", + "0x1b02001b01b32300501b00701b05805600744c25124f007323007243046", + "0x1b05521f00732300521f0052cd01b05700532300501b03701b01b323005", + "0x725104620d01b24f00532300524f00504601b057005323005057005036", + "0x1b01b32300501b00701b0600332d302444d2c92c6007323007055192057", + "0x506300521501b06300532300521f2ef00732401b2ef00532300501b31b", + "0x1b00600532300530600521701b01b32300506200521601b306062007323", + "0x524f00504601b06c00532300506a00521e01b06a00532300500600521b", + "0x1b2c90053230052c900531701b2c60053230052c600503101b24f005323", + "0x1b01b32300501b00701b06c2c92c624f04700506c00532300506c0050b0", + "0x32300506030700702d01b30700532300501b00901b01b32300521f00531d", + "0x3101b24f00532300524f00504601b07000532300506f00502801b06f005", + "0x3230050700050b001b03300532300503300531701b2d30053230052d3005", + "0x1b32300501b02001b01b32300501b00701b0700332d324f047005070005", + "0x532300501b31b01b01b32300519200531e01b01b32300521f00531d01b", + "0x7200732401b30500532300530500502501b30500532300501b22301b072", + "0x532300503407700702d01b07700532300501b00901b034005323005305", + "0x503101b05600532300505600504601b07400532300530200502801b302", + "0x53230050740050b001b00700532300500700531701b058005323005058", + "0x1b01b32300501b02001b01b32300501b00701b074007058056047005074", + "0x1b32300519200531e01b01b32300521600532101b01b323005222005225", + "0x32300507b00502501b07b00532300501b06a01b07300532300501b31b01b", + "0x2d01b30000532300501b00901b07500532300507b07300732401b07b005", + "0x51f500504601b2fe0053230052ff00502801b2ff005323005075300007", + "0x1b00700532300500700531701b04600532300504600503101b1f5005323", + "0x1b01b32300501b00701b2fe0070461f50470052fe0053230052fe0050b0", + "0x1b44e00501b19301b2fd00532300503700504601b01b32300502d005321", + "0x1b32300502d00532101b01b32300507c00522501b01b32300501b00701b", + "0x532300501b31b01b01b32300501b02001b2fd00532300504700504601b", + "0x2fc00732401b2fb0053230052fb00502501b2fb00532300501b22901b2fc", + "0x53230052fa2f600702d01b2f600532300501b00901b2fa0053230052fb", + "0x503101b2fd0053230052fd00504601b2f500532300508800502801b088", + "0x53230052f50050b001b00700532300500700531701b046005323005046", + "0x1b01b32300501b02001b01b32300501b00701b2f50070462fd0470052f5", + "0x2f400532300501b31b01b01b32300502300532101b01b32300531e005225", + "0x862f400732401b08600532300508600502501b08600532300501b04b01b", + "0x840053230052f32f200702d01b2f200532300501b00901b2f3005323005", + "0x4600503101b04700532300504700504601b2f100532300508400502801b", + "0x2f10053230052f10050b001b00700532300500700531701b046005323005", + "0x1b01b32300502400522c01b01b32300501b00701b2f1007046047047005", + "0x532300507f00502501b07f00532300501b22301b2f000532300501b31b", + "0x702d01b32c00532300501b00901b08900532300507f2f000732401b07f", + "0x32300504500504601b2eb0053230052ec00502801b2ec00532300508932c", + "0xb001b00700532300500700531701b04400532300504400503101b045005", + "0x501b01b32300501b01b01b2eb0070440450470052eb0053230052eb005", + "0x2401b01b32300501b00701b04404500744f04604700732300700501b007", + "0x4700532300504700504601b01b32300501b04701b043005323005024005", + "0x4401b01b32300501b00701b04000545004104200732300704300504501b", + "0x32300503f00504201b03f00532300519300504301b193005323005041005", + "0x19301b07d00532300503e00504001b02300532300504200504101b03e005", + "0x503e01b02000532300501b03f01b01b32300501b00701b01b45100501b", + "0x532300532100504001b02300532300504000504101b321005323005020", + "0x4501b01b32300501b00701b31e00545231f00532300707d00502301b07d", + "0x31b00504401b01b32300501b00701b31a00545331b31d007323007023005", + "0x900532300532400504201b32400532300502500504301b025005323005", + "0x501b19301b02800532300500900504001b02d00532300531d00504101b", + "0x503100503e01b03100532300501b03f01b01b32300501b00701b01b454", + "0x1b02800532300531700504001b02d00532300531a00504101b317005323", + "0x2d00504501b01b32300501b00701b07c0054550b0005323007028005023", + "0x1b32300501b02001b01b32300501b00701b0370054561921f5007323007", + "0x3230050b000531d01b01b32300519200531f01b01b3230051f500532101b", + "0x32300501b31a01b03900532300501b31b01b01b32300531f00531d01b01b", + "0x1b03600532300503803900732401b03800532300503800502501b038005", + "0x521300502801b21300532300503620d00702d01b20d00532300501b009", + "0x1b04600532300504600503101b04700532300504700504601b215005323", + "0x70460470470052150053230052150050b001b007005323005007005317", + "0x532300501b07c01b01b32300503700532101b01b32300501b00701b215", + "0x21b21700732300721604604702419201b2160053230052160051f501b216", + "0x52b901b22200532300501b2ba01b01b32300501b00701b21f21e007457", + "0x50b02250072b301b22531f00732300531f0052cd01b223005323005222", + "0xcb01b04b00532300504b00503601b04b00532300501b03701b229005323", + "0x32300521700504601b22900532300522900502501b223005323005223005", + "0x5405105002445805322c00732300722922304b00721b04620d01b217005", + "0x1b24300532300501b31b01b01b32300501b02001b01b32300501b00701b", + "0x521601b05625100732300524f00521501b24f00532300531f243007324", + "0x5700532300505800521b01b05800532300505600521701b01b323005251", + "0x22c00503101b21700532300521700504601b05500532300505700521e01b", + "0x550053230050550050b001b05300532300505300531701b22c005323005", + "0x31d01b01b32300501b02001b01b32300501b00701b05505322c217047005", + "0x53230050542c600702d01b2c600532300501b00901b01b32300531f005", + "0x503101b21700532300521700504601b2d30053230052c900502801b2c9", + "0x53230052d30050b001b05100532300505100531701b050005323005050", + "0x1b01b32300501b02001b01b32300501b00701b2d30510502170470052d3", + "0x3300532300501b31b01b01b32300531f00531d01b01b3230050b000531d", + "0x6003300732401b06000532300506000502501b06000532300501b22301b", + "0x620053230052ef06300702d01b06300532300501b00901b2ef005323005", + "0x21f00503101b21e00532300521e00504601b30600532300506200502801b", + "0x3060053230053060050b001b00700532300500700531701b21f005323005", + "0x22501b01b32300501b02001b01b32300501b00701b30600721f21e047005", + "0x1b01b32300531f00531d01b01b32300502d00532101b01b32300507c005", + "0x532300506a00502501b06a00532300501b22901b00600532300501b31b", + "0x702d01b30700532300501b00901b06c00532300506a00600732401b06a", + "0x32300504700504601b07000532300506f00502801b06f00532300506c307", + "0xb001b00700532300500700531701b04600532300504600503101b047005", + "0x2001b01b32300501b00701b070007046047047005070005323005070005", + "0x31b01b01b32300502300532101b01b32300531e00522501b01b32300501b", + "0x30500532300530500502501b30500532300501b04b01b07200532300501b", + "0x7700702d01b07700532300501b00901b03400532300530507200732401b", + "0x532300504700504601b07400532300530200502801b302005323005034", + "0x50b001b00700532300500700531701b04600532300504600503101b047", + "0x522c01b01b32300501b00701b074007046047047005074005323005074", + "0x2501b07b00532300501b22301b07300532300501b31b01b01b323005024", + "0x32300501b00901b07500532300507b07300732401b07b00532300507b005", + "0x1b2fe0053230052ff00502801b2ff00532300507530000702d01b300005", + "0x500700531701b04400532300504400503101b045005323005045005046", + "0x1b02001b2fe0070440450470052fe0053230052fe0050b001b007005323", + "0x1b00701b04304400745904504600732300700501b00700501b01b323005", + "0x4600532300504600504601b0420470073230050470052cd01b01b323005", + "0x4700531d01b01b32300501b00701b04100545a01b32300704200507e01b", + "0x1930053230050400070072ae01b0400053230050240052b001b01b323005", + "0x4500503101b04600532300504600504601b03f0053230051930050c201b", + "0x1b00701b03f04504602400503f00532300503f0052b101b045005323005", + "0x4701b03e00532300500700502401b01b3230050410052de01b01b323005", + "0x501b00701b02000545b07d02300732300703e00504501b01b32300501b", + "0x4201b31f00532300532100504301b32100532300507d00504401b01b323", + "0x32300531e00504001b31d00532300502300504101b31e00532300531f005", + "0x532300501b03f01b01b32300501b00701b01b45c00501b19301b31b005", + "0x504001b31d00532300502000504101b02500532300531a00503e01b31a", + "0x532300731b00502301b32400532300531d00521701b31b005323005025", + "0x2400732401b01b32300501b02001b01b32300501b00701b02d00545d009", + "0x53230050310470072d601b03100532300501b05101b028005323005009", + "0x52c901b04500532300504500503101b04600532300504600504601b317", + "0x532300531700502501b02800532300502800521f01b324005323005324", + "0x1f507c0b00240051f507c0b00243230053170283240450460462d301b317", + "0x1b01b32300504700531d01b01b32300501b02001b01b32300501b00701b", + "0x51923240072ae01b19200532300502d00506201b01b323005024005216", + "0x1b04600532300504600504601b0390053230050370050c201b037005323", + "0x390450460240050390053230050390052b101b045005323005045005031", + "0x1b32300502400521601b01b32300504700531d01b01b32300501b00701b", + "0x532300501b22301b03800532300501b31b01b01b32300500700522c01b", + "0x901b20d00532300503603800732401b03600532300503600502501b036", + "0x3230052150050cc01b21500532300520d21300702d01b21300532300501b", + "0x2b101b04300532300504300503101b04400532300504400504601b216005", + "0x700501b01b32300501b02001b216043044024005216005323005216005", + "0x52b801b01b32300501b00701b04104200745e04304400732300700501b", + "0x3230050240052b801b1930053230050400052ab01b040046007323005046", + "0x45f01b32300719303f0072aa01b04400532300504400504601b03f024007", + "0x3e00521701b03e0450073230050450052a901b01b32300501b00701b01b", + "0x532300507d00521701b07d0470073230050470052a901b023005323005", + "0x701b31b31d31e02446031f3210073230070200230070430470d001b020", + "0x1b31a00532300531a00530201b31a00532300501b2b701b01b32300501b", + "0x240440240d201b31f00532300531f00531701b321005323005321005031", + "0x2500504601b01b32300501b00701b02d00900746132402500732300731a", + "0x31f00532300531f00531701b32100532300532100503101b025005323005", + "0x4600530201b04700532300504700504101b32400532300532400530201b", + "0x4732431f32102504407401b04500532300504500504101b046005323005", + "0x32300501b00701b0b03170310280470050b0317031028047323005045046", + "0x504600507001b01b32300504500532101b01b32300502d00507001b01b", + "0x501b2b401b07c00532300501b31b01b01b32300504700532101b01b323", + "0x1920053230051f507c00732401b1f50053230051f500502501b1f5005323", + "0x390052b501b03900532300519203700702d01b03700532300501b00901b", + "0x32100532300532100503101b00900532300500900504601b038005323005", + "0x3210090470050380053230050380050d401b31f00532300531f00531701b", + "0x504600507001b01b32300504500532101b01b32300501b00701b03831f", + "0x501b00901b01b32300502400507001b01b32300504700532101b01b323", + "0x21300532300520d0052b501b20d00532300531b03600702d01b036005323", + "0x31d00531701b31e00532300531e00503101b04400532300504400504601b", + "0x701b21331d31e0440470052130053230052130050d401b31d005323005", + "0x32101b01b32300504600507001b01b32300504500532101b01b32300501b", + "0x53230052150240072b601b21500532300501b03f01b01b323005047005", + "0x503101b04400532300504400504601b2170053230052160052a801b216", + "0x53230052170050d401b00700532300500700531701b043005323005043", + "0x1b32300504500532101b01b32300501b00701b217007043044047005217", + "0x32300502400507001b01b32300504700532101b01b32300504600507001b", + "0x521e00502501b21e00532300501b22301b21b00532300501b31b01b01b", + "0x1b22200532300501b00901b21f00532300521e21b00732401b21e005323", + "0x4200504601b2250053230052230052b501b22300532300521f22200702d", + "0x700532300500700531701b04100532300504100503101b042005323005", + "0x32300500500502401b2250070410420470052250053230052250050d401b", + "0x1b32300501b00701b04600546204702400732300700700504501b007005", + "0x4500505701b04400532300502400504101b04500532300504700505801b", + "0x501b03f01b01b32300501b00701b01b46300501b19301b043005323005", + "0x1b04400532300504600504101b04100532300504200505501b042005323", + "0x4000521701b0400440073230050440052a901b043005323005041005057", + "0x32300501b00701b03e00546403f0053230070430052c601b193005323005", + "0x502501b07d00532300502300504301b02300532300503f00504401b01b", + "0x701b31f00546532102000732300707d01b00706f01b07d00532300507d", + "0x1b02000532300502000504601b01b32300519300522c01b01b32300501b", + "0x505801b01b32300501b00701b31b00546631d31e007323007044005045", + "0x532300531a00505701b02500532300531e00504101b31a00532300531d", + "0x900532300501b03f01b01b32300501b00701b01b46700501b19301b324", + "0x2d00505701b02500532300531b00504101b02d00532300500900505501b", + "0x532300502800521701b0280250073230050250052a901b324005323005", + "0x4401b01b32300501b00701b0b00054683170053230073240052c601b031", + "0x3230051f500502501b1f500532300507c00504301b07c005323005317005", + "0x32300501b00701b0390054690371920073230071f502000706f01b1f5005", + "0x2500504501b19200532300519200504601b01b32300503100522c01b01b", + "0x32300503600504401b01b32300501b00701b20d00546a036038007323007", + "0x4101b21600532300521500504201b21500532300521300504301b213005", + "0x1b46b00501b19301b21b00532300521600504001b217005323005038005", + "0x532300521e00503e01b21e00532300501b03f01b01b32300501b00701b", + "0x521701b21b00532300521f00504001b21700532300520d00504101b21f", + "0x501b00701b22500546c22300532300721b00502301b222005323005217", + "0x32300501b00701b22c00546d04b22900732300722319200705601b01b323", + "0x1b0500053230050530052a201b05300532300504b0373210242a001b01b", + "0x505000529d01b2220053230052220052c901b229005323005229005046", + "0x32300532100507001b01b32300501b00701b050222229024005050005323", + "0x501b19301b05100532300522c00504601b01b32300503700507001b01b", + "0x532100507001b01b32300522500522501b01b32300501b00701b01b46e", + "0x1b03f01b05100532300519200504601b01b32300503700507001b01b323", + "0x2220053230052220052c901b24300532300505400529c01b054005323005", + "0x1b01b32300501b00701b24322205102400524300532300524300529d01b", + "0x532300503900504601b01b32300502500532101b01b323005321005070", + "0x1b3230050b000522501b01b32300501b00701b01b46f00501b19301b24f", + "0x32300502000504601b01b32300502500532101b01b32300532100507001b", + "0x52c901b05600532300525100529c01b25100532300501b03f01b24f005", + "0x701b05603124f02400505600532300505600529d01b031005323005031", + "0x1b05800532300531f00504601b01b32300504400532101b01b32300501b", + "0x32101b01b32300503e00522501b01b32300501b00701b01b47000501b193", + "0x5700532300501b03f01b05800532300501b00504601b01b323005044005", + "0x5500529d01b1930053230051930052c901b05500532300505700529c01b", + "0x501b24301b04700532300501b24301b055193058024005055005323005", + "0x1b24301b04100532300501b24301b04300532300501b24301b045005323", + "0x24f01b07d00532300501b24301b03e00532300501b0da01b193005323005", + "0x4501b02000532300500700502401b01b32300501b02001b01b32300501b", + "0x31f00504401b01b32300501b00701b31e00547131f321007323007020005", + "0x31a00532300531b00504201b31b00532300531d00504301b31d005323005", + "0x501b19301b32400532300531a00504001b02500532300532100504101b", + "0x500900503e01b00900532300501b03f01b01b32300501b00701b01b472", + "0x1b32400532300502d00504001b02500532300531e00504101b02d005323", + "0x4100725101b01b32300501b00701b028005473042005323007324005023", + "0x1b00701b0b000547431703100732300702500504501b042005323005042", + "0x1b1f500532300507c00504301b07c00532300531700504401b01b323005", + "0x519200504001b03700532300503100504101b1920053230051f5005042", + "0x32300501b03f01b01b32300501b00701b01b47500501b19301b039005323", + "0x4001b0370053230050b000504101b03600532300503800503e01b038005", + "0x520d00521701b20d0370073230050370052a901b039005323005036005", + "0x21500547604400532300703900502301b01b32300501b04701b213005323", + "0x4401b00705601b04400532300504404300725101b01b32300501b00701b", + "0x32300521300522c01b01b32300501b00701b21b005477217216007323007", + "0x547821f21e00732300703700504501b21600532300521600504601b01b", + "0x521e00504101b22300532300521f00505801b01b32300501b00701b222", + "0x1b00701b01b47900501b19301b22900532300522300505701b225005323", + "0x4101b22c00532300504b00505501b04b00532300501b03f01b01b323005", + "0x32300522500521701b22900532300522c00505701b225005323005222005", + "0x1b01b32300501b00701b05100547a0500053230072290052c601b053005", + "0x2400504301b02400532300502404700725101b024005323005050005044", + "0x1b05805625102447b24f24300732300705421600729a01b054005323005", + "0x53230050530052c901b24300532300524300504601b01b32300501b007", + "0x47c2c600532300705500529701b05505700732300505324300729801b053", + "0x529501b0332d30073230052c60050de01b01b32300501b00701b2c9005", + "0x3230052d300502401b01b32300501b00701b06000547d03f005323007033", + "0x620630073230072ef00504501b03f00532300503f03e00729301b2ef005", + "0x504301b00600532300506200504401b01b32300501b00701b30600547e", + "0x532300506300504101b06c00532300506a00504201b06a005323005006", + "0x32300501b00701b01b47f00501b19301b06f00532300506c00504001b307", + "0x30600504101b07200532300507000503e01b07000532300501b03f01b01b", + "0x2300532300706f00502301b06f00532300507200504001b307005323005", + "0x4501b02300532300502307d00725101b01b32300501b00701b305005480", + "0x7700504401b01b32300501b00701b302005481077034007323007307005", + "0x7b00532300507300504201b07300532300507400504301b074005323005", + "0x501b19301b30000532300507b00504001b07500532300503400504101b", + "0x52ff00503e01b2ff00532300501b03f01b01b32300501b00701b01b482", + "0x1b3000053230052fe00504001b07500532300530200504101b2fe005323", + "0x19300725101b01b32300501b00701b2fd005483040005323007300005023", + "0x1b00701b2fa0054842fb2fc00732300707500504501b040005323005040", + "0x1b0880053230052f600504301b2f60053230052fb00504401b01b323005", + "0x52f500504001b2f40053230052fc00504101b2f5005323005088005042", + "0x32300501b03f01b01b32300501b00701b01b48500501b19301b086005323", + "0x4001b2f40053230052fa00504101b2f20053230052f300503e01b2f3005", + "0x1b00701b08400548604600532300708600502301b0860053230052f2005", + "0x2f10073230072f400504501b04600532300504604500725101b01b323005", + "0x4101b0890053230052f000505801b01b32300501b00701b07f0054872f0", + "0x1b48800501b19301b2ec00532300508900505701b32c0053230052f1005", + "0x53230052eb00505501b2eb00532300501b03f01b01b32300501b00701b", + "0x52c601b2ec0053230052ea00505701b32c00532300507f00504101b2ea", + "0x1b32300501b02001b01b32300501b00701b2e80054892e90053230072ec", + "0x532c00521701b2e600532300501b0df01b2e70053230052e900504401b", + "0x1b05700532300505700504601b2e40053230052e700504301b2e5005323", + "0x52e60050e301b2e50053230052e50052c901b005005323005005005031", + "0x52e42e62e500505704629201b2e40053230052e400502501b2e6005323", + "0x501b00701b07e00548a2df0053230072e100528f01b2e12e22e3024323", + "0x48b2de00532300708f00528d01b08f08d0073230052df00528e01b01b323", + "0x528b01b0902dd0073230052de00528c01b01b32300501b00701b092005", + "0x2dc00532300508700528701b08700532300509000528a01b01b3230052dd", + "0x2e200503101b0980053230052e300504601b2da00532300508d00502401b", + "0x9b0053230052dc0050eb01b09f0053230052da00504101b2d9005323005", + "0x2d80053230050920050ed01b01b32300501b00701b01b48c00501b19301b", + "0x2e200503101b0980053230052e300504601b2d600532300508d00502401b", + "0x9b0053230052d80050eb01b09f0053230052d600504101b2d9005323005", + "0x1b01b32300524f00528601b01b32300501b00701b01b48c00501b19301b", + "0x1b32300504000531d01b01b32300504200531d01b01b323005217005063", + "0x32300504600531d01b01b32300502300531d01b01b32300503f00522c01b", + "0x503101b2e30053230052e300504601b0a300532300507e00528501b01b", + "0x701b0a32e22e30240050a30053230050a300528401b2e20053230052e2", + "0x1b03f01b01b3230052e800522501b01b32300501b02001b01b32300501b", + "0x9800532300505700504601b0a50053230052d40050ed01b2d4005323005", + "0xa50050eb01b09f00532300532c00504101b2d900532300500500503101b", + "0x32300501b00701b2d200548d0a700532300709b0050ef01b09b005323005", + "0x1b2ce00548e2cf0aa00732300709f00504501b01b32300501b04701b01b", + "0x53230050aa00504101b2cd0053230052cf00505801b01b32300501b007", + "0x32300501b00701b01b48f00501b19301b2cb0053230052cd00505701b2cc", + "0x2ce00504101b2ca0053230050af00505501b0af00532300501b03f01b01b", + "0x2c80053230052cc00521701b2cb0053230052ca00505701b2cc005323005", + "0x504401b01b32300501b00701b0490054902c70053230072cb0052c601b", + "0x53230053b300502501b3b30053230053b200504301b3b20053230052c7", + "0x501b00701b0b60b73b50244910cd3b40073230073b309800729a01b3b3", + "0x29801b2c80053230052c80052c901b3b40053230053b400504601b01b323", + "0x1b2c50054920bf0053230070bb00529701b0bb0b90073230052c83b4007", + "0x3230072d500529501b2d541b0073230050bf0050de01b01b32300501b007", + "0x1b0c400532300541b00502401b01b32300501b00701b2bf00549342a005", + "0x505801b01b32300501b00701b42f0054940c52be0073230070c4005045", + "0x53230052bc00505701b2bb0053230052be00504101b2bc0053230050c5", + "0x2b900532300501b03f01b01b32300501b00701b01b49500501b19301b2ba", + "0x2b300505701b2bb00532300542f00504101b2b30053230052b900505501b", + "0x53230050cb00521701b0cb2bb0073230052bb0052a901b2ba005323005", + "0x4401b01b32300501b00701b0c20054962ae0053230072ba0052c601b2b0", + "0x3230050cc00502501b0cc0053230052b100504301b2b10053230052ae005", + "0x32300501b00701b2aa0054972ab2b80073230070cc0b90070f101b0cc005", + "0x2bb00504501b2b80053230052b800504601b01b3230052b000522c01b01b", + "0x3230050d000505801b01b32300501b00701b2b70054980d02a9007323007", + "0x19301b2b50053230050d200505701b2b40053230052a900504101b0d2005", + "0x505501b0d400532300501b03f01b01b32300501b00701b01b49900501b", + "0x53230052b600505701b2b40053230052b700504101b2b60053230050d4", + "0x2a200549a2a00053230072b50052c601b2a80053230052b400521701b2b5", + "0x32300529d00504301b29d0053230052a000504401b01b32300501b00701b", + "0x29a0da00732300729c2b80070f101b29c00532300529c00502501b29c005", + "0x52c901b0da0053230050da00504601b01b32300501b00701b29800549b", + "0x70de00529701b0de2970073230052a80da00729801b2a80053230052a8", + "0xdf0073230052950050de01b01b32300501b00701b29300549c295005323", + "0x2001b01b32300501b00701b28f00549d2920053230070e300529501b0e3", + "0x29229a2ab42a0cd0a704604002303f24f21704203f0f001b01b32300501b", + "0x532300528d0df00728301b28d00532300528e0050ee01b28e005323005", + "0x503101b29700532300529700504601b28b00532300528c00528201b28c", + "0x701b28b2d929702400528b00532300528b00528401b2d90053230052d9", + "0x522201b01b32300504200531d01b01b32300501b02001b01b32300501b", + "0x28601b01b32300542a00522c01b01b3230052ab00522201b01b32300529a", + "0x1b01b32300504600531d01b01b3230050a70050f701b01b3230050cd005", + "0x1b32300503f00522c01b01b32300502300531d01b01b32300504000531d", + "0x32300528f0050f901b01b32300521700506301b01b32300524f00528601b", + "0x1b0eb00532300528700528201b28700532300528a0df00728301b28a005", + "0x50eb00528401b2d90053230052d900503101b297005323005297005046", + "0x1b32300501b02001b01b32300501b00701b0eb2d92970240050eb005323", + "0x32300529a00522201b01b32300504200531d01b01b32300521700506301b", + "0x50cd00528601b01b32300542a00522c01b01b3230052ab00522201b01b", + "0x4000531d01b01b32300504600531d01b01b3230050a70050f701b01b323", + "0x528601b01b32300503f00522c01b01b32300502300531d01b01b323005", + "0x29700532300529700504601b0ed00532300529300528501b01b32300524f", + "0x2d92970240050ed0053230050ed00528401b2d90053230052d900503101b", + "0x32300521700506301b01b32300524f00528601b01b32300501b00701b0ed", + "0x542a00522c01b01b3230052ab00522201b01b32300504200531d01b01b", + "0x4600531d01b01b3230050a70050f701b01b3230050cd00528601b01b323", + "0x522c01b01b32300502300531d01b01b32300504000531d01b01b323005", + "0x701b01b49e00501b19301b28600532300529800504601b01b32300503f", + "0x6301b01b32300524f00528601b01b3230052a200522501b01b32300501b", + "0x1b01b3230052ab00522201b01b32300504200531d01b01b323005217005", + "0x1b3230050a70050f701b01b3230050cd00528601b01b32300542a00522c", + "0x32300502300531d01b01b32300504000531d01b01b32300504600531d01b", + "0x501b02001b2860053230052b800504601b01b32300503f00522c01b01b", + "0x728301b2840053230052850050f901b28500532300501b03f01b01b323", + "0x3230052d900503101b0f10053230050ef00528201b0ef0053230052842a8", + "0x32300501b00701b0f12d92860240050f10053230050f100528401b2d9005", + "0x504200531d01b01b32300521700506301b01b32300524f00528601b01b", + "0x42a00522c01b01b32300503f00522c01b01b3230052bb00532101b01b323", + "0x531d01b01b3230050a70050f701b01b3230050cd00528601b01b323005", + "0x4601b01b32300502300531d01b01b32300504000531d01b01b323005046", + "0x22501b01b32300501b00701b01b49f00501b19301b0f00053230052aa005", + "0x1b01b32300521700506301b01b32300524f00528601b01b3230050c2005", + "0x1b32300503f00522c01b01b3230052bb00532101b01b32300504200531d", + "0x3230050a70050f701b01b3230050cd00528601b01b32300542a00522c01b", + "0x502300531d01b01b32300504000531d01b01b32300504600531d01b01b", + "0x501b03f01b01b32300501b02001b0f00053230050b900504601b01b323", + "0x2820053230052832b000728301b2830053230050ee0050f901b0ee005323", + "0xf700528401b2d90053230052d900503101b0f700532300528200528201b", + "0x32300501b02001b01b32300501b00701b0f72d90f00240050f7005323005", + "0x504200531d01b01b32300521700506301b01b32300524f00528601b01b", + "0xa70050f701b01b3230050cd00528601b01b32300503f00522c01b01b323", + "0x531d01b01b32300504000531d01b01b32300504600531d01b01b323005", + "0x53230050f941b00728301b0f90053230052bf0050f901b01b323005023", + "0x503101b0b90053230050b900504601b0f60053230050f800528201b0f8", + "0x701b0f62d90b90240050f60053230050f600528401b2d90053230052d9", + "0x506301b01b32300524f00528601b01b32300501b02001b01b32300501b", + "0x31d01b01b32300503f00522c01b01b32300504200531d01b01b323005217", + "0x1b01b3230050a70050f701b01b3230050cd00528601b01b323005023005", + "0x53230052c500528501b01b32300504000531d01b01b32300504600531d", + "0x528401b2d90053230052d900503101b0b90053230050b900504601b281", + "0xb700528601b01b32300501b00701b2812d90b9024005281005323005281", + "0x506301b01b32300524f00528601b01b3230050b600528601b01b323005", + "0x22c01b01b32300504000531d01b01b32300504200531d01b01b323005217", + "0x1b01b3230050a70050f701b01b32300502300531d01b01b32300503f005", + "0x1b4a000501b19301b2800053230053b500504601b01b32300504600531d", + "0x1b32300524f00528601b01b32300504900522501b01b32300501b00701b", + "0x32300504000531d01b01b32300504200531d01b01b32300521700506301b", + "0x50a70050f701b01b32300502300531d01b01b32300503f00522c01b01b", + "0x1b02001b28000532300509800504601b01b32300504600531d01b01b323", + "0x28301b1010053230050ff0050f901b0ff00532300501b03f01b01b323005", + "0x52d900503101b0fe00532300510000528201b1000053230051012c8007", + "0x501b00701b0fe2d92800240050fe0053230050fe00528401b2d9005323", + "0x4200531d01b01b32300521700506301b01b32300524f00528601b01b323", + "0x531d01b01b32300503f00522c01b01b32300504000531d01b01b323005", + "0x1b27e00532300509f00521701b01b32300504600531d01b01b323005023", + "0x10700528201b10700532300527d27e00728301b27d0053230052d20050f9", + "0x2d90053230052d900503101b09800532300509800504601b109005323005", + "0x1b01b32300501b00701b1092d909802400510900532300510900528401b", + "0x1b01b32300521700506301b01b32300524f00528601b01b32300501b020", + "0x1b32300503f00522c01b01b32300504000531d01b01b32300504200531d", + "0x3230052f400521701b01b32300504500506c01b01b32300502300531d01b", + "0x1b27c00532300510610800728301b1060053230050840050f901b108005", + "0x500500503101b05700532300505700504601b11300532300527c005282", + "0x501b00701b11300505702400511300532300511300528401b005005323", + "0x504500506c01b01b32300524f00528601b01b32300501b02001b01b323", + "0x3f00522c01b01b32300504200531d01b01b32300521700506301b01b323", + "0x521701b01b32300519300506c01b01b32300502300531d01b01b323005", + "0x32300510e10f00728301b10e0053230052fd0050f901b10f005323005075", + "0x3101b05700532300505700504601b11500532300527b00528201b27b005", + "0x1b11500505702400511500532300511500528401b005005323005005005", + "0x6c01b01b32300524f00528601b01b32300501b02001b01b32300501b007", + "0x1b01b32300504200531d01b01b32300521700506301b01b323005045005", + "0x1b32300507d00506c01b01b32300503f00522c01b01b32300519300506c", + "0x11700728301b2790053230053050050f901b11700532300530700521701b", + "0x532300505700504601b27700532300527800528201b278005323005279", + "0x5702400527700532300527700528401b00500532300500500503101b057", + "0x32300524f00528601b01b32300501b02001b01b32300501b00701b277005", + "0x504200531d01b01b32300521700506301b01b32300504500506c01b01b", + "0x3e0050f801b01b32300507d00506c01b01b32300519300506c01b01b323", + "0x11a0053230052762d300728301b2760053230050600050f901b01b323005", + "0x500503101b05700532300505700504601b11b00532300511a00528201b", + "0x1b00701b11b00505702400511b00532300511b00528401b005005323005", + "0x4500506c01b01b32300524f00528601b01b32300501b02001b01b323005", + "0x506c01b01b32300504200531d01b01b32300521700506301b01b323005", + "0x28501b01b32300507d00506c01b01b32300503e0050f801b01b323005193", + "0x32300500500503101b05700532300505700504601b0180053230052c9005", + "0x32300501b00701b01800505702400501800532300501800528401b005005", + "0x504500506c01b01b32300505800528601b01b32300505600528601b01b", + "0x19300506c01b01b32300504200531d01b01b32300521700506301b01b323", + "0x504601b01b32300507d00506c01b01b32300503e0050f801b01b323005", + "0x522501b01b32300501b00701b01b4a100501b19301b119005323005251", + "0x31d01b01b32300521700506301b01b32300504500506c01b01b323005051", + "0x1b01b32300503e0050f801b01b32300519300506c01b01b323005042005", + "0x532300521600504601b01b32300504700506c01b01b32300507d00506c", + "0x3230052750050f901b27500532300501b03f01b01b32300501b02001b119", + "0x1b12000532300512100528201b12100532300527305300728301b273005", + "0x12000511902400512000532300512000528401b005005323005005005031", + "0x1b32300504500506c01b01b32300504700506c01b01b32300501b00701b", + "0x32300519300506c01b01b32300504200531d01b01b32300503700532101b", + "0x521b00504601b01b32300507d00506c01b01b32300503e0050f801b01b", + "0x521500522501b01b32300501b00701b01b4a200501b19301b271005323", + "0x3700532101b01b32300504500506c01b01b32300504700506c01b01b323", + "0x50f801b01b32300519300506c01b01b32300504200531d01b01b323005", + "0x4601b01b32300504300506c01b01b32300507d00506c01b01b32300503e", + "0x1b04800532300501b03f01b01b32300501b02001b27100532300501b005", + "0x26f00528201b26f00532300527021300728301b2700053230050480050f9", + "0x12600532300512600528401b00500532300500500503101b126005323005", + "0x6c01b01b32300504700506c01b01b32300501b00701b126005271024005", + "0x1b01b32300503e0050f801b01b32300519300506c01b01b323005045005", + "0x1b32300504100506c01b01b32300504300506c01b01b32300507d00506c", + "0x12500728301b26d0053230050280050f901b12500532300502500521701b", + "0x532300501b00504601b12b00532300526c00528201b26c00532300526d", + "0x1b02400512b00532300512b00528401b00500532300500500503101b01b", + "0x501b24301b19300532300501b28101b04100532300501b0f601b12b005", + "0x1b24f01b32100532300501b28001b07d00532300501b0f601b03e005323", + "0x50070ff01b01b3230050240052f301b01b32300501b02001b01b323005", + "0x10101b01b32300501b00701b31a31b31d0244a331e04031f024323007007", + "0x3230050250050fe01b02500532300531e00510001b31e00532300531e005", + "0x32300532400527d01b32400532300532400527e01b03f023042009324046", + "0x10701b01b3230050280052f501b03102800732300502d00510701b02d005", + "0x3230050310052f201b01b3230053170052f501b0b0317007323005047005", + "0x1921f502432300507c00510801b07c03100732300503100510901b031005", + "0x51f50052ab01b01b32300503700506301b01b32300519200507001b037", + "0x3602432300503800510801b0380b00073230050b000510901b039005323", + "0x360052ab01b01b32300521300506301b01b32300520d00507001b21320d", + "0x10601b31f00532300531f00503101b01b32300501b04701b215005323005", + "0x4204100711301b00900532300500900527c01b040005323005040193007", + "0x32300503f03e00725101b02300532300502307d00711301b042005323005", + "0x31d01b01b32300501b00701b01b4a401b3230072150390072aa01b03f005", + "0x1b01b32300502300506301b01b32300504300531d01b01b32300503f005", + "0x1b32300504500531d01b01b32300504600508801b01b32300504400531d", + "0x32300500900510e01b01b32300532100510f01b01b32300504200506301b", + "0x4a500501b19301b01b3230050310052f501b01b3230050b00052f501b01b", + "0x21600510801b21603100732300503100510901b01b32300501b00701b01b", + "0x1b32300521e00506301b01b32300521700507001b21e21b217024323005", + "0x510801b2220b00073230050b000510901b21f00532300521b0052ab01b", + "0x32300522900506301b01b32300522300507001b229225223024323005222", + "0x1b01b4a601b32300704b21f0072aa01b04b0053230052250052ab01b01b", + "0x1b01b32300504300531d01b01b32300503f00531d01b01b32300501b007", + "0x1b32300504600508801b01b32300504400531d01b01b323005023005063", + "0x32300532100510f01b01b32300504200506301b01b32300504500531d01b", + "0x50310052f501b01b3230050b00052f501b01b32300500900510e01b01b", + "0x32300503100510801b01b32300501b00701b01b4a700501b19301b01b323", + "0x27b01b01b32300505300507001b01b32300522c00507001b05005322c024", + "0x3230050b000510801b0540053230050510052cb01b051005323005050005", + "0x27b01b01b32300524f00507001b01b32300524300507001b25124f243024", + "0x50580540072d601b0580053230050560052cb01b056005323005251005", + "0x54a801b32300705700507e01b05700532300505700502501b057005323", + "0x2032100711701b02000532300500900511501b01b32300501b00701b055", + "0x1b3230052c600508801b2c92c600732300502000527901b020005323005", + "0x2c900527801b01b3230052d300508801b0332d300732300504600527901b", + "0x30706c06a0063060620632ef03f32300506000527701b0602c9007323005", + "0x1b01b32300506200528601b01b32300506300506301b03430507207006f", + "0x1b32300506a00531d01b01b32300500600531d01b01b32300530600522c", + "0x32300506f00528601b01b3230053070050f701b01b32300506c00531d01b", + "0x530500522201b01b32300507200522201b01b32300507000522c01b01b", + "0x527801b0770053230052ef00504301b01b32300503400522c01b01b323", + "0x2fe2ff30007507b07307403f32300530200527701b302033007323005033", + "0x1b32300507b00528601b01b32300507300506301b0882f62fa2fb2fc2fd", + "0x3230052ff00531d01b01b32300530000531d01b01b32300507500522c01b", + "0x52fc00528601b01b3230052fd0050f701b01b3230052fe00531d01b01b", + "0x2f600522201b01b3230052fa00522201b01b3230052fb00522c01b01b323", + "0x2d601b2f500532300507400504301b01b32300508800522c01b01b323005", + "0x72f400507e01b2f40053230052f400502501b2f40053230052f5077007", + "0x2f32c90073230052c900527801b01b32300501b00701b0860054a901b323", + "0x2e72e82e92ea2eb2ec32c08907f2f02f10842f203f3230052f300527701b", + "0x3230052f000522c01b01b3230052f100528601b01b3230052f200531d01b", + "0x532c00531d01b01b32300508900531d01b01b32300507f00531d01b01b", + "0x2ea00522c01b01b3230052eb00528601b01b3230052ec0050f701b01b323", + "0x522c01b01b3230052e800522201b01b3230052e900522201b01b323005", + "0x2e50053230052e60052cb01b2e600532300508400527b01b01b3230052e7", + "0x2df2e12e22e303f3230052e400527701b2e403300732300503300527801b", + "0x2e100528601b01b3230052e300531d01b2dc0870902dd0922de08f08d07e", + "0x531d01b01b32300507e00531d01b01b3230052df00522c01b01b323005", + "0x28601b01b3230052de0050f701b01b32300508f00531d01b01b32300508d", + "0x1b01b32300509000522201b01b3230052dd00522c01b01b323005092005", + "0x53230052e200527b01b01b3230052dc00522c01b01b323005087005222", + "0x2501b2d90053230050982e50072d601b0980053230052da0052cb01b2da", + "0x501b00701b09f0054aa01b3230072d900507e01b2d90053230052d9005", + "0x2d62d803f32300509b00527701b09b2c90073230052c900527801b01b323", + "0x6301b01b3230052d800531d01b2cb2cc2cd2ce2cf0aa2d20a70a52d40a3", + "0x1b01b3230050a500531d01b01b3230052d400522c01b01b3230052d6005", + "0x1b3230050aa0050f701b01b3230052d200531d01b01b3230050a700531d", + "0x3230052cd00522201b01b3230052ce00522c01b01b3230052cf00528601b", + "0x50a30050b901b01b3230052cb00522c01b01b3230052cc00522201b01b", + "0x2c803f3230052ca00527701b2ca03300732300503300527801b0af005323", + "0x1b01b3230052c800531d01b0bf0bb0b90b60b73b50cd3b43b33b20492c7", + "0x1b3230053b300531d01b01b3230053b200522c01b01b3230052c7005063", + "0x3230053b50050f701b01b3230050cd00531d01b01b3230053b400531d01b", + "0x50b900522201b01b3230050b600522c01b01b3230050b700528601b01b", + "0x490050b901b01b3230050bf00522c01b01b3230050bb00522201b01b323", + "0x1b32300501b00701b01b4ab01b3230072c50af00727601b2c5005323005", + "0x32300502300506301b01b32300504300531d01b01b32300503f00531d01b", + "0x503300508801b01b3230052c900508801b01b32300504400531d01b01b", + "0x501b19301b01b32300504500531d01b01b32300504200506301b01b323", + "0x527701b41b2c90073230052c900527801b01b32300501b00701b01b4ac", + "0x531d01b0cb2b32b92ba2bb2bc42f0c52be0c42bf42a2d503f32300541b", + "0x31d01b01b3230052bf00528601b01b32300542a00506301b01b3230052d5", + "0x1b01b32300542f00531d01b01b3230050c500531d01b01b3230052be005", + "0x1b3230052ba00522c01b01b3230052bb00528601b01b3230052bc0050f7", + "0x3230050cb00522c01b01b3230052b300522201b01b3230052b900522201b", + "0x2401b2ae2b00073230052b000511b01b2b00053230050c400511a01b01b", + "0x32300503300527801b2b10053230050c200501801b0c20053230052ae005", + "0xd42b52b40d22b70d02a92aa2ab2b803f3230050cc00527701b0cc033007", + "0x528601b01b3230052ab00506301b01b3230052b800531d01b2a02a82b6", + "0x31d01b01b3230052b700531d01b01b3230050d000531d01b01b3230052aa", + "0x1b01b3230052b500528601b01b3230052b40050f701b01b3230050d2005", + "0x1b3230052a800522201b01b3230052b600522201b01b3230050d400522c", + "0x52a200511b01b2a20053230052a900511a01b01b3230052a000522c01b", + "0xda00532300529c00501801b29c00532300529d00502401b29d2a2007323", + "0x2b100711901b0da0053230050da00503601b2b10053230052b100503601b", + "0x31d01b01b32300501b02001b01b32300501b00701b01b4ad01b3230070da", + "0x1b01b32300502300506301b01b32300504300531d01b01b32300503f005", + "0x1b32300503300508801b01b3230052c900508801b01b32300504400531d", + "0x3230052a200522c01b01b32300504500531d01b01b32300504200506301b", + "0x31f00503101b29a00532300501b00504601b01b3230052b000522c01b01b", + "0x501b02001b01b32300501b00701b01b4ae00501b19301b298005323005", + "0x2c901b31f00532300531f00503101b01b00532300501b00504601b01b323", + "0x2b031f01b04727501b2a20053230052a20052c901b2b00053230052b0005", + "0x701b0df0054af29300532300729500527301b2950de2970243230052a2", + "0x3230050e300522c01b28f2920e302432300529300512101b01b32300501b", + "0x1b28d0054b028e00532300728f00512001b01b32300529200522c01b01b", + "0x1b01b32300502300506301b01b32300528e00522501b01b32300501b007", + "0x1b32300503300508801b01b3230052c900508801b01b32300504400531d", + "0x32300504300531d01b01b32300504500531d01b01b32300504200506301b", + "0xde00503101b29a00532300529700504601b01b32300503f00531d01b01b", + "0x28b00532300529800504801b28c00532300529a00527101b298005323005", + "0x1b01b32300528d00522501b01b32300501b00701b01b4b100501b19301b", + "0x2852860ed0eb28703f32300528a00527701b28a2c90073230052c9005278", + "0x50eb00506301b01b32300528700531d01b0f72822830ee0f00f10ef284", + "0x28400531d01b01b32300528600522c01b01b3230050ed00528601b01b323", + "0x528601b01b3230050f10050f701b01b3230050ef00531d01b01b323005", + "0x22201b01b32300528300522201b01b3230050ee00522c01b01b3230050f0", + "0xf900532300528500504301b01b3230050f700522c01b01b323005282005", + "0xff2802810f603f3230050f800527701b0f803300732300503300527801b", + "0x28100506301b01b3230050f600531d01b10610810910727d27e0fe100101", + "0x531d01b01b3230050ff00522c01b01b32300528000528601b01b323005", + "0x28601b01b32300527e0050f701b01b3230050fe00531d01b01b323005100", + "0x1b01b32300510900522201b01b32300510700522c01b01b32300527d005", + "0x532300510100504301b01b32300510600522c01b01b323005108005222", + "0x7e01b11300532300511300502501b11300532300527c0f90072d601b27c", + "0x3230052c900527801b01b32300501b00701b10f0054b201b323007113005", + "0x1811b11a27627727827911711527b03f32300510e00527701b10e2c9007", + "0x528601b01b32300511500506301b01b32300527b00531d01b273275119", + "0x31d01b01b32300527800531d01b01b32300527900522c01b01b323005117", + "0x1b01b32300511b00528601b01b32300511a0050f701b01b323005276005", + "0x1b32300527500522201b01b32300511900522201b01b32300501800522c", + "0x503300527801b12100532300527700504301b01b32300527300522c01b", + "0x12b26c26d12512626f27004827103f32300512000527701b120033007323", + "0x28601b01b32300504800506301b01b32300527100531d01b26b12a12c12d", + "0x1b01b32300512600531d01b01b32300526f00522c01b01b323005270005", + "0x1b32300512b00528601b01b32300526c0050f701b01b32300526d00531d", + "0x32300512a00522201b01b32300512c00522201b01b32300512d00522c01b", + "0x1210072d601b26a00532300512500504301b01b32300526b00522c01b01b", + "0x1b32300726900507e01b26900532300526900502501b26900532300526a", + "0x27701b1332c90073230052c900527801b01b32300501b00701b1340054b3", + "0x31d01b14d26426026214314114013e13c14526526626703f323005133005", + "0x1b01b32300526500528601b01b32300526600506301b01b323005267005", + "0x1b32300513e00531d01b01b32300513c00531d01b01b32300514500522c", + "0x32300526200522c01b01b32300514300528601b01b3230051410050f701b", + "0x514d00522c01b01b32300526400522201b01b32300526000522201b01b", + "0x1b14b03300732300503300527801b14c00532300514000504301b01b323", + "0x1b25725825a25b25c25d25e15714614714814914a03f32300514b005277", + "0x1b32300514800528601b01b32300514900506301b01b32300514a00531d", + "0x32300515700531d01b01b32300514600531d01b01b32300514700522c01b", + "0x525b00522c01b01b32300525c00528601b01b32300525d0050f701b01b", + "0x25700522c01b01b32300525800522201b01b32300525a00522201b01b323", + "0x25500532300525614c0072d601b25600532300525e00504301b01b323005", + "0x701b1600054b401b32300725500507e01b25500532300525500502501b", + "0x3f32300516200527701b1622c90073230052c900527801b01b32300501b", + "0x1b32300525300531d01b24824924d13813925016a168167165252164253", + "0x32300516500522c01b01b32300525200528601b01b32300516400506301b", + "0x516a00531d01b01b32300516800531d01b01b32300516700531d01b01b", + "0x24d00522201b01b32300513800522c01b01b32300513900528601b01b323", + "0x527001b01b32300524800522c01b01b32300524900522201b01b323005", + "0x32300524600512601b24624700732300524700526f01b247005323005250", + "0x1b17203300732300503300527801b17000532300524500512501b245005", + "0x1b17b23d18318218018124217a17817724417517303f323005172005277", + "0x1b32300524400528601b01b32300517500506301b01b32300517300531d", + "0x32300517a00531d01b01b32300517800531d01b01b32300517700522c01b", + "0x518200522c01b01b32300518000528601b01b32300524200531d01b01b", + "0x17b00522c01b01b32300523d00522201b01b32300518300522201b01b323", + "0x18723e00732300523e00526f01b23e00532300518100527001b01b323005", + "0x17000503601b24a00532300524b00512501b24b00532300518700512601b", + "0x1b32300724a17000711901b24a00532300524a00503601b170005323005", + "0x504400531d01b01b32300502300506301b01b32300501b00701b01b4b5", + "0x4200506301b01b32300503300508801b01b3230052c900508801b01b323", + "0x531d01b01b32300504300531d01b01b32300504500531d01b01b323005", + "0x4601b01b3230052470050f701b01b32300523e0050f701b01b32300503f", + "0x1b4b600501b19301b18a0053230050de00503101b239005323005297005", + "0x3230050de00503101b29700532300529700504601b01b32300501b00701b", + "0x26c01b23e00532300523e00526d01b24700532300524700526d01b0de005", + "0x4b719000532300718e00512b01b18e23818c02432300523e2470de297047", + "0xf701b23323523b02432300519000512d01b01b32300501b00701b237005", + "0x22b00532300723300512001b01b3230052350050f701b01b32300523b005", + "0x2c900508801b01b32300522b00522501b01b32300501b00701b22a0054b8", + "0x531d01b01b32300504200506301b01b32300503300508801b01b323005", + "0x31d01b01b32300503f00531d01b01b32300504300531d01b01b323005045", + "0x23900532300518c00504601b01b32300502300506301b01b323005044005", + "0x18a00504801b22800532300523900527101b18a00532300523800503101b", + "0x22a00522501b01b32300501b00701b01b4b900501b19301b227005323005", + "0x22403f32300519800527701b1982c90073230052c900527801b01b323005", + "0x1b01b32300522400531d01b20c20e2102141a321921a21c19e19c21d221", + "0x1b32300519c00522c01b01b32300521d00528601b01b323005221005063", + "0x32300521a00531d01b01b32300521c00531d01b01b32300519e00531d01b", + "0x521000522201b01b32300521400522c01b01b3230052190050f701b01b", + "0x1a30050b901b01b32300520c00522c01b01b32300520e00522201b01b323", + "0x3f32300520600527701b20603300732300503300527801b20a005323005", + "0x1b32300520300531d01b1fc1fd1b42041ff17c2001b01ae2011ac202203", + "0x32300520100522c01b01b3230051ac00528601b01b32300520200506301b", + "0x520000531d01b01b3230051b000531d01b01b3230051ae00531d01b01b", + "0x1b400522201b01b32300520400522c01b01b32300517c0050f701b01b323", + "0x50b901b01b3230051fc00522c01b01b3230051fd00522201b01b323005", + "0x32300501b00701b01b4ba01b3230071fb20a00727601b1fb0053230051ff", + "0x504200506301b01b32300503300508801b01b3230052c900508801b01b", + "0x3f00531d01b01b32300504300531d01b01b32300504500531d01b01b323", + "0x504601b01b32300502300506301b01b32300504400531d01b01b323005", + "0x1b01b4bb00501b19301b1b700532300523800503101b1f800532300518c", + "0x3230051b900527701b1b92c90073230052c900527801b01b32300501b007", + "0x3230051f600531d01b1e31c21e81e91ea1eb1ec1ed1ee1f91f31bb1f603f", + "0x51f900522c01b01b3230051f300528601b01b3230051bb00506301b01b", + "0x1ec00531d01b01b3230051ed00531d01b01b3230051ee00531d01b01b323", + "0x522201b01b3230051ea00528601b01b3230051eb0050f701b01b323005", + "0x11a01b01b3230051e300522c01b01b3230051c200522201b01b3230051e8", + "0x51de00502401b1de1e10073230051e100511b01b1e10053230051e9005", + "0x1d203300732300503300527801b1d90053230051dc00501801b1dc005323", + "0x4c64c54c44c34c24c14c04bf4be4bd4bc0001df03f3230051d200527701b", + "0x3230054bc00528601b01b32300500000506301b01b3230051df00531d01b", + "0x54bf00531d01b01b3230054be00531d01b01b3230054bd00522c01b01b", + "0x4c200528601b01b3230054c10050f701b01b3230054c000531d01b01b323", + "0x522c01b01b3230054c500522201b01b3230054c400522201b01b323005", + "0x4c70073230054c700511b01b4c70053230054c300511a01b01b3230054c6", + "0x503601b32b0053230054c900501801b4c90053230054c800502401b4c8", + "0x32300732b1d900711901b32b00532300532b00503601b1d90053230051d9", + "0x3300508801b01b3230052c900508801b01b32300501b00701b01b4ca01b", + "0x531d01b01b32300504500531d01b01b32300504200506301b01b323005", + "0x6301b01b32300504400531d01b01b32300503f00531d01b01b323005043", + "0x1b01b3230051e100522c01b01b3230054c700522c01b01b323005023005", + "0x4cd00501b19301b4cc00532300523800503101b4cb00532300518c005046", + "0x523800503101b18c00532300518c00504601b01b32300501b00701b01b", + "0x1b4c70053230054c70052c901b1e10053230051e10052c901b238005323", + "0x4d10053230074d000527301b4d04cf4ce0243230054c71e123818c047275", + "0x1b4d532a4d40243230054d100512101b01b32300501b00701b4d30054d2", + "0x53230074d500512001b01b32300532a00522c01b01b3230054d400522c", + "0x506301b01b3230054d600522501b01b32300501b00701b4d80054d74d6", + "0x31d01b01b32300504300531d01b01b32300504500531d01b01b323005042", + "0x1b01b32300502300506301b01b32300504400531d01b01b32300503f005", + "0x53230054ce00504601b01b3230052c900508801b01b323005033005088", + "0x504801b4d90053230054cb00527101b4cc0053230054cf00503101b4cb", + "0x522501b01b32300501b00701b01b4db00501b19301b4da0053230054cc", + "0x3f3230054dc00527701b4dc2c90073230052c900527801b01b3230054d8", + "0x1b3230054dd00531d01b4e84e74e63294e54e44e34e24e14e04df4de4dd", + "0x3230054e000522c01b01b3230054df00528601b01b3230054de00506301b", + "0x54e300531d01b01b3230054e200531d01b01b3230054e100531d01b01b", + "0x32900522c01b01b3230054e500528601b01b3230054e40050f701b01b323", + "0x512c01b01b3230054e800522c01b01b3230054e700522201b01b323005", + "0x3230054ea00527701b4ea03300732300503300527801b4e90053230054e6", + "0x3230054eb00531d01b4f63284f54f44f34f24f14f04ef4ee4ed4ec4eb03f", + "0x54ee00522c01b01b3230054ed00528601b01b3230054ec00506301b01b", + "0x4f100531d01b01b3230054f000531d01b01b3230054ef00531d01b01b323", + "0x522c01b01b3230054f300528601b01b3230054f20050f701b01b323005", + "0x12c01b01b3230054f600522c01b01b32300532800522201b01b3230054f4", + "0x501b00701b01b4f801b3230074f74e900711901b4f70053230054f5005", + "0x4300531d01b01b32300504500531d01b01b32300504200506301b01b323", + "0x506301b01b32300504400531d01b01b32300503f00531d01b01b323005", + "0x4601b01b3230052c900508801b01b32300503300508801b01b323005023", + "0x1b4fb00501b19301b4fa0053230054cf00503101b4f90053230054ce005", + "0x54fc00527701b4fc2c90073230052c900527801b01b32300501b00701b", + "0x54fd00531d01b3275085075065055045035025015004ff4fe4fd03f323", + "0x50000522c01b01b3230054ff00528601b01b3230054fe00506301b01b323", + "0x531d01b01b32300550200531d01b01b32300550100531d01b01b323005", + "0x22c01b01b32300550500528601b01b3230055040050f701b01b323005503", + "0x1b01b32300532700522c01b01b32300550700522201b01b323005506005", + "0x50a00527701b50a03300732300503300527801b50900532300550800512c", + "0x50b00531d01b51551451351232d51151050f50e50d32650c50b03f323005", + "0x522c01b01b32300532600528601b01b32300550c00506301b01b323005", + "0x31d01b01b32300550f00531d01b01b32300550e00531d01b01b32300550d", + "0x1b01b32300532d00528601b01b3230055110050f701b01b323005510005", + "0x1b32300551500522c01b01b32300551300522201b01b32300551200522c", + "0x701b01b51701b32300751650900711901b51600532300551400512c01b", + "0x31d01b01b32300504500531d01b01b32300504200506301b01b32300501b", + "0x1b01b32300504400531d01b01b32300503f00531d01b01b323005043005", + "0x1b3230052c900508801b01b32300503300508801b01b323005023005063", + "0x501b19301b5190053230054cf00503101b5180053230054ce00504601b", + "0x51f51e51d51c51b03f3230052c900527701b01b32300501b00701b01b51a", + "0x551c00506301b01b32300551b00531d01b526525524523522521520325", + "0x51f00531d01b01b32300551e00522c01b01b32300551d00528601b01b323", + "0x50f701b01b32300552000531d01b01b32300532500531d01b01b323005", + "0x22201b01b32300552300522c01b01b32300552200528601b01b323005521", + "0x52700532300552600511a01b01b32300552500522201b01b323005524005", + "0x501801b52900532300552800502401b52852700732300552700511b01b", + "0x53253153052f52e52d52c52b03f32300503300527701b52a005323005529", + "0x1b01b32300552c00506301b01b32300552b00531d01b537536535534533", + "0x1b32300552f00531d01b01b32300552e00522c01b01b32300552d005286", + "0x3230055320050f701b01b32300553100531d01b01b32300553000531d01b", + "0x553500522201b01b32300553400522c01b01b32300553300528601b01b", + "0x511b01b53800532300553700511a01b01b32300553600522201b01b323", + "0x32300553a00501801b53a00532300553900502401b539538007323005538", + "0x11901b53b00532300553b00503601b52a00532300552a00503601b53b005", + "0x32300504200506301b01b32300501b00701b01b53c01b32300753b52a007", + "0x503f00531d01b01b32300504300531d01b01b32300504500531d01b01b", + "0x53800522c01b01b32300502300506301b01b32300504400531d01b01b323", + "0x3101b53d0053230054ce00504601b01b32300552700522c01b01b323005", + "0x4601b01b32300501b00701b01b53f00501b19301b53e0053230054cf005", + "0x3230055270052c901b4cf0053230054cf00503101b4ce0053230054ce005", + "0x243230055385274cf4ce04727501b5380053230055380052c901b527005", + "0x1b32300501b00701b54400554354200532300754100527301b54154032f", + "0x522c01b01b32300533000522c01b54654533002432300554200512101b", + "0x32300501b00701b54900554854700532300754600512001b01b323005545", + "0x503f00531d01b01b32300504300531d01b01b32300554700522501b01b", + "0x4500531d01b01b32300502300506301b01b32300504400531d01b01b323", + "0x3101b53d00532300532f00504601b01b32300504200506301b01b323005", + "0x22501b01b32300501b00701b01b53f00501b19301b53e005323005540005", + "0x32300504554a0072d601b54a0053230050420052cb01b01b323005549005", + "0x54d00554c01b32300754b00507e01b54b00532300554b00502501b54b005", + "0x504454e0072d601b54e0053230050230052cb01b01b32300501b00701b", + "0x555001b32300754f00507e01b54f00532300554f00502501b54f005323", + "0x55200502501b55200532300504303f0072d601b01b32300501b00701b551", + "0x1b32300501b00701b55400555301b32300755200507e01b552005323005", + "0x533300526b01b33300532300555500512a01b55500532300501b03f01b", + "0x1b54000532300554000503101b32f00532300532f00504601b556005323", + "0x4054032f04700555600532300555600526a01b040005323005040005317", + "0x532300501b31b01b01b3230055540052de01b01b32300501b00701b556", + "0x55700732401b55800532300555800502501b55800532300501b26901b557", + "0x532300555933400702d01b33400532300501b00901b559005323005558", + "0x503101b32f00532300532f00504601b55b00532300555a00513401b55a", + "0x532300555b00526a01b04000532300504000531701b540005323005540", + "0x1b3230055510052de01b01b32300501b00701b55b04054032f04700555b", + "0x532300501b31b01b01b32300503f00531d01b01b32300504300531d01b", + "0x55c00732401b55d00532300555d00502501b55d00532300501b13301b55c", + "0x532300555e55f00702d01b55f00532300501b00901b55e00532300555d", + "0x503101b32f00532300532f00504601b56100532300556000513401b560", + "0x532300556100526a01b04000532300504000531701b540005323005540", + "0x1b32300554d0052de01b01b32300501b00701b56104054032f047005561", + "0x32300504400531d01b01b32300503f00531d01b01b32300504300531d01b", + "0x32300501b26701b56200532300501b31b01b01b32300502300506301b01b", + "0x1b56400532300556356200732401b56300532300556300502501b563005", + "0x556600513401b56600532300556456500702d01b56500532300501b009", + "0x1b54000532300554000503101b32f00532300532f00504601b567005323", + "0x4054032f04700556700532300556700526a01b040005323005040005317", + "0x32300503f00531d01b01b32300504300531d01b01b32300501b00701b567", + "0x504500531d01b01b32300502300506301b01b32300504400531d01b01b", + "0x503101b56800532300532f00504601b01b32300504200506301b01b323", + "0x1b01b56b00501b19301b56a0053230055440052bb01b569005323005540", + "0x1b01b32300504500531d01b01b32300504200506301b01b32300501b007", + "0x1b32300504400531d01b01b32300503f00531d01b01b32300504300531d", + "0x3230052c900508801b01b32300503300508801b01b32300502300506301b", + "0x52bb01b5690053230054cf00503101b5680053230054ce00504601b01b", + "0x508801b01b32300501b00701b01b56b00501b19301b56a0053230054d3", + "0x31d01b01b32300504200506301b01b32300503300508801b01b3230052c9", + "0x1b01b32300503f00531d01b01b32300504300531d01b01b323005045005", + "0x532300518c00504601b01b32300502300506301b01b32300504400531d", + "0x1b19301b56a0053230052370052bb01b56900532300523800503101b568", + "0x2300506301b01b3230051600052de01b01b32300501b00701b01b56b005", + "0x508801b01b3230052c900508801b01b32300504400531d01b01b323005", + "0x31d01b01b32300504500531d01b01b32300504200506301b01b323005033", + "0x56c00532300529700504601b01b32300503f00531d01b01b323005043005", + "0x1b32300501b00701b01b56e00501b19301b56d0053230050de00503101b", + "0x32300504400531d01b01b32300502300506301b01b3230051340052de01b", + "0x504200506301b01b32300503300508801b01b3230052c900508801b01b", + "0x3f00531d01b01b32300504300531d01b01b32300504500531d01b01b323", + "0x1b5700053230050de00503101b56f00532300529700504601b01b323005", + "0x6301b01b32300510f0052de01b01b32300501b00701b01b57100501b193", + "0x1b01b3230052c900508801b01b32300504400531d01b01b323005023005", + "0x1b32300504500531d01b01b32300504200506301b01b323005033005088", + "0x32300529700504601b01b32300503f00531d01b01b32300504300531d01b", + "0x501b00701b01b57300501b19301b5720053230050de00503101b336005", + "0x2c900508801b01b32300504400531d01b01b32300502300506301b01b323", + "0x531d01b01b32300504200506301b01b32300503300508801b01b323005", + "0x4601b01b32300503f00531d01b01b32300504300531d01b01b323005045", + "0x3230050df0052bb01b5690053230050de00503101b568005323005297005", + "0x3101b56800532300556800504601b57400532300556a00513401b56a005", + "0x32300557400526a01b04000532300504000531701b569005323005569005", + "0x32300509f0052de01b01b32300501b00701b574040569568047005574005", + "0x502300506301b01b32300504300531d01b01b32300503f00531d01b01b", + "0x3300508801b01b3230052c900508801b01b32300504400531d01b01b323", + "0x1b19301b01b32300504500531d01b01b32300504200506301b01b323005", + "0x3f00531d01b01b3230050860052de01b01b32300501b00701b01b4ac005", + "0x531d01b01b32300502300506301b01b32300504300531d01b01b323005", + "0x6301b01b32300503300508801b01b3230052c900508801b01b323005044", + "0x4601b01b32300501b02001b01b32300504500531d01b01b323005042005", + "0x32300528c00527101b28b00532300531f00503101b28c00532300501b005", + "0x4801b56f00532300533600527101b57200532300528b00504801b336005", + "0x32300557000504801b56c00532300556f00527101b570005323005572005", + "0x27101b22700532300556d00504801b22800532300556c00527101b56d005", + "0x3230051f800527101b1b700532300522700504801b1f8005323005228005", + "0x4801b4f90053230054d900527101b4da0053230051b700504801b4d9005", + "0x3230054fa00504801b5180053230054f900527101b4fa0053230054da005", + "0x31b01b53e00532300551900504801b53d00532300551800527101b519005", + "0x57600532300557600502501b57600532300501b26601b57500532300501b", + "0x57800702d01b57800532300501b00901b57700532300557657500732401b", + "0x532300553d00504601b57a00532300557900513401b579005323005577", + "0x526a01b04000532300504000531701b53e00532300553e00503101b53d", + "0x52de01b01b32300501b00701b57a04053e53d04700557a00532300557a", + "0x6301b01b32300504300531d01b01b32300503f00531d01b01b323005055", + "0x1b01b32300504600508801b01b32300504400531d01b01b323005023005", + "0x1b32300532100510f01b01b32300504200506301b01b32300504500531d", + "0x33500532300501b31b01b01b32300501b02001b01b32300500900510e01b", + "0x57b33500732401b57b00532300557b00502501b57b00532300501b26501b", + "0x57e00532300557c57d00702d01b57d00532300501b00901b57c005323005", + "0x31f00503101b01b00532300501b00504601b57f00532300557e00513401b", + "0x57f00532300557f00526a01b04000532300504000531701b31f005323005", + "0x1b01b32300503e00506c01b01b32300501b00701b57f04031f01b047005", + "0x1b32300504300531d01b01b3230050470052f501b01b32300507d005145", + "0x32300504600508801b01b32300504400531d01b01b32300532100510f01b", + "0x519300513c01b01b32300504100514501b01b32300504500531d01b01b", + "0x13401b58100532300531a58000702d01b58000532300501b00901b01b323", + "0x32300531d00503101b01b00532300501b00504601b582005323005581005", + "0x4700558200532300558200526a01b31b00532300531b00531701b31d005", + "0x13e01b04300532300501b31b01b01b3230050070052f301b58231b31d01b", + "0x4104300732401b04100532300504200514001b042024007323005024005", + "0x32300519304000732401b1930460073230050460052cd01b040005323005", + "0x732401b03e00532300503e00502501b03e00532300501b14101b03f005", + "0x73230050450052cd01b07d00532300501b05101b02300532300503e03f", + "0x1b32100532300532100502501b32100532300507d0200072b301b020045", + "0x50440052cd01b31e00532300501b05101b31f005323005321023007324", + "0x532300531b00502501b31b00532300531e31d0072b301b31d044007323", + "0x1b32402500732300531a00521501b31a00532300531b31f00732401b31b", + "0x32300502400513e01b00900532300532400521701b01b323005025005216", + "0x700904702d00501b0462e901b0090053230050090052c901b02d024007", + "0x31700522c01b01b32300501b00701b1f507c0b0024583317031028024323", + "0x1b03700532300504519200732401b19200532300501b31b01b01b323005", + "0x521601b03603800732300503900521501b039005323005044037007324", + "0x2800532300502800503101b20d00532300503600521701b01b323005038", + "0x21302432300720d0460240310280462e901b20d00532300520d0052c901b", + "0x532300521600521b01b01b32300501b00701b21e21b217024584216215", + "0x531701b21300532300521300503101b22200532300521f00521e01b21f", + "0x701b2222152130240052220053230052220050b001b215005323005215", + "0x22500532300521e22300702d01b22300532300501b00901b01b32300501b", + "0x21b00531701b21700532300521700503101b22900532300522500502801b", + "0x1b00701b22921b2170240052290053230052290050b001b21b005323005", + "0x52ea01b01b32300504600531d01b01b32300504500531d01b01b323005", + "0x2d01b04b00532300501b00901b01b32300504400531d01b01b323005024", + "0x50b000503101b05300532300522c00502801b22c0053230051f504b007", + "0x50530053230050530050b001b07c00532300507c00531701b0b0005323", + "0x4732300502400500701b04714301b01b32300501b02001b05307c0b0024", + "0x450053230050450052e401b04700532300504700504601b044045046047", + "0x4504704700504400532300504400526201b04600532300504600503101b", + "0x32300501b26401b04700532300501b26001b01b32300501b02001b044046", + "0x14b01b04400532300504504600714c01b04500532300501b14d01b046005", + "0x32300501b14901b04300532300504404700714a01b044005323005044005", + "0x14601b01b32300504100514701b04004100732300504300514801b042005", + "0x32300500500503101b01b00532300501b00504601b193005323005040005", + "0x25d01b04200532300504200525e01b19300532300519300515701b005005", + "0x58507d00532300702300525c01b02303e03f02432300504219300501b047", + "0x25a01b31e31f32102432300507d00525b01b01b32300501b00701b020005", + "0x1b31d00532300501b03401b01b32300531e00522501b01b323005321005", + "0x32300503e00503101b03f00532300503f00504601b31b00532300501b037", + "0x3601b31d00532300531d00530201b31f00532300531f00525e01b03e005", + "0x32402531a02432300531b31d31f03e03f04625801b31b00532300531b005", + "0x525601b01b32300501b00701b02d00558600900532300732400525701b", + "0x732300502800525501b01b32300503100522501b031028007323005009", + "0x2425301b07c0053230050b000516201b01b32300531700516001b0b0317", + "0x1b32300501b00701b0360380390245870371921f502432300707c007025", + "0x20d00516501b21500532300501b25201b21320d00732300503700516401b", + "0x19200532300519200531701b1f50053230051f500503101b20d005323005", + "0x701b01b58801b32300721520d00727601b21300532300521300516501b", + "0x31b01b01b32300521300528601b01b3230050240052f301b01b32300501b", + "0x21700532300521700502501b21700532300501b16701b21600532300501b", + "0x21e00702d01b21e00532300501b00901b21b00532300521721600732401b", + "0x532300531a00504601b22200532300521f00516801b21f00532300521b", + "0x516a01b19200532300519200531701b1f50053230051f500503101b31a", + "0x1b25001b01b32300501b00701b2221921f531a047005222005323005222", + "0x1b32300501b00701b01b58901b32300722321300727601b223005323005", + "0x532300501b16701b22500532300501b31b01b01b3230050240052f301b", + "0x901b04b00532300522922500732401b22900532300522900502501b229", + "0x32300505300516801b05300532300504b22c00702d01b22c00532300501b", + "0x31701b1f50053230051f500503101b31a00532300531a00504601b050005", + "0x501921f531a04700505000532300505000516a01b192005323005192005", + "0x5400532300501b2b701b05100532300501b14901b01b32300501b00701b", + "0x525501b24300532300505405100713901b05400532300505400530201b", + "0x532300525100516201b01b32300524f00516001b25124f007323005243", + "0x570580243230070561921f502425301b05600532300505600513801b056", + "0x1b01b32300505500524d01b01b32300501b00701b2d32c92c602458a055", + "0x6000532300501b24901b03300532300501b31b01b01b3230050240052f3", + "0x1b00901b2ef00532300506003300732401b06000532300506000502501b", + "0x532300506200516801b0620053230052ef06300702d01b063005323005", + "0x531701b05800532300505800503101b31a00532300531a00504601b306", + "0x1b30605705831a04700530600532300530600516a01b057005323005057", + "0x32300500600521601b06a0060073230052d300521501b01b32300501b007", + "0x6c00503601b06a00532300506a00504101b06c00532300501b03701b01b", + "0x2c90053230052c900531701b2c60053230052c600503101b06c005323005", + "0x1b32300501b00701b07000558b06f30700732300706c06a31a02424801b", + "0x7200504301b07200532300506f00504401b06f00532300506f00524701b", + "0x1b30500532300530500502501b03400532300501b24601b305005323005", + "0x30700504601b07700532300507700502501b0770053230050343050072d6", + "0x1b32300501b00701b30200558c01b32300707700507e01b307005323005", + "0x7300517001b07300532300507402400724501b07400532300501b03f01b", + "0x2c60053230052c600503101b30700532300530700504601b07b005323005", + "0x2c630704700507b00532300507b00516a01b2c90053230052c900531701b", + "0x50240052f301b01b3230053020052de01b01b32300501b00701b07b2c9", + "0x30000502501b30000532300501b17201b07500532300501b31b01b01b323", + "0x2fe00532300501b00901b2ff00532300530007500732401b300005323005", + "0x504601b2fc0053230052fd00516801b2fd0053230052ff2fe00702d01b", + "0x53230052c900531701b2c60053230052c600503101b307005323005307", + "0x32300501b00701b2fc2c92c63070470052fc0053230052fc00516a01b2c9", + "0x32300501b17301b2fb00532300501b31b01b01b3230050240052f301b01b", + "0x1b2f60053230052fa2fb00732401b2fa0053230052fa00502501b2fa005", + "0x52f500516801b2f50053230052f608800702d01b08800532300501b009", + "0x1b2c60053230052c600503101b07000532300507000504601b2f4005323", + "0x2c92c60700470052f40053230052f400516a01b2c90053230052c9005317", + "0x32300531a00504601b01b3230050240052f301b01b32300501b00701b2f4", + "0x21f01b2f200532300503800531701b2f300532300503900503101b086005", + "0x2f301b01b32300501b00701b01b58d00501b19301b084005323005036005", + "0x3230052f100524401b2f02f100732300502d00517501b01b323005024005", + "0x531701b2f300532300502500503101b08600532300531a00504601b01b", + "0x1b01b58d00501b19301b0840053230052f000521f01b2f2005323005007", + "0x7f00732300502000517501b01b3230050240052f301b01b32300501b007", + "0x3e00503101b08600532300503f00504601b01b32300507f00524401b089", + "0x8400532300508900521f01b2f200532300500700531701b2f3005323005", + "0x2ec00516801b2ec00532300508432c00702d01b32c00532300501b00901b", + "0x2f30053230052f300503101b08600532300508600504601b2eb005323005", + "0x2f30860470052eb0053230052eb00516a01b2f20053230052f200531701b", + "0x32300501b17801b04700532300501b17701b01b32300501b02001b2eb2f2", + "0x1b04500532300504604700717a01b04600532300504600503601b046005", + "0x532300501b00504601b04300532300501b03701b04400532300501b037", + "0x503601b04400532300504400503601b04500532300504500524201b01b", + "0x518001b04104200732300504304404501b04718101b043005323005043", + "0x532300501b18201b01b32300501b00701b19300558e040005323007041", + "0x22501b07d02300732300504000523d01b03e00532300503f00518301b03f", + "0x32300502000523e01b32102000732300502300517b01b01b32300507d005", + "0x503101b04200532300504200504601b31f00532300532100518701b01b", + "0x532300531f00524b01b00700532300500700531701b005005323005005", + "0x4732300503e31f00700504204623901b03e00532300503e00524a01b31f", + "0x32300501b00701b32400558f02500532300731a00518a01b31a31b31d31e", + "0x22501b01b32300500900523801b02802d00902432300502500518c01b01b", + "0x532300503100519001b03100532300502d00518e01b01b323005028005", + "0x1921f507c0b004332300531700523b01b31700532300503100523701b031", + "0x22201b01b3230051f500522201b01b32300507c00522201b036038039037", + "0x1b01b32300503900522201b01b32300503700522201b01b323005192005", + "0x20d00532300501b23501b01b32300503600522201b01b323005038005222", + "0x701b01b59001b32300720d0b000711901b0b00053230050b000503601b", + "0x16701b21300532300501b31b01b01b3230050240052f301b01b32300501b", + "0x32300521521300732401b21500532300521500502501b21500532300501b", + "0x16801b21b00532300521621700702d01b21700532300501b00901b216005", + "0x32300531d00503101b31e00532300531e00504601b21e00532300521b005", + "0x4700521e00532300521e00516a01b31b00532300531b00531701b31d005", + "0x724501b21f00532300501b03f01b01b32300501b00701b21e31b31d31e", + "0x32300531e00504601b22300532300522200517001b22200532300521f024", + "0x16a01b31b00532300531b00531701b31d00532300531d00503101b31e005", + "0x2f301b01b32300501b00701b22331b31d31e047005223005323005223005", + "0x532300531d00503101b22500532300531e00504601b01b323005024005", + "0x1b19301b22c0053230053240052bb01b04b00532300531b00531701b229", + "0x4200504601b01b3230050240052f301b01b32300501b00701b01b591005", + "0x4b00532300500700531701b22900532300500500503101b225005323005", + "0x22500504601b05300532300522c00516801b22c0053230051930052bb01b", + "0x4b00532300504b00531701b22900532300522900503101b225005323005", + "0x1b32300501b02001b05304b22922504700505300532300505300516a01b", + "0x32300504600514b01b04500532300501b22b01b04600532300501b23301b", + "0x2432300704504602400504722a01b04500532300504500514b01b046005", + "0x32300504200522801b01b32300501b00701b193040041024592042043044", + "0x3101b03e00532300503e00519801b01b32300503f00522701b03e03f007", + "0x32300703e00522401b04300532300504300531701b044005323005044005", + "0x2f301b01b32300502300522101b01b32300501b00701b07d005593023005", + "0x1b32100532300501b21d01b02000532300501b31b01b01b323005047005", + "0x501b00901b31f00532300532102000732401b321005323005321005025", + "0x31b00532300531d00516801b31d00532300531f31e00702d01b31e005323", + "0x700509f01b04400532300504400503101b01b00532300501b00504601b", + "0x31b00532300531b00516a01b04300532300504300531701b007005323005", + "0x1b32300507d00522501b01b32300501b00701b31b04300704401b046005", + "0x32300531a00514b01b02500532300501b22b01b31a00532300501b19c01b", + "0x2432300702531a04304404722a01b02500532300502500514b01b31a005", + "0x32300502d00522701b01b32300501b00701b31703102802459402d009324", + "0x32300501b24901b0b000532300501b31b01b01b3230050470052f301b01b", + "0x1b1f500532300507c0b000732401b07c00532300507c00502501b07c005", + "0x503700516801b0370053230051f519200702d01b19200532300501b009", + "0x1b32400532300532400503101b01b00532300501b00504601b039005323", + "0x503900516a01b00900532300500900531701b00700532300500700509f", + "0x31700521501b01b32300501b00701b03900900732401b046005039005323", + "0x1b20d00532300501b03701b01b32300503800521601b036038007323005", + "0x502800503101b20d00532300520d00503601b036005323005036005041", + "0x732300720d03601b02424801b03100532300503100531701b028005323", + "0x1b21500532300521500524701b01b32300501b00701b216005595215213", + "0x32300501b19e01b21b00532300521700504301b217005323005215005044", + "0x1b21f00532300521e21b0072d601b21b00532300521b00502501b21e005", + "0x721f00507e01b21300532300521300504601b21f00532300521f005025", + "0x21a01b22300532300501b21c01b01b32300501b00701b22200559601b323", + "0x32300522500521901b22922300732300522300521901b22500532300501b", + "0x1b04b00532300504b00514b01b22900532300522900514b01b04b225007", + "0x1b00701b24305405102459705005322c02432300704b22903102804722a", + "0x1b22c00532300522c00503101b05000532300505000519801b01b323005", + "0x701b25100559824f00532300705000522401b053005323005053005317", + "0x2c602459905505705805604732300724f05322c0241a301b01b32300501b", + "0x524d01b06003300732300505700521401b01b32300501b00701b2d32c9", + "0x1b3230052ef00524d01b0632ef00732300522300521401b01b323005033", + "0x516401b06206000732300506000521901b06000532300506000514b01b", + "0x732300506300521901b01b32300500600528601b006306007323005062", + "0xb901b01b32300530700528601b30706c00732300506a00516401b06a063", + "0x1b32300501b04701b07000532300506c0050b901b06f005323005306005", + "0x5500514b01b05800532300505800531701b05600532300505600503101b", + "0x1b32300501b00701b01b59a01b32300707006f00727601b055005323005", + "0x32300505500524d01b01b32300522500524d01b01b3230050470052f301b", + "0x59b00501b19301b01b32300506000524d01b01b32300506300524d01b01b", + "0x7200528601b30507200732300506000516401b01b32300501b00701b01b", + "0x1b01b32300503400528601b07703400732300506300516401b01b323005", + "0x7430200727601b0740053230050770050b901b3020053230053050050b9", + "0x24d01b01b3230050470052f301b01b32300501b00701b01b59c01b323007", + "0x701b01b59d00501b19301b01b32300505500524d01b01b323005225005", + "0x1b32300507300524d01b07b07300732300505500521401b01b32300501b", + "0x7b00521901b01b32300507500524d01b30007500732300522500521401b", + "0x3230052fd00528601b2fd2fe0073230052ff00516401b2ff07b007323005", + "0x1b2fa2fb0073230052fc00516401b2fc30000732300530000521901b01b", + "0x3230052fb0050b901b2f60053230052fe0050b901b01b3230052fa005286", + "0x2f301b01b32300501b00701b01b59e01b3230070882f600727601b088005", + "0x1b01b32300507b00524d01b01b32300530000524d01b01b323005047005", + "0x2f42f500732300507b00516401b01b32300501b00701b01b59d00501b193", + "0x8600528601b2f308600732300530000516401b01b3230052f500528601b", + "0x1b0840053230052f30050b901b2f20053230052f40050b901b01b323005", + "0x50470052f301b01b32300501b00701b01b59f01b3230070842f2007276", + "0x32300501b21001b2f100532300501b31b01b01b32300501b02001b01b323", + "0x1b07f0053230052f02f100732401b2f00053230052f000502501b2f0005", + "0x532c00516801b32c00532300507f08900702d01b08900532300501b009", + "0x1b05600532300505600503101b21300532300521300504601b2ec005323", + "0x52ec00516a01b05800532300505800531701b00700532300500700509f", + "0x501b20e01b01b32300501b00701b2ec0580070562130460052ec005323", + "0x1b2e800532300501b20c01b2e92ea0073230052eb00516401b2eb005323", + "0x2e921302420601b2e80053230052e800520a01b2e90053230052e9005165", + "0x3230052e50050bb01b01b3230052e600528601b2e52e62e70243230052e8", + "0x720201b2e200532300501b20301b2e30053230052ea0050bb01b2e4005", + "0x52e32e10072b301b2e10053230052e100502501b2e10053230052e22e4", + "0x1b1ae01b08d00532300501b20101b07e00532300501b1ac01b2df005323", + "0x1b0920053230052de00508d01b2de00532300501b03f01b08f005323005", + "0x504601b0900053230052df00520001b2dd00532300509208f08d0241b0", + "0x532300500700509f01b05600532300505600503101b2e70053230052e7", + "0x517c01b07e00532300507e00514b01b05800532300505800531701b007", + "0x580070562e704420401b0900053230050900051ff01b2dd0053230052dd", + "0x51b401b01b32300501b04701b2d90982da2dc0870463230050902dd07e", + "0x32300509f0051fd01b01b32300501b00701b09b0055a009f0053230072d9", + "0x1b01b32300501b00701b0a30055a12d60053230072d80051fc01b2d8005", + "0x1b2d400532300501b03f01b01b3230052d600522501b01b32300501b020", + "0x8700504601b0a70053230050a500517001b0a50053230052d4047007245", + "0x2da0053230052da00509f01b2dc0053230052dc00503101b087005323005", + "0x2dc0870460050a70053230050a700516a01b09800532300509800531701b", + "0x501b31b01b01b3230050470052f301b01b32300501b00701b0a70982da", + "0x2cf0053230050aa00521f01b0aa0053230050a32d200732401b2d2005323", + "0x1b01b3230050470052f301b01b32300501b00701b01b5a200501b19301b", + "0x52cd00521f01b01b3230052ce00524401b2cd2ce00732300509b005175", + "0x2cc00702d01b2cc00532300501b00901b01b32300501b02001b2cf005323", + "0x532300508700504601b0af0053230052cb00516801b2cb0053230052cf", + "0x531701b2da0053230052da00509f01b2dc0053230052dc00503101b087", + "0xaf0982da2dc0870460050af0053230050af00516a01b098005323005098", + "0x1b32300522500524d01b01b32300522300524d01b01b32300501b00701b", + "0x52d32ca00702d01b2ca00532300501b00901b01b3230050470052f301b", + "0x1b21300532300521300504601b2c70053230052c800516801b2c8005323", + "0x52c900531701b00700532300500700509f01b2c60053230052c6005031", + "0x701b2c72c90072c62130460052c70053230052c700516a01b2c9005323", + "0x24d01b01b32300522300524d01b01b32300525100522501b01b32300501b", + "0x1b04900532300501b31b01b01b3230050470052f301b01b323005225005", + "0x53b204900732401b3b20053230053b200502501b3b200532300501b054", + "0x1b0cd0053230053b33b400702d01b3b400532300501b00901b3b3005323", + "0x522c00503101b21300532300521300504601b3b50053230050cd005168", + "0x1b05300532300505300531701b00700532300500700509f01b22c005323", + "0x1b32300501b00701b3b505300722c2130460053b50053230053b500516a", + "0x3230050470052f301b01b32300522500524d01b01b32300522300524d01b", + "0x516801b0b60053230052430b700702d01b0b700532300501b00901b01b", + "0x532300505100503101b21300532300521300504601b0b90053230050b6", + "0x516a01b05400532300505400531701b00700532300500700509f01b051", + "0x2de01b01b32300501b00701b0b90540070512130460050b90053230050b9", + "0x1b0bb00532300501b31b01b01b3230050470052f301b01b323005222005", + "0x50bf0bb00732401b0bf0053230050bf00502501b0bf00532300501b172", + "0x1b2d50053230052c541b00702d01b41b00532300501b00901b2c5005323", + "0x502800503101b21300532300521300504601b42a0053230052d5005168", + "0x1b03100532300503100531701b00700532300500700509f01b028005323", + "0x1b32300501b00701b42a03100702821304600542a00532300542a00516a", + "0x532300501b17301b2bf00532300501b31b01b01b3230050470052f301b", + "0x901b2be0053230050c42bf00732401b0c40053230050c400502501b0c4", + "0x32300542f00516801b42f0053230052be0c500702d01b0c500532300501b", + "0x9f01b02800532300502800503101b21600532300521600504601b2bc005", + "0x3230052bc00516a01b03100532300503100531701b007005323005007005", + "0x50470052f301b01b32300501b00701b2bc0310070282160460052bc005", + "0x16801b2ba0053230051932bb00702d01b2bb00532300501b00901b01b323", + "0x32300504100503101b01b00532300501b00504601b2b90053230052ba005", + "0x16a01b04000532300504000531701b00700532300500700509f01b041005", + "0x4700532300501b23301b2b904000704101b0460052b90053230052b9005", + "0x504600514b01b04700532300504700514b01b04600532300501b22b01b", + "0x410420245a30430440450243230070460470070050471fb01b046005323", + "0x1930051b701b03f1930073230050430051f801b01b32300501b00701b040", + "0x1b04500532300504500503101b03f00532300503f0051b901b01b323005", + "0x701b0230055a403e00532300703f0051f601b044005323005044005317", + "0x31b01b01b3230050240052f301b01b32300503e0051bb01b01b32300501b", + "0x2000532300502000502501b02000532300501b21d01b07d00532300501b", + "0x31f00702d01b31f00532300501b00901b32100532300502007d00732401b", + "0x532300501b00504601b31d00532300531e00516801b31e005323005321", + "0x516a01b04400532300504400531701b04500532300504500503101b01b", + "0x522501b01b32300501b00701b31d04404501b04700531d00532300531d", + "0x14b01b31a00532300501b22b01b31b00532300501b1f301b01b323005023", + "0x31b0440450471fb01b31a00532300531a00514b01b31b00532300531b005", + "0x1b701b01b32300501b00701b03102802d0245a500932402502432300731a", + "0x1b31700532300501b31b01b01b3230050240052f301b01b323005009005", + "0x50b031700732401b0b00053230050b000502501b0b000532300501b249", + "0x1b19200532300507c1f500702d01b1f500532300501b00901b07c005323", + "0x502500503101b01b00532300501b00504601b037005323005192005168", + "0x503700532300503700516a01b32400532300532400531701b025005323", + "0x3803900732300503100521501b01b32300501b00701b03732402501b047", + "0x32300503800504101b03600532300501b03701b01b32300503900521601b", + "0x31701b02d00532300502d00503101b03600532300503600503601b038005", + "0x2150055a621320d00732300703603801b02424801b028005323005028005", + "0x32300521300504401b21300532300521300524701b01b32300501b00701b", + "0x502501b21b00532300501b19e01b21700532300521600504301b216005", + "0x32300521e00502501b21e00532300521b2170072d601b217005323005217", + "0x21f0055a701b32300721e00507e01b20d00532300520d00504601b21e005", + "0x22300532300501b1ee01b22200532300501b1f901b01b32300501b00701b", + "0x14b01b22922300732300522300521901b22522200732300522200521901b", + "0x22502802d0471fb01b22900532300522900514b01b225005323005225005", + "0x1b901b01b32300501b00701b0540510500245a805322c04b024323007229", + "0x32300522c00531701b04b00532300504b00503101b053005323005053005", + "0x1b01b32300501b00701b24f0055a92430053230070530051f601b22c005", + "0x1b00701b2c92c60550245aa05705805625104732300724322c04b0241ed", + "0x1b01b3230052d300524d01b0332d300732300505800521401b01b323005", + "0x503300514b01b01b32300506000524d01b2ef060007323005222005214", + "0x6200732300506300516401b06303300732300503300521901b033005323", + "0x516401b0062ef0073230052ef00521901b01b32300530600528601b306", + "0x53230050620050b901b01b32300506c00528601b06c06a007323005006", + "0x531701b25100532300525100503101b06f00532300506a0050b901b307", + "0x32300706f30700727601b05700532300505700514b01b056005323005056", + "0x22300524d01b01b3230050240052f301b01b32300501b00701b01b5ab01b", + "0x524d01b01b3230052ef00524d01b01b32300505700524d01b01b323005", + "0x3300516401b01b32300501b00701b01b5ac00501b19301b01b323005033", + "0x3050073230052ef00516401b01b32300507000528601b072070007323005", + "0x340050b901b0770053230050720050b901b01b32300530500528601b034", + "0x1b32300501b00701b01b5ad01b32300730207700727601b302005323005", + "0x32300505700524d01b01b32300522300524d01b01b3230050240052f301b", + "0x732300505700521401b01b32300501b00701b01b5ae00501b19301b01b", + "0x24d01b07507b00732300522300521401b01b32300507400524d01b073074", + "0x32300530000516401b30007300732300507300521901b01b32300507b005", + "0x1b2fd07500732300507500521901b01b3230052fe00528601b2fe2ff007", + "0x52ff0050b901b01b3230052fb00528601b2fb2fc0073230052fd005164", + "0x5af01b3230072f62fa00727601b2f60053230052fc0050b901b2fa005323", + "0x32300507500524d01b01b3230050240052f301b01b32300501b00701b01b", + "0x1b32300501b00701b01b5ae00501b19301b01b32300507300524d01b01b", + "0x7500516401b01b32300508800528601b2f508800732300507300516401b", + "0x2f30053230052f50050b901b01b3230052f400528601b0862f4007323005", + "0x701b01b5b001b3230072f22f300727601b2f20053230050860050b901b", + "0x21001b08400532300501b31b01b01b3230050240052f301b01b32300501b", + "0x3230052f108400732401b2f10053230052f100502501b2f100532300501b", + "0x16801b0890053230052f007f00702d01b07f00532300501b00901b2f0005", + "0x32300525100503101b20d00532300520d00504601b32c005323005089005", + "0x4700532c00532300532c00516a01b05600532300505600531701b251005", + "0x516401b2ec00532300501b1ec01b01b32300501b00701b32c05625120d", + "0x53230052ea00516501b2e900532300501b20c01b2ea2eb0073230052ec", + "0x2e72e80243230052e92ea20d02420601b2e90053230052e900520a01b2ea", + "0x2e500531d01b2e50053230052e60050bb01b01b3230052e700528601b2e6", + "0x1eb01b01b3230052e400531d01b2e40053230052eb0050bb01b01b323005", + "0x2e30053230052e300514b01b2e200532300501b1ea01b2e300532300501b", + "0x2510471fb01b2e80053230052e800504601b2e20053230052e200514b01b", + "0x1b32300501b00701b2de08f08d0245b107e2df2e10243230072e22e3056", + "0x2df00531701b2e10053230052e100503101b07e00532300507e0051b901b", + "0x32300501b00701b2dd0055b209200532300707e0051f601b2df005323005", + "0x32300501b1c201b08700532300501b1e801b09000532300501b1e901b01b", + "0x31701b2e10053230052e100503101b2e80053230052e800504601b2dc005", + "0x32300508700514b01b09000532300509000514b01b2df0053230052df005", + "0x1e101b0920053230050920051e301b2dc0053230052dc00514b01b087005", + "0x709f0051de01b09f2d90982da0473230050922dc0870902df2e12e8044", + "0x1b01b32300509b0051dc01b01b32300501b00701b2d80055b309b005323", + "0x50a300517001b0a30053230052d602400724501b2d600532300501b03f", + "0x1b09800532300509800503101b2da0053230052da00504601b2d4005323", + "0x2d90982da0470052d40053230052d400516a01b2d90053230052d9005317", + "0x3230052d800516801b01b3230050240052f301b01b32300501b00701b2d4", + "0x31701b09800532300509800503101b2da0053230052da00504601b0a5005", + "0xa52d90982da0470050a50053230050a500516a01b2d90053230052d9005", + "0x1b3230050240052f301b01b3230052dd00522501b01b32300501b00701b", + "0x3230052d200502501b2d200532300501b05401b0a700532300501b31b01b", + "0x2d01b2cf00532300501b00901b0aa0053230052d20a700732401b2d2005", + "0x52e800504601b2cd0053230052ce00516801b2ce0053230050aa2cf007", + "0x1b2df0053230052df00531701b2e10053230052e100503101b2e8005323", + "0x1b01b32300501b00701b2cd2df2e12e80470052cd0053230052cd00516a", + "0x3230052de2cc00702d01b2cc00532300501b00901b01b3230050240052f3", + "0x3101b2e80053230052e800504601b0af0053230052cb00516801b2cb005", + "0x3230050af00516a01b08f00532300508f00531701b08d00532300508d005", + "0x32300522200524d01b01b32300501b00701b0af08f08d2e80470050af005", + "0x32300501b00901b01b3230050240052f301b01b32300522300524d01b01b", + "0x1b2c70053230052c800516801b2c80053230052c92ca00702d01b2ca005", + "0x52c600531701b05500532300505500503101b20d00532300520d005046", + "0x1b00701b2c72c605520d0470052c70053230052c700516a01b2c6005323", + "0x524d01b01b32300522200524d01b01b32300524f00522501b01b323005", + "0x5401b04900532300501b31b01b01b3230050240052f301b01b323005223", + "0x3230053b204900732401b3b20053230053b200502501b3b200532300501b", + "0x16801b0cd0053230053b33b400702d01b3b400532300501b00901b3b3005", + "0x32300504b00503101b20d00532300520d00504601b3b50053230050cd005", + "0x470053b50053230053b500516a01b22c00532300522c00531701b04b005", + "0x524d01b01b32300522200524d01b01b32300501b00701b3b522c04b20d", + "0x2d01b0b700532300501b00901b01b3230050240052f301b01b323005223", + "0x520d00504601b0b90053230050b600516801b0b60053230050540b7007", + "0x1b05100532300505100531701b05000532300505000503101b20d005323", + "0x1b01b32300501b00701b0b905105020d0470050b90053230050b900516a", + "0xbb00532300501b31b01b01b3230050240052f301b01b32300521f0052de", + "0xbf0bb00732401b0bf0053230050bf00502501b0bf00532300501b17201b", + "0x2d50053230052c541b00702d01b41b00532300501b00901b2c5005323005", + "0x2d00503101b20d00532300520d00504601b42a0053230052d500516801b", + "0x42a00532300542a00516a01b02800532300502800531701b02d005323005", + "0x1b01b3230050240052f301b01b32300501b00701b42a02802d20d047005", + "0x53230050c400502501b0c400532300501b17301b2bf00532300501b31b", + "0x702d01b0c500532300501b00901b2be0053230050c42bf00732401b0c4", + "0x32300521500504601b2bc00532300542f00516801b42f0053230052be0c5", + "0x16a01b02800532300502800531701b02d00532300502d00503101b215005", + "0x2f301b01b32300501b00701b2bc02802d2150470052bc0053230052bc005", + "0x53230050402bb00702d01b2bb00532300501b00901b01b323005024005", + "0x503101b01b00532300501b00504601b2b90053230052ba00516801b2ba", + "0x53230052b900516a01b04100532300504100531701b042005323005042", + "0x32300700501b00700501b01b32300501b02001b2b904104201b0470052b9", + "0x732300504700521501b01b32300501b00701b0430440075b4045046007", + "0x503601b19300532300501b1d901b04000532300504100501801b041042", + "0x71930400460241d201b19300532300519300503601b040005323005040", + "0x32300503e00522201b01b32300501b00701b07d0230075b503e03f007323", + "0x70420051df01b03f00532300503f00504601b01b32300501b04701b01b", + "0x532300532100504401b01b32300501b00701b31f0055b6321020007323", + "0x504001b31b00532300502000521f01b31d00532300531e00504201b31e", + "0x1b03f01b01b32300501b00701b01b5b700501b19301b31a00532300531d", + "0x31b00532300531f00521f01b32400532300502500503e01b025005323005", + "0x1b02d0055b800900532300731a00502301b31a00532300532400504001b", + "0x1b00701b3170055b903102800732300731b0051df01b01b32300501b007", + "0x1b07c0053230050b000504201b0b000532300503100504401b01b323005", + "0x5ba00501b19301b19200532300507c00504001b1f500532300502800521f", + "0x32300503700503e01b03700532300501b03f01b01b32300501b00701b01b", + "0x2301b19200532300503900504001b1f500532300531700521f01b039005", + "0x71f50051df01b01b32300501b00701b0360055bb038005323007192005", + "0x532300521300504401b01b32300501b00701b2150055bc21320d007323", + "0x504001b21b00532300520d00521f01b21700532300521600504201b216", + "0x1b03f01b01b32300501b00701b01b5bd00501b19301b21e005323005217", + "0x21b00532300521500521f01b22200532300521f00503e01b21f005323005", + "0x1b2250055be22300532300721e00502301b21e00532300522200504001b", + "0x32300722900507e01b2292230073230052230052cd01b01b32300501b007", + "0x705601b01b32300522300531d01b01b32300501b00701b04b0055bf01b", + "0x501b02001b01b32300501b00701b0500055c005322c00732300700903f", + "0x21701b01b32300505100521601b05405100732300521b00521501b01b323", + "0x5300704504600601b22c00532300522c00504601b243005323005054005", + "0x1b01b32300501b00701b0550570580245c105625124f024323007243038", + "0x32300524f00503101b2c600532300522c00504601b01b32300505600522c", + "0x501b00701b01b5c200501b19301b2d300532300525100531701b2c9005", + "0x3300702d01b03300532300501b00901b01b3230050240052f301b01b323", + "0x532300522c00504601b2ef00532300506000500001b060005323005055", + "0x54bc01b05700532300505700531701b05800532300505800503101b22c", + "0x1b02001b01b32300501b00701b2ef05705822c0470052ef0053230052ef", + "0x531d01b01b3230050240052f301b01b32300521b00521601b01b323005", + "0x2501b06200532300501b05401b06300532300501b31b01b01b323005038", + "0x32300501b00901b30600532300506206300732401b062005323005062005", + "0x1b06c00532300506a00500001b06a00532300530600600702d01b006005", + "0x500700531701b04500532300504500503101b050005323005050005046", + "0x1b00701b06c00704505004700506c00532300506c0054bc01b007005323", + "0x72d601b30700532300501b05101b01b32300504b0052de01b01b323005", + "0x32300706f00507e01b06f00532300506f00502501b06f005323005307223", + "0x30507200732300700903f0072eb01b01b32300501b00701b0700055c301b", + "0x521b00521501b01b32300501b02001b01b32300501b00701b0340055c4", + "0x1b07400532300530200521701b01b32300507700521601b302077007323", + "0x7b0730243230070740383050070450462e901b072005323005072005046", + "0x1b01b32300507500522c01b01b32300501b00701b2fe2ff3000245c5075", + "0x507b00531701b2fc00532300507300503101b2fd005323005072005046", + "0x50240052f301b01b32300501b00701b01b5c600501b19301b2fb005323", + "0x1b2f60053230052fe2fa00702d01b2fa00532300501b00901b01b323", + "0x32300530000503101b07200532300507200504601b0880053230052f6005", + "0x470050880053230050880054bc01b2ff0053230052ff00531701b300005", + "0x21b00521601b01b32300501b02001b01b32300501b00701b0882ff300072", + "0x1b31b01b01b32300503800531d01b01b3230050240052f301b01b323005", + "0x1b2f40053230052f400502501b2f400532300501b05401b2f5005323005", + "0x862f300702d01b2f300532300501b00901b0860053230052f42f5007324", + "0x3400532300503400504601b0840053230052f200500001b2f2005323005", + "0x840054bc01b00700532300500700531701b04500532300504500503101b", + "0x700052de01b01b32300501b00701b084007045034047005084005323005", + "0x52cd01b2f100532300501b4bd01b01b32300500900531d01b01b323005", + "0x507f00502501b07f0053230052f12f00072d601b2f0038007323005038", + "0x1b01b32300501b00701b0890055c701b32300707f00507e01b07f005323", + "0x3f00532300503f00504601b01b32300503800531d01b01b32300501b020", + "0x21b00521f01b00700532300500700531701b04500532300504500503101b", + "0x52ea2eb2ec32c04732300521b02400704503f0460a501b21b005323005", + "0x21601b01b3230050890052de01b01b32300501b00701b2ea2eb2ec32c047", + "0x53230052e90380072d601b2e900532300501b4be01b01b32300521b005", + "0x1b2e70055c801b3230072e800507e01b2e80053230052e800502501b2e8", + "0x31b01b01b3230050240052f301b01b32300501b02001b01b32300501b007", + "0x2e50053230052e500502501b2e500532300501b0aa01b2e600532300501b", + "0x2e300702d01b2e300532300501b00901b2e40053230052e52e600732401b", + "0x532300503f00504601b2e10053230052e200500001b2e20053230052e4", + "0x54bc01b00700532300500700531701b04500532300504500503101b03f", + "0x1b02001b01b32300501b00701b2e100704503f0470052e10053230052e1", + "0x3101b2fd00532300503f00504601b01b3230052e70052de01b01b323005", + "0x3230052fd00527101b2fb00532300500700531701b2fc005323005045005", + "0x5001b2d30053230052fb0054bf01b2c90053230052fc00504801b2c6005", + "0x32300507e0054c101b07e0053230052df0240074c001b2df00532300501b", + "0x501b00701b08d2d32c92c604700508d00532300508d0054bc01b08d005", + "0x521b00521601b01b32300522500522501b01b32300501b02001b01b323", + "0x900531d01b01b32300503800531d01b01b3230050240052f301b01b323", + "0x502501b2de00532300501b05401b08f00532300501b31b01b01b323005", + "0x532300501b00901b0920053230052de08f00732401b2de0053230052de", + "0x4601b08700532300509000500001b0900053230050922dd00702d01b2dd", + "0x32300500700531701b04500532300504500503101b03f00532300503f005", + "0x501b00701b08700704503f0470050870053230050870054bc01b007005", + "0x50240052f301b01b32300503600522501b01b32300501b02001b01b323", + "0x501b31b01b01b32300500900531d01b01b3230051f500521601b01b323", + "0x32401b2da0053230052da00502501b2da00532300501b05401b2dc005323", + "0x50982d900702d01b2d900532300501b00901b0980053230052da2dc007", + "0x1b03f00532300503f00504601b09b00532300509f00500001b09f005323", + "0x509b0054bc01b00700532300500700531701b045005323005045005031", + "0x32300501b02001b01b32300501b00701b09b00704503f04700509b005323", + "0x531b00521601b01b3230050240052f301b01b32300502d00522501b01b", + "0x2d600502501b2d600532300501b05401b2d800532300501b31b01b01b323", + "0x2d400532300501b00901b0a30053230052d62d800732401b2d6005323005", + "0x504601b0a70053230050a500500001b0a50053230050a32d400702d01b", + "0x532300500700531701b04500532300504500503101b03f00532300503f", + "0x32300501b00701b0a700704503f0470050a70053230050a70054bc01b007", + "0x50240052f301b01b32300504200521601b01b32300507d00522201b01b", + "0xaa00502501b0aa00532300501b4c201b2d200532300501b31b01b01b323", + "0x2ce00532300501b00901b2cf0053230050aa2d200732401b0aa005323005", + "0x504601b2cc0053230052cd00500001b2cd0053230052cf2ce00702d01b", + "0x532300500700531701b04500532300504500503101b023005323005023", + "0x32300501b00701b2cc0070450230470052cc0053230052cc0054bc01b007", + "0x32300501b31b01b01b3230050240052f301b01b32300504700521601b01b", + "0x732401b0af0053230050af00502501b0af00532300501b22301b2cb005", + "0x3230052ca2c800702d01b2c800532300501b00901b2ca0053230050af2cb", + "0x3101b04400532300504400504601b0490053230052c700500001b2c7005", + "0x3230050490054bc01b00700532300500700531701b043005323005043005", + "0x700501b00700501b01b32300501b02001b049007043044047005049005", + "0x3230050240052cd01b01b32300501b00701b0440450075c9046047007323", + "0x55ca01b32300704300507e01b04700532300504700504601b043024007", + "0x32300502400531d01b01b3230050070052f301b01b32300501b00701b042", + "0x504000502501b04000532300501b4c301b04100532300501b31b01b01b", + "0x1b03f00532300501b00901b19300532300504004100732401b040005323", + "0x4700504601b02300532300503e00516801b03e00532300519303f00702d", + "0x2300532300502300516a01b04600532300504600503101b047005323005", + "0x5101b01b3230050420052de01b01b32300501b00701b023046047024005", + "0x32300504700504601b02000532300507d0240072d601b07d00532300501b", + "0x2cf01b02000532300502000502501b04600532300504600503101b047005", + "0x501b00701b31e31f32102400531e31f321024323005020007046047047", + "0x501b31b01b01b3230050070052f301b01b32300502400531d01b01b323", + "0x32401b31b00532300531b00502501b31b00532300501b22301b31d005323", + "0x531a02500702d01b02500532300501b00901b31a00532300531b31d007", + "0x1b04500532300504500504601b00900532300532400516801b324005323", + "0x904404502400500900532300500900516a01b044005323005044005031", + "0x440450075cb04604700732300700501b00700501b01b32300501b02001b", + "0x504700504601b0430240073230050240052cd01b01b32300501b00701b", + "0x1b01b32300501b00701b0420055cc01b32300704300507e01b047005323", + "0x32300504100700724501b04100532300501b03f01b01b32300502400531d", + "0x3101b04700532300504700504601b19300532300504000517001b040005", + "0x1b19304604702400519300532300519300516a01b046005323005046005", + "0x1b03f00532300501b05101b01b3230050420052de01b01b32300501b007", + "0x4600503101b04700532300504700504601b03e00532300503f0240072d6", + "0x503e0070460470472ce01b03e00532300503e00502501b046005323005", + "0x2400531d01b01b32300501b00701b02007d02302400502007d023024323", + "0x1b22301b32100532300501b31b01b01b3230050070052f301b01b323005", + "0x532300531f32100732401b31f00532300531f00502501b31f005323005", + "0x516801b31b00532300531e31d00702d01b31d00532300501b00901b31e", + "0x532300504400503101b04500532300504500504601b31a00532300531b", + "0x532300501b4c401b31a04404502400531a00532300531a00516a01b044", + "0x4c701b0400410073230050420054c601b0420053230050430054c501b043", + "0x532300519300504301b1930053230050400054c801b01b323005041005", + "0x4c901b03f00532300503f00502501b03e0460073230050460052cd01b03f", + "0x732b01b07d00532300507d00502501b07d02300732300503e03f007024", + "0x531f0054cc01b31f0053230053210054cb01b32102000732300507d01b", + "0x1b31b00532300531d0054cf01b01b32300531e0054ce01b31d31e007323", + "0x250052b901b02531a00732300531a0054d101b31a00532300531b0054d0", + "0x2d00900732300500900503901b00900532300501b03701b324005323005", + "0x2000504601b0230053230050230050af01b02d00532300502d00503601b", + "0xb00245cd31703102802432300732402d02400504721301b020005323005", + "0x19231a0074d401b19200532300501b4d301b01b32300501b00701b1f507c", + "0x900532300500900503601b02800532300502800503101b037005323005", + "0x2804721301b31700532300531700502501b0370053230050370050cb01b", + "0x1b32300501b00701b21521320d0245ce036038039024323007037009031", + "0x52170054c601b2170053230052160054c501b21600532300501b4c401b", + "0x1b21f00532300521e0054c801b01b32300521b0054c701b21e21b007323", + "0x2220230244c901b22200532300522200502501b22200532300521f005043", + "0x522502000732b01b22500532300522500502501b225223007323005046", + "0x532300522c0052b901b22c04b00732300504b0054d101b04b229007323", + "0x503901b05100532300501b03701b0500053230050453170072b301b053", + "0x32300505400503601b03900532300503900503101b054051007323005051", + "0xaf01b03600532300503600502501b05000532300505000502501b054005", + "0x5403803904620d01b22900532300522900504601b223005323005223005", + "0x4d301b01b32300501b00701b0580562510245cf24f243007323007050053", + "0x50440360072b301b05500532300505704b0074d401b05700532300501b", + "0x1b05100532300505100503601b24300532300524300503101b2c6005323", + "0x24f24304620d01b2c60053230052c600502501b0550053230050550050cb", + "0x1b01b32300501b00701b2ef0600330245d02d32c90073230072c6055051", + "0x506200517001b06200532300506304700724501b06300532300501b03f", + "0x1b2c90053230052c900503101b22900532300522900504601b306005323", + "0x530600516a01b2d30053230052d300531701b2230053230052230050af", + "0x470052f301b01b32300501b00701b3062d32232c9229046005306005323", + "0x1b06a00532300506000531701b00600532300503300503101b01b323005", + "0x1b01b32300501b00701b01b5d100501b19301b06c0053230052ef00521f", + "0x1b32300503600531d01b01b32300504b00532a01b01b3230050470052f3", + "0x32300525100503101b01b32300504400531d01b01b32300505100522201b", + "0x901b06c00532300505800521f01b06a00532300505600531701b006005", + "0x32300506f00516801b06f00532300506c30700702d01b30700532300501b", + "0xaf01b00600532300500600503101b22900532300522900504601b070005", + "0x32300507000516a01b06a00532300506a00531701b223005323005223005", + "0x504500531d01b01b32300501b00701b07006a223006229046005070005", + "0x4600531d01b01b32300531700531d01b01b3230050470052f301b01b323", + "0x31701b07200532300520d00503101b01b32300504400531d01b01b323005", + "0x1b5d200501b19301b03400532300521500521f01b305005323005213005", + "0x1b3230050470052f301b01b32300504500531d01b01b32300501b00701b", + "0x32300504400531d01b01b32300504600531d01b01b32300500900522201b", + "0x7c00531701b0720053230050b000503101b01b32300531a00532a01b01b", + "0x1b07700532300501b00901b0340053230051f500521f01b305005323005", + "0x2000504601b07400532300530200516801b30200532300503407700702d", + "0x230053230050230050af01b07200532300507200503101b020005323005", + "0x7202004600507400532300507400516a01b30500532300530500531701b", + "0x4702400732300700700504501b00700532300500500502401b074305023", + "0x504301b04500532300504700504401b01b32300501b00701b0460055d3", + "0x532300502400504101b04300532300504400504201b044005323005045", + "0x32300501b00701b01b5d400501b19301b04100532300504300504001b042", + "0x4600504101b19300532300504000503e01b04000532300501b03f01b01b", + "0x3f00532300704100502301b04100532300519300504001b042005323005", + "0x55d607d02300732300704200504501b01b32300501b00701b03e0055d5", + "0x502300504101b32100532300507d00505801b01b32300501b00701b020", + "0x1b00701b01b5d700501b19301b31e00532300532100505701b31f005323", + "0x4101b31b00532300531d00505501b31d00532300501b03f01b01b323005", + "0x32300731e0052c601b31e00532300531b00505701b31f005323005020005", + "0x1b32400532300531a00504401b01b32300501b00701b0250055d831a005", + "0x901b00729a01b00900532300500900502501b009005323005324005043", + "0x2d00504601b01b32300501b00701b0b03170310245d902802d007323007", + "0x501b00701b1920055da1f507c00732300731f00504501b02d005323005", + "0x5701b03900532300507c00504101b0370053230051f500505801b01b323", + "0x3f01b01b32300501b00701b01b5db00501b19301b038005323005037005", + "0x532300519200504101b20d00532300503600505501b03600532300501b", + "0x2150055dc2130053230070380052c601b03800532300520d00505701b039", + "0x32300521600504301b21600532300521300504401b01b32300501b00701b", + "0x21e21b00732300721702d00729a01b21700532300521700502501b217005", + "0x22500532300521e0280074d501b01b32300501b00701b22322221f0245dd", + "0x3900504101b04b00532300521b00504601b2290053230052250054d601b", + "0x701b01b5de00501b19301b0530053230052290054d801b22c005323005", + "0x28601b01b32300522300528601b01b32300522200528601b01b32300501b", + "0x1b01b5df00501b19301b05000532300521f00504601b01b323005028005", + "0x1b01b32300502800528601b01b32300521500522501b01b32300501b007", + "0x3230050510054d901b05100532300501b03f01b05000532300502d005046", + "0x4d801b22c00532300503900504101b04b00532300505000527101b054005", + "0x28601b01b32300501b00701b01b5de00501b19301b053005323005054005", + "0x24300532300503100504601b01b3230050b000528601b01b323005317005", + "0x1b01b32300502500522501b01b32300501b00701b01b5e000501b19301b", + "0x32300524f0054d901b24f00532300501b03f01b24300532300501b005046", + "0x4d801b22c00532300531f00504101b04b00532300524300527101b251005", + "0x3230070530054da01b05600532300522c00521701b053005323005251005", + "0x5500532300505803f0074dc01b01b32300501b00701b0570055e1058005", + "0x560052c901b04b00532300504b00504601b2c60053230050550054dd01b", + "0x1b00701b2c605604b0240052c60053230052c60054de01b056005323005", + "0x4601b2c90053230050570054df01b01b32300503f00531d01b01b323005", + "0x3230052c90054de01b0560053230050560052c901b04b00532300504b005", + "0x532300504200521701b01b32300501b00701b2c905604b0240052c9005", + "0x52c901b01b00532300501b00504601b03300532300503e0054df01b2d3", + "0x3b501b0332d301b0240050330053230050330054de01b2d30053230052d3", + "0x3230050420054c501b04200532300501b4c401b043044007323005045005", + "0x4c801b01b3230050400054c701b1930400073230050410054c601b041005", + "0x3230050440052cd01b03e00532300503f00504301b03f005323005193005", + "0x732300502303e0240244c901b03e00532300503e00502501b023044007", + "0x31f32100732300502001b00732b01b02000532300502000502501b02007d", + "0x54ce01b31b31d00732300531e0054cc01b31e00532300531f0054cb01b", + "0x2500532300531a0054d001b31a00532300531b0054cf01b01b32300531d", + "0x1b03701b0090053230053240052b901b3240250073230050250054d101b", + "0x532300502800503601b02802d00732300502d00503901b02d005323005", + "0x4721301b32100532300532100504601b07d00532300507d0050af01b028", + "0x32300501b00701b1921f507c0245e20b0317031024323007009028047005", + "0x503101b0390053230050370250074d401b03700532300501b4d301b01b", + "0x53230050390050cb01b02d00532300502d00503601b031005323005031", + "0x3802432300703902d31703104721301b0b00053230050b000502501b039", + "0x532300503800503101b01b32300501b00701b2162152130245e320d036", + "0x729a01b20d00532300520d00502501b03600532300503600531701b038", + "0x29a01b01b32300501b00701b22221f21e0245e421b2170073230070b0321", + "0x1b01b32300501b00701b22c04b2290245e522522300732300720d217007", + "0x24305405104732300505321b0070244e001b0500530073230050430050b6", + "0x52430050bb01b01b32300524f00528601b01b32300505400528601b24f", + "0x5800528601b0550570580560473230050502250510244e001b251005323", + "0x4c401b2c60053230050570050bb01b01b32300505500528601b01b323005", + "0x73230052d30054c601b2d30053230052c90054c501b2c900532300501b", + "0x504301b2ef0053230050600054c801b01b3230050330054c701b060033", + "0x504406307d0244c901b06300532300506300502501b0630053230052ef", + "0x732300530622300732b01b30600532300530600502501b306062007323", + "0x1b30700532300506c0052b901b06c06a00732300506a0054d101b06a006", + "0x507000503601b07006f00732300506f00503901b06f00532300501b037", + "0x1b05600532300505600509f01b25100532300525100502501b070005323", + "0x500600504601b0620053230050620050af01b2c60053230052c6005025", + "0x770340245e630507200732300725130707003603804620d01b006005323", + "0x507406a0074d401b07400532300501b4d301b01b32300501b00701b302", + "0x1b06f00532300506f00503601b07200532300507200503101b073005323", + "0x7507b0073230072c607306f30507204620d01b0730053230050730050cb", + "0x24501b2fd00532300501b03f01b01b32300501b00701b2fe2ff3000245e7", + "0x500600504601b2fb0053230052fc00517001b2fc0053230052fd046007", + "0x1b05600532300505600509f01b07b00532300507b00503101b006005323", + "0x52fb00516a01b07500532300507500531701b0620053230050620050af", + "0x52f301b01b32300501b00701b2fb07506205607b0060450052fb005323", + "0x2f60053230052ff00531701b2fa00532300530000503101b01b323005046", + "0x1b32300501b00701b01b5e800501b19301b0880053230052fe00521f01b", + "0x32300506a00532a01b01b3230052c600531d01b01b3230050460052f301b", + "0x7700531701b2fa00532300503400503101b01b32300506f00522201b01b", + "0x1b2f500532300501b00901b08800532300530200521f01b2f6005323005", + "0x600504601b0860053230052f400516801b2f40053230050882f500702d", + "0x5600532300505600509f01b2fa0053230052fa00503101b006005323005", + "0x8600516a01b2f60053230052f600531701b0620053230050620050af01b", + "0x28601b01b32300501b00701b0862f60620562fa006045005086005323005", + "0x1b01b3230050460052f301b01b32300522c00528601b01b32300504b005", + "0x1b32300521b00528601b01b32300504400531d01b01b3230050430050b7", + "0x3230052f200502501b2f200532300501b05401b2f300532300501b31b01b", + "0x2d01b2f100532300501b00901b0840053230052f22f300732401b2f2005", + "0x522900504601b07f0053230052f000516801b2f00053230050842f1007", + "0x1b00700532300500700509f01b03800532300503800503101b229005323", + "0x507f00516a01b03600532300503600531701b07d00532300507d0050af", + "0x528601b01b32300501b00701b07f03607d00703822904500507f005323", + "0xb701b01b3230050460052f301b01b32300522200528601b01b32300521f", + "0x1b01b32300520d00531d01b01b32300504400531d01b01b323005043005", + "0x532300532c00502501b32c00532300501b05401b08900532300501b31b", + "0x702d01b2eb00532300501b00901b2ec00532300532c08900732401b32c", + "0x32300521e00504601b2e90053230052ea00516801b2ea0053230052ec2eb", + "0xaf01b00700532300500700509f01b03800532300503800503101b21e005", + "0x3230052e900516a01b03600532300503600531701b07d00532300507d005", + "0xb000531d01b01b32300501b00701b2e903607d00703821e0450052e9005", + "0x531d01b01b3230050430050b701b01b3230050460052f301b01b323005", + "0x2e700532300521500531701b2e800532300521300503101b01b323005044", + "0x1b32300501b00701b01b5e900501b19301b2e600532300521600521f01b", + "0x3230050430050b701b01b3230050460052f301b01b32300502d00522201b", + "0x507c00503101b01b32300502500532a01b01b32300504400531d01b01b", + "0x1b2e600532300519200521f01b2e70053230051f500531701b2e8005323", + "0x52e400516801b2e40053230052e62e500702d01b2e500532300501b009", + "0x1b2e80053230052e800503101b32100532300532100504601b2e3005323", + "0x52e700531701b07d00532300507d0050af01b00700532300500700509f", + "0x1b2e32e707d0072e83210450052e30053230052e300516a01b2e7005323", + "0x532300504600502501b04500532300501b4e201b04600532300501b4e1", + "0x1b5ea0440053230070450460074e301b04500532300504500502501b046", + "0x3230050440054e501b0440053230050440054e401b01b32300501b00701b", + "0x4200502501b04100532300501b4e601b04200532300501b32901b043005", + "0x53230070410420074e301b04100532300504100502501b042005323005", + "0x54e501b0400053230050400054e401b01b32300501b00701b01b5eb040", + "0x32300703f0054e801b03f1930073230051930054e701b193005323005040", + "0x4e901b0230053230050050052c501b01b32300501b00701b03e0055ec01b", + "0x4ea01b01b32300501b00701b01b5ed00501b19301b07d005323005193005", + "0x1b32100532300501b4ec01b02000532300501b4eb01b01b323005193005", + "0x1b31e31f00732300503e3210200050474ed01b321005323005321005025", + "0x731e0054ef01b31f00532300531f0052c501b31e00532300531e0054ee", + "0x1b31b00532300531d0054e501b01b32300501b00701b01b5ee31d005323", + "0x5ed00501b19301b07d00532300531b0054e901b02300532300531f0052c5", + "0x32300531f0052c501b31a00532300501b4f001b01b32300501b00701b01b", + "0x1b02507d00732300507d0054e701b07d00532300531a0054e901b023005", + "0x507d0054ea01b01b32300501b00701b3240055ef01b3230070250054e8", + "0x501b00701b01b5f000501b19301b0090053230050430054e901b01b323", + "0x4f101b01b32300501b00701b02d0055f101b3230070430054e801b01b323", + "0x1b01b5f000501b19301b00900532300507d0054e901b01b323005324005", + "0x1b02800532300501b4eb01b01b32300507d0054ea01b01b32300501b007", + "0x310074f201b0310053230050310054ee01b0310053230053240280074f2", + "0x53230073170054ef01b3170053230053170054ee01b31700532300502d", + "0x54e901b07c0053230050b00054e501b01b32300501b00701b01b5f20b0", + "0x1b4f001b01b32300501b00701b01b5f000501b19301b00900532300507c", + "0x5f301b3230070090054e801b0090053230051f50054e901b1f5005323005", + "0x32300501b31b01b01b3230050470052f301b01b32300501b00701b192005", + "0x732401b03900532300503900502501b03900532300501b05401b037005", + "0x32300503803600702d01b03600532300501b00901b038005323005039037", + "0x2c501b01b00532300501b00504601b21300532300520d00516801b20d005", + "0x32300502400531701b00700532300500700503101b023005323005023005", + "0x1b00701b21302400702301b04600521300532300521300516a01b024005", + "0x1b21700532300501b4f401b2162150073230051920054f301b01b323005", + "0x501b03701b21e00532300521b0052b901b21b2170073230052170054d1", + "0x22200532300522200503601b22221f00732300521f00503901b21f005323", + "0x22300732300721521e22202400704620d01b21e00532300521e0050cb01b", + "0x1b05300532300501b4d301b01b32300501b00701b22c04b2290245f4225", + "0x22300503101b0500053230050532170074d401b2170053230052170054f5", + "0x500053230050500050cb01b21f00532300521f00503601b223005323005", + "0x701b25124f2430245f505405100732300721605021f22522304620d01b", + "0x5800532300505604700724501b05600532300501b03f01b01b32300501b", + "0x230052c501b01b00532300501b00504601b05700532300505800517001b", + "0x5400532300505400531701b05100532300505100503101b023005323005", + "0x32300501b00701b05705405102301b04600505700532300505700516a01b", + "0x24f00531701b05500532300524300503101b01b3230050470052f301b01b", + "0x701b01b5f600501b19301b2c900532300525100521f01b2c6005323005", + "0x32a01b01b32300521600531d01b01b3230050470052f301b01b32300501b", + "0x5500532300522900503101b01b32300521f00522201b01b323005217005", + "0x501b00901b2c900532300522c00521f01b2c600532300504b00531701b", + "0x6000532300503300516801b0330053230052c92d300702d01b2d3005323", + "0x5500503101b0230053230050230052c501b01b00532300501b00504601b", + "0x6000532300506000516a01b2c60053230052c600531701b055005323005", + "0x1b3230050470052f301b01b32300501b00701b0602c605502301b046005", + "0x532300501b05401b2ef00532300501b31b01b01b3230050430054ea01b", + "0x901b0620053230050632ef00732401b06300532300506300502501b063", + "0x32300500600516801b00600532300506230600702d01b30600532300501b", + "0x3101b0050053230050050052c501b01b00532300501b00504601b06a005", + "0x32300506a00516a01b02400532300502400531701b007005323005007005", + "0x50470052f301b01b32300501b00701b06a02400700501b04600506a005", + "0x30700502501b30700532300501b05401b06c00532300501b31b01b01b323", + "0x7000532300501b00901b06f00532300530706c00732401b307005323005", + "0x504601b30500532300507200516801b07200532300506f07000702d01b", + "0x532300500700503101b0050053230050050052c501b01b00532300501b", + "0x1b04600530500532300530500516a01b02400532300502400531701b007", + "0x400410420245f70430440450243230070240050070ff01b305024007005", + "0x32300504300510001b04300532300504300510101b01b32300501b00701b", + "0x32300503f00532801b02007d02303e03f0463230051930050fe01b193005", + "0x502000531d01b01b32300507d00506301b01b32300502300506301b01b", + "0x4c401b32100532300503e00511501b03e00532300503e00527c01b01b323", + "0x732300531e0054c601b31e00532300531f0054c501b31f00532300501b", + "0x504301b31a00532300531b0054c801b01b32300531d0054c701b31b31d", + "0x32300502500502501b3240460073230050460052cd01b02500532300531a", + "0x532300502d00502501b02d0090073230053240250070244c901b025005", + "0x1b3170053230050310054cb01b03102800732300502d01b00732b01b02d", + "0x507c0054cf01b01b3230050b00054ce01b07c0b00073230053170054cc", + "0x371920073230051920054d101b1920053230051f50054d001b1f5005323", + "0x503800503901b03800532300501b03701b0390053230050370052b901b", + "0x3600532300503600503601b04500532300504500503101b036038007323", + "0x2800504601b0090053230050090050af01b32100532300532100508401b", + "0x2160245f821521320d02432300703903604404504721301b028005323005", + "0x21e1920074d401b21e00532300501b4d301b01b32300501b00701b21b217", + "0x3800532300503800503601b20d00532300520d00503101b21f005323005", + "0x20d04721301b21500532300521500502501b21f00532300521f0050cb01b", + "0x1b32300501b00701b22c04b2290245f922522322202432300721f038213", + "0x2c92c605505705805625124f24305405105005303f32300532100527701b", + "0x32300505100528601b01b32300505000506301b01b32300505300531d01b", + "0x525100531d01b01b32300524f00531d01b01b32300524300531d01b01b", + "0x5700522c01b01b32300505800528601b01b3230050560050f701b01b323", + "0x522c01b01b3230052c600522201b01b32300505500522201b01b323005", + "0x3305400732300505400511b01b2d300532300501b03701b01b3230052c9", + "0x22200503101b2d30053230052d300503601b06000532300503300502401b", + "0x22500532300522500502501b22300532300522300531701b222005323005", + "0x1b32300501b00701b0620055fa0632ef0073230072d306002802424801b", + "0x501b4f601b30600532300506300504401b06300532300506300524701b", + "0x1b00600532300500600503601b06a00532300505400502401b006005323", + "0x55fb30706c00732300700606a2ef02424801b306005323005306005025", + "0x530700504401b30700532300530700524701b01b32300501b00701b06f", + "0x4c601b3050053230050720054c501b07200532300501b4c401b070005323", + "0x3230050770054c801b01b3230050340054c701b077034007323005305005", + "0x4c901b07400532300507400502501b07400532300530200504301b302005", + "0x732b01b07b00532300507b00502501b07b073007323005046074009024", + "0x2ff0052b901b2ff3000073230053000054d101b30007500732300507b06c", + "0x53230052fd2150072b301b2fd00532300530600504301b2fe005323005", + "0x503601b2fa2fb0073230052fb00503901b2fb00532300501b03701b2fc", + "0x532300507000502501b2fc0053230052fc00502501b2fa0053230052fa", + "0x4620d01b07500532300507500504601b0730053230050730050af01b070", + "0x32300501b00701b0862f42f50245fc0882f60073230072fc2fe2fa223222", + "0x504301b2f20053230052f33000074d401b2f300532300501b4d301b01b", + "0x3230052f600503101b2f10053230050842250072b301b084005323005070", + "0x2501b2f20053230052f20050cb01b2fb0053230052fb00503601b2f6005", + "0x5fd07f2f00073230072f12f22fb0882f604620d01b2f10053230052f1005", + "0x724501b2eb00532300501b03f01b01b32300501b00701b2ec32c089024", + "0x32300507500504601b2e90053230052ea00517001b2ea0053230052eb047", + "0x31701b0730053230050730050af01b2f00053230052f000503101b075005", + "0x7f0732f00750460052e90053230052e900516a01b07f00532300507f005", + "0x32300508900503101b01b3230050470052f301b01b32300501b00701b2e9", + "0x19301b2e60053230052ec00521f01b2e700532300532c00531701b2e8005", + "0x532a01b01b3230050470052f301b01b32300501b00701b01b5fe00501b", + "0x31d01b01b3230052fb00522201b01b32300507000531d01b01b323005300", + "0x53230052f400531701b2e80053230052f500503101b01b323005225005", + "0x2e500702d01b2e500532300501b00901b2e600532300508600521f01b2e7", + "0x532300507500504601b2e30053230052e400516801b2e40053230052e6", + "0x531701b0730053230050730050af01b2e80053230052e800503101b075", + "0x2e32e70732e80750460052e30053230052e300516a01b2e70053230052e7", + "0x1b3230050470052f301b01b32300521500531d01b01b32300501b00701b", + "0x32300522500531d01b01b32300530600531d01b01b32300504600531d01b", + "0x52e100502501b2e100532300501b17301b2e200532300501b31b01b01b", + "0x1b07e00532300501b00901b2df0053230052e12e200732401b2e1005323", + "0x6f00504601b08f00532300508d00516801b08d0053230052df07e00702d", + "0x90053230050090050af01b22200532300522200503101b06f005323005", + "0x22206f04600508f00532300508f00516a01b22300532300522300531701b", + "0x470052f301b01b32300521500531d01b01b32300501b00701b08f223009", + "0x531d01b01b32300505400522c01b01b32300504600531d01b01b323005", + "0x2501b09200532300501b17301b2de00532300501b31b01b01b323005225", + "0x32300501b00901b2dd0053230050922de00732401b092005323005092005", + "0x1b2dc00532300508700516801b0870053230052dd09000702d01b090005", + "0x50090050af01b22200532300522200503101b062005323005062005046", + "0x52dc0053230052dc00516a01b22300532300522300531701b009005323", + "0x1b01b32300521500531d01b01b32300501b00701b2dc223009222062046", + "0x1b32300532100508801b01b32300504600531d01b01b3230050470052f3", + "0x22c00521f01b09800532300504b00531701b2da00532300522900503101b", + "0x3800522201b01b32300501b00701b01b5ff00501b19301b2d9005323005", + "0x508801b01b32300504600531d01b01b3230050470052f301b01b323005", + "0x1b2da00532300521600503101b01b32300519200532a01b01b323005321", + "0x32300501b00901b2d900532300521b00521f01b098005323005217005317", + "0x1b2d800532300509b00516801b09b0053230052d909f00702d01b09f005", + "0x50090050af01b2da0053230052da00503101b028005323005028005046", + "0x52d80053230052d800516a01b09800532300509800531701b009005323", + "0x1b01b3230050470052f301b01b32300501b00701b2d80980092da028046", + "0x3230050402d600702d01b2d600532300501b00901b01b32300504600531d", + "0x3101b01b00532300501b00504601b2d40053230050a300516801b0a3005", + "0x32300504100531701b0070053230050070050af01b042005323005042005", + "0x1b4f701b2d404100704201b0460052d40053230052d400516a01b041005", + "0x4fc01b04000532300501b4fa01b04200532300501b4f901b044005323005", + "0x1b4fd01b01b32300501b02001b01b32300501b24f01b03f00532300501b", + "0x4fe01b07d00532300501b4fe01b02300532300501b4fe01b03e005323005", + "0x32100550001b32100532300502007d02303e0474ff01b02000532300501b", + "0x1b32300501b00701b01b60031f00532300732100550101b321005323005", + "0x31b00550401b31b00532300501b50301b31d31e00732300502400550201b", + "0x1b32400532300502500550401b02500532300501b4fe01b31a005323005", + "0x532300501b4fe01b02d00532300500900550401b00900532300501b4fe", + "0x31700532300503102d32431a04750501b03100532300502800550401b028", + "0x31e0050c401b31700532300531700550701b31d00532300531d00550601b", + "0x501b00701b07c0056010b000532300731731d00750801b31e005323005", + "0x4000550901b01b3230050460052f301b01b3230050b000532701b01b323", + "0x550c01b01b32300504400550b01b01b32300504200550a01b01b323005", + "0x50d01b1f500532300501b31b01b01b32300531f00532601b01b32300503f", + "0x3230051921f500732401b19200532300519200502501b19200532300501b", + "0x732401b03900532300503900502501b03900532300501b05001b037005", + "0x532300503600502501b03600532300501b50e01b038005323005039037", + "0x502501b21300532300501b50f01b20d00532300503603800732401b036", + "0x532300501b00901b21500532300521320d00732401b213005323005213", + "0x4601b21b00532300521700516801b21700532300521521600702d01b216", + "0x3230050070050c501b0050053230050050052be01b01b00532300501b005", + "0x16a01b04700532300504700503101b31e00532300531e0050c401b007005", + "0x1b32300501b00701b21b04731e00700501b04500521b00532300521b005", + "0x32300501b4fe01b21f00532300521e00550401b21e00532300501b51001b", + "0x550401b22500532300501b4fe01b22300532300522200550401b222005", + "0x22c00532300504b00550401b04b00532300501b4fe01b229005323005225", + "0x1b05300532300505300550701b05300532300522c22922321f04750501b", + "0x1b51101b01b32300501b00701b05100560205000532300705307c007508", + "0x51301b24f00532300501b51201b24300532300501b32d01b054005323005", + "0x5400700504451501b24f00532300524f00551401b243005323005243005", + "0x501b00701b05505705805604760325119304502432300724f24331f050", + "0x751801b01b32300501b04701b2c92c600732300525100551601b01b323", + "0x72c900551b01b19300532300519303f00751901b045005323005045044", + "0x600053230072d300551c01b01b32300501b00701b0330056042d3005323", + "0x6200560606300532300706000551d01b01b32300501b00701b2ef005605", + "0x32300530600551f01b30600532300506300551e01b01b32300501b00701b", + "0x32300506200551f01b01b32300501b00701b01b60700501b19301b006005", + "0x3230052ef00551f01b01b32300501b00701b01b60700501b19301b006005", + "0x32300503300551f01b01b32300501b00701b01b60700501b19301b006005", + "0x552001b04100532300500631e00732501b01b32300501b02001b006005", + "0x30700532300501b51001b01b32300506a00552101b06c06a0073230052c6", + "0x532300501b4fe01b07000532300501b4fe01b06f00532300501b4fe01b", + "0x3400732300530500552001b30500532300507207006f30704752201b072", + "0x7700552301b06c00532300506c00552301b01b32300503400552101b077", + "0x32300504104000752501b30200532300507706c00752401b077005323005", + "0x1b01b32300501b00701b07300560807400532300730200512001b041005", + "0x7b00532300501b52601b01b3230050460052f301b01b323005074005225", + "0x532300501b52701b30000532300501b03701b07500532300501b05001b", + "0x4601b2fd00532300530007507b02452901b2fe00532300501b52801b2ff", + "0x3230052ff00502501b2fd0053230052fd00552a01b01b00532300501b005", + "0x73230052fe2ff2fd01b04752b01b2fe0053230052fe00503601b2ff005", + "0x1b01b32300501b00701b2f60056092fa0053230072fb00552c01b2fb2fc", + "0x32300501b52e01b01b3230052f500522501b2f50880073230052fa00552d", + "0x552a01b2fc0053230052fc00504601b08600532300501b52801b2f4005", + "0x532300508600503601b2f40053230052f400502501b088005323005088", + "0x53230072f200552c01b2f22f30073230050862f40882fc04752b01b086", + "0x1b07f2f000732300508400552d01b01b32300501b00701b2f100560a084", + "0x32c00532300501b52801b08900532300501b52f01b01b32300507f005225", + "0x8900502501b2f00053230052f000552a01b2f30053230052f300504601b", + "0x532c0892f02f304752b01b32c00532300532c00503601b089005323005", + "0x32300501b00701b2e900560b2ea0053230072eb00552c01b2eb2ec007323", + "0x1b53001b01b3230052e700522501b2e72e80073230052ea00552d01b01b", + "0x1b2ec0053230052ec00504601b2e500532300501b53101b2e6005323005", + "0x52e500503601b2e60053230052e600502501b2e80053230052e800552a", + "0x72e300552c01b2e32e40073230052e52e62e82ec04752b01b2e5005323", + "0x1b2df00532300501b31b01b01b32300501b00701b2e100560c2e2005323", + "0x507e2df00732401b07e00532300507e00502501b07e00532300501b50d", + "0x1b01b32300508f00522501b08f0430073230052e200552d01b08d005323", + "0x553401b0922de00732300504300553301b043005323005043042007532", + "0x243230052dd00553601b2dd09200732300509200553501b01b3230052de", + "0x553701b01b3230052dc00522201b01b32300508700531d01b2dc087090", + "0x32300509800553901b0980053230052da00553801b2da090007323005090", + "0x1b09f0053230052d908d00732401b2d90053230052d900502501b2d9005", + "0x504700503101b2e40053230052e400504601b09b00532300509000553a", + "0x1b09f00532300509f00521f01b09b00532300509b00553b01b047005323", + "0x53e01b01b32300501b04701b0a32d62d802432300509f09b0472e404753d", + "0x52d400532f01b01b32300501b00701b0a500560d2d40053230070a3005", + "0xaa09200732300509200553501b01b3230052d200522501b2d20a7007323", + "0x522201b01b3230052cf00554001b2cd2ce2cf0243230050aa00553601b", + "0x53230052cc0a700732401b2cc0053230052ce00504301b01b3230052cd", + "0x31d01b01b3230050af00554001b2c82ca0af02432300509200553601b2cb", + "0x53230052c700553901b2c70053230052c800512c01b01b3230052ca005", + "0x19301b3b30053230053b200521f01b3b20053230050492cb00732401b049", + "0x517501b01b32300509200554101b01b32300501b00701b01b60e00501b", + "0x53230050cd00521f01b01b3230053b400524401b0cd3b40073230050a5", + "0x53b33b500702d01b3b500532300501b00901b01b32300501b02001b3b3", + "0x1b2d80053230052d800504601b0b60053230050b700516801b0b7005323", + "0x50410050c401b1930053230051930050c501b0450053230050450052be", + "0x50b60053230050b600516a01b2d60053230052d600503101b041005323", + "0x1b32300504200550a01b01b32300501b00701b0b62d60411930452d8045", + "0x450052be01b2e40053230052e400504601b0b90053230052e100516801b", + "0x410053230050410050c401b1930053230051930050c501b045005323005", + "0x452e40450050b90053230050b900516a01b04700532300504700503101b", + "0x516801b01b32300504200550a01b01b32300501b00701b0b9047041193", + "0x53230050450052be01b2ec0053230052ec00504601b0bb0053230052e9", + "0x503101b0410053230050410050c401b1930053230051930050c501b045", + "0x470411930452ec0450050bb0053230050bb00516a01b047005323005047", + "0x3230052f100516801b01b32300504200550a01b01b32300501b00701b0bb", + "0xc501b0450053230050450052be01b2f30053230052f300504601b0bf005", + "0x32300504700503101b0410053230050410050c401b193005323005193005", + "0x701b0bf0470411930452f30450050bf0053230050bf00516a01b047005", + "0x1b2c50053230052f600516801b01b32300504200550a01b01b32300501b", + "0x51930050c501b0450053230050450052be01b2fc0053230052fc005046", + "0x1b04700532300504700503101b0410053230050410050c401b193005323", + "0x32300501b00701b2c50470411930452fc0450052c50053230052c500516a", + "0x32300501b03f01b01b32300504200550a01b01b32300507300522501b01b", + "0x1b42a0053230052d500517001b2d500532300541b04600724501b41b005", + "0x51930050c501b0450053230050450052be01b01b00532300501b005046", + "0x1b04700532300504700503101b0410053230050410050c401b193005323", + "0x32300501b00701b42a04704119304501b04500542a00532300542a00516a", + "0x504000550901b01b3230050460052f301b01b32300505700554201b01b", + "0x3f00550c01b01b32300504400550b01b01b32300504200550a01b01b323", + "0x502501b0c400532300501b54401b2bf00532300501b31b01b01b323005", + "0x532300501b32d01b2be0053230050c42bf00732401b0c40053230050c4", + "0xc500551301b0580053230050580050c501b42f00532300501b51201b0c5", + "0x42f0c505505831e04633001b42f00532300542f00551401b0c5005323005", + "0x560053230050560052be01b01b32300501b04701b2ba2bb2bc024323005", + "0x2bb0050c501b2bc0053230052bc0050c401b2be0053230052be00521f01b", + "0x32300501b00701b2b300560f2b90053230072ba00551b01b2bb005323005", + "0x51d01b01b32300501b00701b2b00056100cb0053230072b900551c01b01b", + "0x52ae00551e01b01b32300501b00701b0c20056112ae0053230070cb005", + "0x1b00701b01b61200501b19301b0cc0053230052b100551f01b2b1005323", + "0x1b00701b01b61200501b19301b0cc0053230050c200551f01b01b323005", + "0x1b00701b01b61200501b19301b0cc0053230052b000551f01b01b323005", + "0x732501b01b32300501b02001b0cc0053230052b300551f01b01b323005", + "0x3230052be2ab00702d01b2ab00532300501b00901b2b80053230050cc2bc", + "0x2be01b01b00532300501b00504601b2a90053230052aa00516801b2aa005", + "0x3230052b80050c401b2bb0053230052bb0050c501b056005323005056005", + "0x450052a90053230052a900516a01b04700532300504700503101b2b8005", + "0x1b01b32300505100554501b01b32300501b00701b2a90472b82bb05601b", + "0x1b32300504200550a01b01b32300504000550901b01b3230050460052f3", + "0x32300531f00532601b01b32300503f00550c01b01b32300504400550b01b", + "0x52b700502501b2b700532300501b50d01b0d000532300501b31b01b01b", + "0x1b2b400532300501b05101b0d20053230052b70d000732401b2b7005323", + "0x501b54601b2b50053230052b40d200732401b2b40053230052b4005025", + "0x2b60053230050d42b500732401b0d40053230050d400502501b0d4005323", + "0x2a82b600732401b2a80053230052a800502501b2a800532300501b05001b", + "0x1b2a20053230052a200502501b2a200532300501b05001b2a0005323005", + "0x29d29c00702d01b29c00532300501b00901b29d0053230052a22a0007324", + "0x1b00532300501b00504601b29a0053230050da00516801b0da005323005", + "0x31e0050c401b0070053230050070050c501b0050053230050050052be01b", + "0x29a00532300529a00516a01b04700532300504700503101b31e005323005", + "0x3230050460052f301b01b32300501b00701b29a04731e00700501b045005", + "0x504400550b01b01b32300504200550a01b01b32300504000550901b01b", + "0x501b05401b29800532300501b31b01b01b32300503f00550c01b01b323", + "0xde00532300529729800732401b29700532300529700502501b297005323", + "0x29300516801b2930053230050de29500702d01b29500532300501b00901b", + "0x50053230050050052be01b01b00532300501b00504601b0df005323005", + "0x4700503101b0240053230050240050c401b0070053230050070050c501b", + "0xdf04702400700501b0450050df0053230050df00516a01b047005323005", + "0x2400550401b02400532300501b50301b00700500732300501b00554701b", + "0x1b04500532300504600550401b04600532300501b4fe01b047005323005", + "0x532300501b4fe01b04300532300504400550401b04400532300501b4fe", + "0x4000532300504104304504704750501b04100532300504200550401b042", + "0x50050c401b04000532300504000550701b00700532300500700554901b", + "0x501b00701b03f00561319300532300704000700754a01b005005323005", + "0x32300501b00701b01b61400501b19301b01b32300519300554b01b01b323", + "0x503e00512a01b03e00532300501b03f01b01b32300503f00554d01b01b", + "0x1b0050053230050050050c401b07d00532300502300526b01b023005323", + "0x1b00700532300500500502401b07d00500700507d00532300507d00526a", + "0x505801b01b32300501b00701b046005615047024007323007007005045", + "0x532300504500505701b04400532300502400504101b045005323005047", + "0x4200532300501b03f01b01b32300501b00701b01b61600501b19301b043", + "0x4100505701b04400532300504600504101b04100532300504200505501b", + "0x532300504000521701b0400440073230050440052a901b043005323005", + "0x4401b01b32300501b00701b03e00561703f0053230070430052c601b193", + "0x32300507d00502501b07d00532300502300504301b02300532300503f005", + "0x32300501b00701b31f00561832102000732300707d01b0070f101b07d005", + "0x50440052a901b31e00532300501b03701b01b32300519300522c01b01b", + "0x532300531e00503601b31b32100732300532100503901b31d044007323", + "0x501b00701b32400561902531a00732300731b31e31d02004754e01b31e", + "0x1b02d00532300500900501801b0090440073230050440052a901b01b323", + "0x2500504101b02d00532300502d00503601b028321007323005321005039", + "0x1b07c0b000761a31703100732300702802d31a0241d201b025005323005", + "0x3700561b1921f500732300731732104403104754e01b01b32300501b007", + "0x32300503900554f01b03900532300502500521701b01b32300501b00701b", + "0x1b20d00532300503803600755101b03600532300519200521701b038005", + "0x521300555401b1f50053230051f500504601b21300532300520d005552", + "0x1b32300502500532101b01b32300501b00701b2131f5007005213005323", + "0x32300521600502501b21600532300501b17301b21500532300501b31b01b", + "0x2d01b21b00532300501b00901b21700532300521621500732401b216005", + "0x503700504601b21f00532300521e00555501b21e00532300521721b007", + "0x32300501b00701b21f03700700521f00532300521f00555401b037005323", + "0x504400532101b01b32300502500532101b01b32300507c00522201b01b", + "0x501b33301b22200532300501b31b01b01b32300532100522201b01b323", + "0x22500532300522322200732401b22300532300522300502501b223005323", + "0x4b00555501b04b00532300522522900702d01b22900532300501b00901b", + "0x22c00532300522c00555401b0b00053230050b000504601b22c005323005", + "0x532101b01b32300532100522201b01b32300501b00701b22c0b0007005", + "0x2501b05000532300501b17301b05300532300501b31b01b01b323005044", + "0x32300501b00901b05100532300505005300732401b050005323005050005", + "0x1b24f00532300524300555501b24300532300505105400702d01b054005", + "0x1b24f32400700524f00532300524f00555401b324005323005324005046", + "0x1b25100532300501b03f01b01b32300504400532101b01b32300501b007", + "0x5800555201b05800532300505619300755101b056005323005251005556", + "0x5700532300505700555401b31f00532300531f00504601b057005323005", + "0x532101b01b32300503e00522501b01b32300501b00701b05731f007005", + "0x1b2c600532300505500555601b05500532300501b03f01b01b323005044", + "0x1b00504601b2d30053230052c900555201b2c90053230052c6193007551", + "0x501b02001b2d301b0070052d30053230052d300555401b01b005323005", + "0x501b00701b04304400761c04504600732300700501b00700501b01b323", + "0x1b04600532300504600504601b0420470073230050470052cd01b01b323", + "0x504700531d01b01b32300501b00701b04100561d01b32300704200507e", + "0x1b19300532300504000700755801b04000532300502400555701b01b323", + "0x504500503101b04600532300504600504601b03f005323005193005559", + "0x501b00701b03f04504602400503f00532300503f00533401b045005323", + "0x52c901b04600532300504600504601b01b3230050410052de01b01b323", + "0x7d00555b01b07d02303e02432300500704600755a01b007005323005007", + "0x32300502002400755c01b01b32300501b00701b32100561e020005323007", + "0x4601b31d00532300531e0470072d601b31e00532300501b05101b31f005", + "0x3230050230052c901b04500532300504500503101b03e00532300503e005", + "0x29201b31d00532300531d00502501b31f00532300531f0050e301b023005", + "0x1b00701b02531a31b02400502531a31b02432300531d31f02304503e046", + "0x555d01b01b32300502400528b01b01b32300504700531d01b01b323005", + "0x32300500900555901b00900532300532402300755801b324005323005321", + "0x33401b04500532300504500503101b03e00532300503e00504601b02d005", + "0x531d01b01b32300501b00701b02d04503e02400502d00532300502d005", + "0x31b01b01b32300500700522c01b01b32300502400528b01b01b323005047", + "0x3100532300503100502501b03100532300501b22301b02800532300501b", + "0xb000702d01b0b000532300501b00901b31700532300503102800732401b", + "0x532300504400504601b1f500532300507c00555e01b07c005323005317", + "0x440240051f50053230051f500533401b04300532300504300503101b044", + "0x761f04604700732300700501b00700501b01b32300501b02001b1f5043", + "0x501b04701b04300532300500700502401b01b32300501b00701b044045", + "0x62004104200732300704300504501b04700532300504700504601b01b323", + "0x4200504101b19300532300504100505801b01b32300501b00701b040005", + "0x701b01b62100501b19301b03e00532300519300505701b03f005323005", + "0x1b07d00532300502300505501b02300532300501b03f01b01b32300501b", + "0x503f00521701b03e00532300507d00505701b03f005323005040005041", + "0x1b32300501b00701b31f00562232100532300703e0052c601b020005323", + "0x31e00502501b31d00532300502400502401b31e00532300532100504401b", + "0x501b00701b02500562331a31b00732300731d00504501b31e005323005", + "0x5701b00900532300531b00504101b32400532300531a00505801b01b323", + "0x3f01b01b32300501b00701b01b62400501b19301b02d005323005324005", + "0x532300502500504101b03100532300502800505501b02800532300501b", + "0xb000562531700532300702d0052c601b02d00532300503100505701b009", + "0x32300500900521701b07c00532300531700504401b01b32300501b00701b", + "0x2501b03700532300507c00504301b19200532300531e00504301b1f5005", + "0x503900502501b0390053230050371920072d601b037005323005037005", + "0x1b01b32300501b00701b03800562601b32300703900507e01b039005323", + "0x532300504600503101b04700532300504700504601b01b32300501b020", + "0x4727501b1f50053230051f50052c901b0200053230050200052c901b046", + "0x32300501b00701b21320d03602400521320d0360243230051f5020046047", + "0x532300501b03f01b01b3230050380052de01b01b32300501b02001b01b", + "0x1b2170053230052161f502002455f01b21600532300521500509201b215", + "0x504600503101b04700532300504700504601b21b005323005217005560", + "0x501b00701b21b04604702400521b00532300521b00556101b046005323", + "0x531e00531d01b01b3230050b000522501b01b32300501b02001b01b323", + "0x501b31b01b01b32300500900532101b01b32300502000522c01b01b323", + "0x32401b21f00532300521f00502501b21f00532300501b05401b21e005323", + "0x522222300702d01b22300532300501b00901b22200532300521f21e007", + "0x1b04700532300504700504601b22900532300522500556201b225005323", + "0x22904604702400522900532300522900556101b046005323005046005031", + "0x1b01b32300531f00522501b01b32300501b02001b01b32300501b00701b", + "0x22c02402002455f01b22c00532300504b00508d01b04b00532300501b03f", + "0x4700532300504700504601b05000532300505300556001b053005323005", + "0x4604702400505000532300505000556101b04600532300504600503101b", + "0x32300500700522c01b01b32300502400522c01b01b32300501b00701b050", + "0x505400502501b05400532300501b22301b05100532300501b31b01b01b", + "0x1b24f00532300501b00901b24300532300505405100732401b054005323", + "0x4500504601b05600532300525100556201b25100532300524324f00702d", + "0x5600532300505600556101b04400532300504400503101b045005323005", + "0x4700732300700501b00700501b01b32300501b02001b056044045024005", + "0x1b04300532300500700512601b01b32300501b00701b044045007627046", + "0x732300704300556301b04700532300504700504601b01b32300501b047", + "0x1b19300532300504100556401b01b32300501b00701b040005628041042", + "0x62900501b19301b03e00532300519300556601b03f005323005042005565", + "0x32300502300556701b02300532300501b03f01b01b32300501b00701b01b", + "0x28a01b03e00532300507d00556601b03f00532300504000556501b07d005", + "0x1b00701b31f00562a32100532300703e00556801b02000532300503f005", + "0x1b31d00532300502400512601b31e00532300532100556901b01b323005", + "0x1b02500562b31a31b00732300731d00556301b31e00532300531e00556a", + "0x532300531b00556501b32400532300531a00556401b01b32300501b007", + "0x32300501b00701b01b62c00501b19301b02d00532300532400556601b009", + "0x2500556501b03100532300502800556701b02800532300501b03f01b01b", + "0x31700532300702d00556801b02d00532300503100556601b009005323005", + "0x528a01b07c00532300531700556901b01b32300501b00701b0b000562d", + "0x32300519200556d01b19231e00732300531e00556c01b1f5005323005009", + "0x4301b01b32300503800528601b01b32300503900507001b038039037024", + "0x32300507c00556c01b07c00532300507c00556a01b036005323005037005", + "0x1b32300521500507001b21621521302432300520d00556d01b20d07c007", + "0x2170360072d601b21700532300521300504301b01b32300521600528601b", + "0x62e01b32300721b00507e01b21b00532300521b00502501b21b005323005", + "0x556d01b21f31e00732300531e00556c01b01b32300501b00701b21e005", + "0x32300522500528601b01b32300522200531d01b22522322202432300521f", + "0x56d01b04b07c00732300507c00556c01b2290053230052230052ab01b01b", + "0x505000528601b01b32300522c00531d01b05005322c02432300504b005", + "0x1b62f01b3230070512290072aa01b0510053230050530052ab01b01b323", + "0x1b32300531e00556f01b01b32300507c00556f01b01b32300501b00701b", + "0x5402432300531e00556d01b01b32300501b00701b01b63000501b19301b", + "0x24f0050b901b01b32300524300507001b01b32300505400531d01b24f243", + "0x32300505600531d01b05705805602432300507c00556d01b251005323005", + "0x25100727601b0550053230050570050b901b01b32300505800507001b01b", + "0x701b01b63000501b19301b01b32300501b00701b01b63101b323007055", + "0x3101b04700532300504700504601b01b32300501b02001b01b32300501b", + "0x3230051f500526d01b02000532300502000526d01b046005323005046005", + "0x2d32c92c60240052d32c92c60243230051f502004604704726c01b1f5005", + "0x1b32300507c00556f01b01b32300521e0052de01b01b32300501b00701b", + "0x3300532300501b03f01b01b32300501b02001b01b32300531e00556f01b", + "0x33601b2ef0053230050601f502002457001b06000532300503300509201b", + "0x32300504600503101b04700532300504700504601b0630053230052ef005", + "0x32300501b00701b06304604702400506300532300506300557201b046005", + "0x3230050200050f701b01b3230050b000522501b01b32300501b02001b01b", + "0x32300501b31b01b01b32300500900557401b01b32300531e00556f01b01b", + "0x732401b30600532300530600502501b30600532300501b05401b062005", + "0x32300500606a00702d01b06a00532300501b00901b006005323005306062", + "0x3101b04700532300504700504601b30700532300506c00557501b06c005", + "0x1b30704604702400530700532300530700557201b046005323005046005", + "0x3f01b01b32300531f00522501b01b32300501b02001b01b32300501b007", + "0x507002402002457001b07000532300506f00508d01b06f00532300501b", + "0x1b04700532300504700504601b30500532300507200533601b072005323", + "0x30504604702400530500532300530500557201b046005323005046005031", + "0x1b3230050240050f701b01b3230050070050f701b01b32300501b00701b", + "0x32300507700502501b07700532300501b22301b03400532300501b31b01b", + "0x2d01b07400532300501b00901b30200532300507703400732401b077005", + "0x504500504601b07b00532300507300557501b073005323005302074007", + "0x507b00532300507b00557201b04400532300504400503101b045005323", + "0x4604700732300700501b00700501b01b32300501b02001b07b044045024", + "0x4701b04300532300500700557601b01b32300501b00701b044045007632", + "0x4200732300704300557701b04700532300504700504601b01b32300501b", + "0x57901b19300532300504100557801b01b32300501b00701b040005633041", + "0x1b63400501b19301b03e00532300519300557a01b03f005323005042005", + "0x532300502300533501b02300532300501b03f01b01b32300501b00701b", + "0x514601b03e00532300507d00557a01b03f00532300504000557901b07d", + "0x501b00701b31f00563532100532300703e00557b01b02000532300503f", + "0x4601b31d00532300531e00557d01b31e00532300532100557c01b01b323", + "0x32300531d00514b01b02400532300502400525e01b047005323005047005", + "0x532300731a00525701b31a31b00732300531d02404702457e01b31d005", + "0x2500525601b01b32300501b02001b01b32300501b00701b324005636025", + "0x31b00532300531b00504601b01b32300502d00522501b02d009007323005", + "0x900525e01b02000532300502000515701b04600532300504600503101b", + "0x2802400531703102802432300500902004631b04725d01b009005323005", + "0x32300502000525a01b01b32300501b02001b01b32300501b00701b317031", + "0x503101b31b00532300531b00504601b0b000532300532400557f01b01b", + "0x701b0b004631b0240050b00053230050b000558001b046005323005046", + "0x1b03f01b01b32300531f00522501b01b32300501b02001b01b32300501b", + "0x3230051f500558201b1f500532300507c02402002458101b07c005323005", + "0x58001b04600532300504600503101b04700532300504700504601b192005", + "0x525a01b01b32300501b00701b192046047024005192005323005192005", + "0x22301b03700532300501b31b01b01b32300502400516001b01b323005007", + "0x32300503903700732401b03900532300503900502501b03900532300501b", + "0x57f01b20d00532300503803600702d01b03600532300501b00901b038005", + "0x32300504400503101b04500532300504500504601b21300532300520d005", + "0x32300501b02001b21304404502400521300532300521300558001b044005", + "0x63701b04400532300504500533701b04504600732300500700525501b01b", + "0x532300504300563801b04400532300504400503601b04300532300501b", + "0x1b32300504100522201b04004104202432300504304401b02463901b043", + "0x732300504700503901b01b32300501b04701b19300532300501b03701b", + "0x1b63a01b32300719303f00711901b04200532300504200504601b03f047", + "0x732300504700503901b03e00532300501b4f601b01b32300501b00701b", + "0x53101b01b32300501b00701b01b63b01b32300703e02300711901b023047", + "0x707d02000711901b02004700732300504700503901b07d00532300501b", + "0x503901b32100532300501b1d901b01b32300501b00701b01b63c01b323", + "0x501b00701b01b63d01b32300732131f00711901b31f047007323005047", + "0x11901b31d04700732300504700503901b31e00532300501b63e01b01b323", + "0x532300501b64001b01b32300501b00701b01b63f01b32300731e31d007", + "0x1b64101b32300731b31a00711901b31a04700732300504700503901b31b", + "0x732300504700503901b02500532300501b64201b01b32300501b00701b", + "0x64401b01b32300501b00701b01b64301b32300702532400711901b324047", + "0x32300501b00701b01b64501b32300700904700711901b00900532300501b", + "0x32300504000522201b01b32300504600516001b01b32300501b02001b01b", + "0x32300501b64601b02d00532300501b31b01b01b32300502400507001b01b", + "0x1b03100532300502802d00732401b02800532300502800502501b028005", + "0x50b000564701b0b000532300503131700702d01b31700532300501b009", + "0x1b00500532300500500503101b04200532300504200504601b07c005323", + "0x64801b01b32300501b00701b07c00504202400507c00532300507c005339", + "0x1b01b64900501b19301b1920053230051f500530201b1f500532300501b", + "0x1b03700532300501b64a01b01b32300504700522201b01b32300501b007", + "0x64b00501b19301b0390053230051920052ab01b192005323005037005302", + "0x532300501b64c01b01b32300504700522201b01b32300501b00701b01b", + "0x1b19301b0360053230050390052ab01b03900532300503800530201b038", + "0x501b64e01b01b32300504700522201b01b32300501b00701b01b64d005", + "0x1b2130053230050360052ab01b03600532300520d00530201b20d005323", + "0x33a01b01b32300504700522201b01b32300501b00701b01b64f00501b193", + "0x53230052130052ab01b21300532300521500530201b21500532300501b", + "0x1b32300504700522201b01b32300501b00701b01b65000501b19301b216", + "0x52160052ab01b21600532300521700530201b21700532300501b65101b", + "0x504700522201b01b32300501b00701b01b65200501b19301b21b005323", + "0x52b801b21b00532300521e00530201b21e00532300501b65301b01b323", + "0x501b00701b22200565501b32300721f00565401b21f21b00732300521b", + "0x504000522201b01b32300504600516001b01b32300501b02001b01b323", + "0x501b31b01b01b32300502400507001b01b32300521b00507001b01b323", + "0x32401b22500532300522500502501b22500532300501b05401b223005323", + "0x522904b00702d01b04b00532300501b00901b229005323005225223007", + "0x1b04200532300504200504601b05300532300522c00564701b22c005323", + "0x5300504202400505300532300505300533901b005005323005005005031", + "0x7001b05405105002432300522202404202465601b01b32300501b00701b", + "0x5625100765724f24300732300705421b0500240d201b01b323005051005", + "0x32300524f00530201b05800532300524300504601b01b32300501b00701b", + "0x1b32300501b02001b01b32300501b00701b01b65800501b19301b057005", + "0x32300504000522201b01b32300504600516001b01b32300505600507001b", + "0x52c600502501b2c600532300501b2b401b05500532300501b31b01b01b", + "0x1b2d300532300501b00901b2c90053230052c605500732401b2c6005323", + "0x25100504601b06000532300503300564701b0330053230052c92d300702d", + "0x6000532300506000533901b00500532300500500503101b251005323005", + "0x22201b01b32300502400507001b01b32300501b00701b060005251024005", + "0x5800532300504200504601b2ef00532300501b2b701b01b323005047005", + "0x504000503901b06300532300501b65901b0570053230052ef00530201b", + "0x1b32300501b00701b01b65a01b32300706306200711901b062040007323", + "0x32300501b65901b30600532300505704600713901b01b32300501b02001b", + "0x1d201b30600532300530600525e01b00600532300500600503601b006005", + "0x1b01b32300501b00701b06f30700765b06c06a007323007040006058024", + "0x530600525e01b00500532300500500503101b06a00532300506a005046", + "0x32300506c30600506a04765c01b06c00532300506c00503601b306005323", + "0x506f00522201b01b32300501b00701b305072070024005305072070024", + "0x501b33301b03400532300501b31b01b01b32300530600516001b01b323", + "0x30200532300507703400732401b07700532300507700502501b077005323", + "0x7300564701b07300532300530207400702d01b07400532300501b00901b", + "0x500532300500500503101b30700532300530700504601b07b005323005", + "0x1b01b32300501b00701b07b00530702400507b00532300507b00533901b", + "0x1b07500532300501b65d01b01b32300504000522201b01b32300501b020", + "0x765e2ff3000073230070570750580240d201b075005323005075005302", + "0x1b03f01b2fc0053230052ff04600713901b01b32300501b00701b2fd2fe", + "0x53230052fa00566001b2fa0053230052fb2fc00765f01b2fb005323005", + "0x533901b00500532300500500503101b30000532300530000504601b2f6", + "0x2fd00507001b01b32300501b00701b2f60053000240052f60053230052f6", + "0x1b2b401b08800532300501b31b01b01b32300504600516001b01b323005", + "0x53230052f508800732401b2f50053230052f500502501b2f5005323005", + "0x564701b2f30053230052f408600702d01b08600532300501b00901b2f4", + "0x532300500500503101b2fe0053230052fe00504601b2f20053230052f3", + "0x32300500500517b01b2f20052fe0240052f20053230052f200533901b005", + "0x3901b04400532300501b03701b04500532300504600566101b046047007", + "0x4404300711901b04500532300504500503601b043024007323005024005", + "0x3901b04200532300501b4f601b01b32300501b00701b01b66201b323007", + "0x1b00701b01b66301b32300704204100711901b041024007323005024005", + "0x1b19302400732300502400503901b04000532300501b53101b01b323005", + "0x32300501b66501b01b32300501b00701b01b66401b323007040193007119", + "0x3f00563801b02300532300501b66701b03e00532300501b66601b03f005", + "0x32100532300502300503601b02000532300503e00503601b07d005323005", + "0x1b31f00532300501b66901b01b32300501b00701b01b66800501b19301b", + "0x532300531f00563801b31d00532300501b66b01b31e00532300501b66a", + "0x566c01b32100532300531d00503601b02000532300531e00503601b07d", + "0x532300532100512c01b31a00532300502000512c01b31b00532300507d", + "0x32400532300501b66e01b01b32300501b00701b01b66d00501b19301b025", + "0x32300532400563801b02d00532300501b67001b00900532300501b66f01b", + "0x63901b02500532300502d00503601b31a00532300500900503601b31b005", + "0x767101b01b32300503100522201b31703102802432300531b00701b024", + "0x70b002800733c01b0b00053230050b000530201b0b000532300531a317", + "0x70251f507c02467301b01b32300501b00701b1920056721f507c007323", + "0x503904700717a01b01b32300501b00701b036038007674039037007323", + "0x1b21500532300520d00524201b21300532300503700504601b20d005323", + "0x22201b01b32300503600522201b01b32300501b00701b01b67500501b193", + "0x1b01b32300504700523e01b01b32300502400522201b01b323005045005", + "0x532300521700502501b21700532300501b67601b21600532300501b31b", + "0x702d01b21e00532300501b00901b21b00532300521721600732401b217", + "0x32300503800504601b22200532300521f00567701b21f00532300521b21e", + "0x1b32300501b00701b22203800700522200532300522200567801b038005", + "0x32300504700523e01b01b32300502400522201b01b32300504500522201b", + "0x32300501b67901b22300532300501b31b01b01b32300502500522201b01b", + "0x1b22900532300522522300732401b22500532300522500502501b225005", + "0x522c00567701b22c00532300522904b00702d01b04b00532300501b009", + "0x505300532300505300567801b19200532300519200504601b053005323", + "0x501b67a01b01b32300500700522201b01b32300501b00701b053192007", + "0x5100532300505004700717a01b05000532300505000503601b050005323", + "0x21500517b01b21500532300505100524201b21300532300501b00504601b", + "0x25100532300501b4f601b24f00532300524300566101b243054007323005", + "0x21302467301b25100532300525100503601b24f00532300524f00503601b", + "0x1b67c01b01b32300501b00701b05505700767b05805600732300725124f", + "0x3230052c605805602463901b2c60053230052c600563801b2c6005323005", + "0x1b06000532300503300553901b01b3230052d300522201b0332d32c9024", + "0x50602ef0072d601b2ef0053230052ef00502501b2ef00532300501b67d", + "0x1b06300532300506300502501b05400532300505400524201b063005323", + "0x30604500767101b30600532300501b67e01b06200532300506305400733b", + "0x73230070062c900733c01b00600532300500600530201b006005323005", + "0x67101b06f00532300501b68001b01b32300501b00701b30700567f06c06a", + "0x7006a00733c01b07000532300507000530201b07000532300506f024007", + "0x30506c07202467301b01b32300501b00701b034005681305072007323007", + "0x30206200717a01b01b32300501b00701b073074007682302077007323007", + "0x30000532300507507b00768301b07500532300501b03f01b07b005323005", + "0x2ff00567801b07700532300507700504601b2ff00532300530000568401b", + "0x32300507300522201b01b32300501b00701b2ff0770070052ff005323005", + "0x32300501b67601b2fe00532300501b31b01b01b32300506200523e01b01b", + "0x1b2fc0053230052fd2fe00732401b2fd0053230052fd00502501b2fd005", + "0x52fa00567701b2fa0053230052fc2fb00702d01b2fb00532300501b009", + "0x52f60053230052f600567801b07400532300507400504601b2f6005323", + "0x6c00522201b01b32300506200523e01b01b32300501b00701b2f6074007", + "0x502501b2f500532300501b67901b08800532300501b31b01b01b323005", + "0x532300501b00901b2f40053230052f508800732401b2f50053230052f5", + "0x4601b2f20053230052f300567701b2f30053230052f408600702d01b086", + "0x701b2f20340070052f20053230052f200567801b034005323005034005", + "0x31b01b01b32300502400522201b01b32300506200523e01b01b32300501b", + "0x2f10053230052f100502501b2f100532300501b67901b08400532300501b", + "0x7f00702d01b07f00532300501b00901b2f00053230052f108400732401b", + "0x532300530700504601b32c00532300508900567701b0890053230052f0", + "0x1b01b32300501b00701b32c30700700532c00532300532c00567801b307", + "0x1b32300502400522201b01b32300504500522201b01b323005055005222", + "0x532300501b67601b2ec00532300501b31b01b01b32300505400523e01b", + "0x901b2ea0053230052eb2ec00732401b2eb0053230052eb00502501b2eb", + "0x3230052e800567701b2e80053230052ea2e900702d01b2e900532300501b", + "0x70052e70053230052e700567801b05700532300505700504601b2e7005", + "0x768504504600732300700501b00700501b01b32300501b02001b2e7057", + "0x501b04701b04200532300502400568601b01b32300501b00701b043044", + "0x1b00701b03e03f00768819304004102432300704204600768701b01b323", + "0x1b07d00532300504100504601b02300532300519300568901b01b323005", + "0x68b00501b19301b32100532300502300533d01b02000532300504000568a", + "0x32300531f00568c01b31f00532300501b03f01b01b32300501b00701b01b", + "0x33d01b02000532300503e00568a01b07d00532300503f00504601b31e005", + "0x32300732100568d01b31d00532300502000518701b32100532300531e005", + "0x568f01b01b32300501b02001b01b32300501b00701b31a00568e31b005", + "0x2469102d00932402432300702504700704504769001b02500532300531b", + "0x503101b07d00532300507d00504601b01b32300501b00701b317031028", + "0x532300531d00524b01b00900532300500900531701b324005323005324", + "0x4732300502d31d00932407d04623901b02d00532300502d00524a01b31d", + "0x31d00523801b01b32300501b00701b1921f507c0b00470051921f507c0b0", + "0x1b03900532300531703700702d01b03700532300501b00901b01b323005", + "0x502800503101b07d00532300507d00504601b038005323005039005692", + "0x503800532300503800569301b03100532300503100531701b028005323", + "0x522501b01b32300501b02001b01b32300501b00701b03803102807d047", + "0x532300503604731d02469401b03600532300501b03f01b01b32300531a", + "0x503101b07d00532300507d00504601b21300532300520d00569501b20d", + "0x532300521300569301b00700532300500700531701b045005323005045", + "0x1b32300504700569601b01b32300501b00701b21300704507d047005213", + "0x532300501b22301b21500532300501b31b01b01b32300502400523801b", + "0x901b21700532300521621500732401b21600532300521600502501b216", + "0x32300521e00569201b21e00532300521721b00702d01b21b00532300501b", + "0x31701b04300532300504300503101b04400532300504400504601b21f005", + "0x21f00704304404700521f00532300521f00569301b007005323005007005", + "0x504400569801b04404600732300504600569701b01b32300501b02001b", + "0x4000732300504300521401b01b3230050410052dd01b041042043024323", + "0x524d01b02303e00732300503f00521401b03f00532300501b23301b193", + "0x732300507d00516401b07d19300732300519300521901b01b32300503e", + "0x16401b31f02300732300502300521901b01b32300532100528601b321020", + "0x3230050200050b901b01b32300531d00528601b31d31e00732300531f005", + "0x1b69901b32300731a31b00727601b31a00532300531e0050b901b31b005", + "0x1b32300519300524d01b01b32300502300524d01b01b32300501b00701b", + "0x2500732300519300516401b01b32300501b00701b01b69a00501b19301b", + "0x528601b02d00900732300502300516401b01b32300502500528601b324", + "0x3100532300502d0050b901b0280053230053240050b901b01b323005009", + "0x4000516401b01b32300501b00701b01b69b01b32300703102800727601b", + "0x1f500732300507c00516401b07c00532300501b69c01b0b0317007323005", + "0x1b03919200732300519200569d01b0370b00073230050b000569d01b192", + "0x769f03603800732300703903701b02469e01b039005323005039005165", + "0x503800504601b01b32300503600528601b01b32300501b00701b21320d", + "0x1b01b32300501b00701b01b6a001b3230071920b000727601b038005323", + "0x1b3230050460056a201b01b3230050450056a101b01b32300504200524d", + "0x32300531700528601b01b3230051f500528601b01b32300504700524d01b", + "0x32300501b00701b01b6a300501b19301b21500532300503800504601b01b", + "0x2172160073230071f531703802469e01b1f50053230051f500516501b01b", + "0x524d01b01b32300521700528601b01b32300501b00701b21e21b0076a4", + "0x24d01b01b3230050460056a201b01b3230050450056a101b01b323005042", + "0x1b01b6a300501b19301b21500532300521600504601b01b323005047005", + "0x21f00532300521b00504601b01b32300521e00528601b01b32300501b007", + "0x1b01b32300521300528601b01b32300501b00701b01b6a500501b19301b", + "0x1b32300531700528601b01b3230051f500528601b01b3230050b0005286", + "0x504200521401b21f00532300520d00504601b01b32300519200528601b", + "0x4b22900732300522500521401b22500532300501b23301b223222007323", + "0x22c00516401b22c22300732300522300521901b01b32300522900524d01b", + "0x4b00732300504b00521901b01b32300505000528601b050053007323005", + "0x50b901b01b32300524300528601b24305400732300505100516401b051", + "0x1b01b32300501b04701b2510053230050540050b901b24f005323005053", + "0x504b00524d01b01b32300501b00701b01b6a601b32300725124f007276", + "0x32300501b00701b01b6a700501b19301b01b32300522300524d01b01b323", + "0x516401b01b32300505600528601b05805600732300522300516401b01b", + "0x53230050580050b901b01b32300505700528601b05505700732300504b", + "0x1b01b6a801b3230072c92c600727601b2c90053230050550050b901b2c6", + "0x332d300732300522200516401b01b32300501b02001b01b32300501b007", + "0x3300569d01b0632ef00732300506000516401b06000532300501b69c01b", + "0x32300530600516501b30606300732300506300569d01b062033007323005", + "0x1b00701b30706c0076a906a00600732300730606221f02469e01b306005", + "0x27601b00600532300500600504601b01b32300506a00528601b01b323005", + "0x3230050450056a101b01b32300501b00701b01b6aa01b323007063033007", + "0x52ef00528601b01b32300504700524d01b01b3230050460056a201b01b", + "0x1b19301b06f00532300500600504601b01b3230052d300528601b01b323", + "0x2469e01b2ef0053230052ef00516501b01b32300501b00701b01b6ab005", + "0x28601b01b32300501b00701b0343050076ac0720700073230072ef2d3006", + "0x1b01b3230050460056a201b01b3230050450056a101b01b323005072005", + "0x1b6ab00501b19301b06f00532300507000504601b01b32300504700524d", + "0x532300530500504601b01b32300503400528601b01b32300501b00701b", + "0x1b32300530700528601b01b32300501b00701b01b6ad00501b19301b077", + "0x3230052d300528601b01b3230052ef00528601b01b32300503300528601b", + "0x500503101b07700532300506c00504601b01b32300506300528601b01b", + "0x4700532300504700514b01b02400532300502400531701b005005323005", + "0x3020473230050460470240050770466ae01b04600532300504600517c01b", + "0x1b32300501b00701b3000056b007500532300707b0056af01b07b073074", + "0x1b2fd0056b22fe0053230072ff00522401b2ff0053230050750056b101b", + "0x532300507400503101b30200532300530200504601b01b32300501b007", + "0x56b301b07300532300507300531701b00700532300500700509f01b074", + "0x2f62fa2fb2fc0463230052fe07300707430204633f01b2fe0053230052fe", + "0x6b601b01b32300501b00701b2f40056b52f50053230070880056b401b088", + "0x52f30056a101b2f22f30073230050450056b701b0860053230052f5005", + "0x6b801b01b3230050840056a101b2f10840073230050860056b701b01b323", + "0x3230052f000504301b07f0053230052f10056b801b2f00053230052f2005", + "0x1b2ec00532300532c0890072d601b32c00532300507f00504301b089005", + "0x1b00701b2eb0056b901b3230072ec00507e01b2ec0053230052ec005025", + "0x6bb01b2e90053230052ea0056ba01b2ea00532300501b03f01b01b323005", + "0x3230052fc00504601b2e70053230052e80056bc01b2e80053230052e9005", + "0x31701b2fa0053230052fa00509f01b2fb0053230052fb00503101b2fc005", + "0x2f62fa2fb2fc0460052e70053230052e70056bd01b2f60053230052f6005", + "0x532300501b6be01b01b3230052eb0052de01b01b32300501b00701b2e7", + "0x56bc01b2e40053230052e50056bb01b2e50053230052e60056bf01b2e6", + "0x53230052fb00503101b2fc0053230052fc00504601b2e30053230052e4", + "0x56bd01b2f60053230052f600531701b2fa0053230052fa00509f01b2fb", + "0x6a101b01b32300501b00701b2e32f62fa2fb2fc0460052e30053230052e3", + "0x53230052fc00504601b2e20053230052f40056c001b01b323005045005", + "0x531701b2fa0053230052fa00509f01b2fb0053230052fb00503101b2fc", + "0x2e22f62fa2fb2fc0460052e20053230052e20056bd01b2f60053230052f6", + "0x1b3230050450056a101b01b3230052fd00522501b01b32300501b00701b", + "0x3230052df00502501b2df00532300501b05401b2e100532300501b31b01b", + "0x2d01b08d00532300501b00901b07e0053230052df2e100732401b2df005", + "0x530200504601b2de00532300508f0056c001b08f00532300507e08d007", + "0x1b00700532300500700509f01b07400532300507400503101b302005323", + "0x70743020460052de0053230052de0056bd01b073005323005073005317", + "0x53000056c001b01b3230050450056a101b01b32300501b00701b2de073", + "0x1b07400532300507400503101b30200532300530200504601b092005323", + "0x50920056bd01b07300532300507300531701b00700532300500700509f", + "0x501b02001b01b32300501b00701b092073007074302046005092005323", + "0x4700524d01b01b3230050460056a201b01b3230050450056a101b01b323", + "0x6c101b06f00532300521f00504601b01b32300522200524d01b01b323005", + "0x53230050900056bb01b0900053230052dd0056bf01b2dd00532300501b", + "0x509f01b00500532300500500503101b2dc0053230050870056bc01b087", + "0x53230052dc0056bd01b02400532300502400531701b007005323005007", + "0x32300504200524d01b01b32300501b00701b2dc02400700506f0460052dc", + "0x504700524d01b01b3230050460056a201b01b3230050450056a101b01b", + "0x1b6c101b21500532300501b00504601b01b32300504000524d01b01b323", + "0x2d90053230050980056bb01b0980053230052da0056bf01b2da005323005", + "0x700509f01b00500532300500500503101b09f0053230052d90056bc01b", + "0x9f00532300509f0056bd01b02400532300502400531701b007005323005", + "0x4400521401b04404700732300504700521901b09f024007005215046005", + "0x4000732300504100521401b04100532300501b23301b042043007323005", + "0x516401b03f04200732300504200521901b01b32300504000524d01b193", + "0x732300519300521901b01b32300502300528601b02303e00732300503f", + "0xb901b01b32300532100528601b32102000732300507d00516401b07d193", + "0x731e31f00727601b31e0053230050200050b901b31f00532300503e005", + "0x524d01b01b32300519300524d01b01b32300501b00701b01b6c201b323", + "0x4200516401b01b32300501b00701b01b6c300501b19301b01b323005042", + "0x31a00732300519300516401b01b32300531d00528601b31b31d007323005", + "0x250050b901b32400532300531b0050b901b01b32300531a00528601b025", + "0x1b32300501b00701b01b6c401b32300700932400727601b009005323005", + "0x3100516401b03100532300501b6c501b02802d00732300504300516401b", + "0x3230050b000569d01b07c02800732300502800569d01b0b0317007323005", + "0x73230071f507c01b02469e01b1f50053230051f500516501b1f50b0007", + "0x1b01b32300503700528601b01b32300501b00701b0380390076c6037192", + "0x1b00701b01b6c701b3230070b002800727601b192005323005192005046", + "0x524d01b01b3230050450051bb01b01b32300504700524d01b01b323005", + "0x28601b01b32300531700528601b01b32300504600524d01b01b323005024", + "0x1b01b6c800501b19301b03600532300519200504601b01b32300502d005", + "0x731702d19202469e01b31700532300531700516501b01b32300501b007", + "0x32300521300528601b01b32300501b00701b2162150076c921320d007323", + "0x502400524d01b01b3230050450051bb01b01b32300504700524d01b01b", + "0x1b19301b03600532300520d00504601b01b32300504600524d01b01b323", + "0x21500504601b01b32300521600528601b01b32300501b00701b01b6c8005", + "0x3800528601b01b32300501b00701b01b6ca00501b19301b217005323005", + "0x528601b01b32300531700528601b01b32300502800528601b01b323005", + "0x1b21700532300503900504601b01b3230050b000528601b01b32300502d", + "0x1b23301b21f21e00732300521b00521401b21b046007323005046005219", + "0x1b32300522300524d01b22522300732300522200521401b222005323005", + "0x28601b22c04b00732300522900516401b22921f00732300521f00521901b", + "0x32300505300516401b05322500732300522500521901b01b32300522c005", + "0xb901b05400532300504b0050b901b01b32300505100528601b051050007", + "0x501b00701b01b6cb01b32300724305400727601b243005323005050005", + "0x501b19301b01b32300521f00524d01b01b32300522500524d01b01b323", + "0x528601b25124f00732300521f00516401b01b32300501b00701b01b6cc", + "0x1b32300505600528601b05805600732300522500516401b01b32300524f", + "0x5700727601b0550053230050580050b901b0570053230052510050b901b", + "0x2c600732300521e00516401b01b32300501b00701b01b6cd01b323007055", + "0x569d01b0600330073230052d300516401b2d300532300501b6c501b2c9", + "0x506300516501b06306000732300506000569d01b2ef2c90073230052c9", + "0x701b06a0060076ce3060620073230070632ef21702469e01b063005323", + "0x1b06200532300506200504601b01b32300530600528601b01b32300501b", + "0x503300528601b01b32300501b00701b01b6cf01b3230070602c9007276", + "0x6c00509201b06c00532300501b03f01b01b3230052c600528601b01b323", + "0x7000532300530700508f01b06f00532300506200504601b307005323005", + "0x3300532300503300516501b01b32300501b00701b01b6d000501b19301b", + "0x32300501b00701b0770340076d13050720073230070332c606202469e01b", + "0x530200509201b30200532300501b03f01b01b32300530500528601b01b", + "0x1b07000532300507400508f01b06f00532300507200504601b074005323", + "0x3f01b01b32300507700528601b01b32300501b00701b01b6d000501b193", + "0x532300503400504601b07b00532300507300508d01b07300532300501b", + "0x32300501b00701b01b6d000501b19301b07000532300507b00508f01b06f", + "0x503300528601b01b3230052c900528601b01b32300506a00528601b01b", + "0x501b03f01b01b32300506000528601b01b3230052c600528601b01b323", + "0x1b06f00532300500600504601b30000532300507500508d01b075005323", + "0x1b01b32300501b00701b01b6d000501b19301b07000532300530000508f", + "0x53230052ff00509201b2ff00532300501b03f01b01b32300521e00524d", + "0x509001b0700053230052fe00508f01b06f00532300521700504601b2fe", + "0x53230072fd00512001b2fd0053230052fd00508f01b2fd005323005070", + "0x1b6d301b01b3230052fc00522501b01b32300501b00701b2fb0056d22fc", + "0x53230052f60056d501b2f62fa0073230052fa0056d401b2fa005323005", + "0x7f2f02f10842f22f30862f42f50880413230072f604606f0246d601b2f6", + "0x2eb00532300507f0880076d801b01b32300501b00701b2ec32c0890246d7", + "0x6d801b2e90053230052f12ea0076d801b2ea0053230052f02eb0076d801b", + "0x2e70076d801b2e70053230052f22e80076d801b2e80053230050842e9007", + "0x52f42e50076d801b2e50053230050862e60076d801b2e60053230052f3", + "0x1b2e40053230052e400504601b2e30053230052f50056d901b2e4005323", + "0x2e200514b01b2e22e30073230052e300521901b02400532300502400514b", + "0x52fa0056d401b2df2e10073230052e20242e40246da01b2e2005323005", + "0x32300507e2df2e10246db01b07e00532300507e0056d501b07e2fa007323", + "0x8d0076d801b01b32300508f0056dc01b2dc0870902dd0922de08f08d043", + "0x50900980076d801b0980053230050872da0076d801b2da0053230052dc", + "0x532300509209f0076d801b09f0053230052dd2d90076d801b2d9005323", + "0x14b01b2d804700732300504700521901b09b00532300509b00504601b09b", + "0x2e32d809b0246da01b2e30053230052e300514b01b2d80053230052d8005", + "0x52fa0a32d60246db01b2fa0053230052fa0056d501b0a32d6007323005", + "0x76d801b01b3230050a50056dc01b2cd2ce2cf0aa2d20a70a52d4043323", + "0x2cf2cb0076d801b2cb0053230052ce2cc0076d801b2cc0053230052cd2d4", + "0x3230052d22ca0076d801b2ca0053230050aa0af0076d801b0af005323005", + "0x2c700514b01b04900532300501b6de01b2c700532300501b6dd01b2c8005", + "0x2c80053230052c800504601b04900532300504900514b01b2c7005323005", + "0x701b0b73b50cd0246df3b43b33b20243230070492c70070050471fb01b", + "0x3b20053230053b200503101b3b40053230053b40051b901b01b32300501b", + "0x1b0b90056e00b60053230073b40051f601b3b30053230053b300531701b", + "0x246e22c50bf0bb0243230072de0b63b33b20476e101b01b32300501b007", + "0x51e301b0bb0053230050bb00503101b01b32300501b00701b42a2d541b", + "0x246e32be0c42bf0243230070a70450bf0bb0476e101b2c50053230052c5", + "0x51e301b2bf0053230052bf00503101b01b32300501b00701b2bc42f0c5", + "0x246e52b92ba2bb0243230072be2c50c42bf0476e401b2be0053230052be", + "0x51e301b2bb0053230052bb00503101b01b32300501b00701b2b00cb2b3", + "0x246e60cc2b10c22ae0473230072b92ba2bb0241ed01b2b90053230052b9", + "0x2b100521401b01b3230050cc00524d01b01b32300501b00701b2aa2ab2b8", + "0x2b700732300504700521401b01b3230052a900524d01b0d02a9007323005", + "0xd000521901b0d00053230050d000514b01b01b3230052b700524d01b0d2", + "0x3230050d400528601b0d42b50073230052b400516401b2b40d0007323005", + "0x1b2a02a80073230052b600516401b2b60d20073230050d200521901b01b", + "0x3230052a80050b901b2a20053230052b50050b901b01b3230052a0005286", + "0x27601b0c20053230050c200531701b2ae0053230052ae00503101b29d005", + "0x3230050d200524d01b01b32300501b00701b01b6e701b32300729d2a2007", + "0x529c00509201b29c00532300501b03f01b01b3230050d000524d01b01b", + "0x1b00701b01b6e800501b19301b29a0053230050da00508f01b0da005323", + "0x1b01b32300529800528601b2972980073230050d000516401b01b323005", + "0x52970050b901b01b3230050de00528601b2950de0073230050d2005164", + "0x6e901b3230070df29300727601b0df0053230052950050b901b293005323", + "0x3230050e300509201b0e300532300501b03f01b01b32300501b00701b01b", + "0x501b00701b01b6e800501b19301b29a00532300529200508f01b292005", + "0x508f01b28e00532300528f00508d01b28f00532300501b03f01b01b323", + "0x532300528d0056eb01b28d00532300529a0056ea01b29a00532300528e", + "0x531701b2ae0053230052ae00503101b2c80053230052c800504601b28c", + "0x1b28c0c22ae2c804700528c00532300528c0056ec01b0c20053230050c2", + "0x1b28b00532300501b00901b01b32300504700524d01b01b32300501b007", + "0x2c800504601b28700532300528a0056ed01b28a0053230052aa28b00702d", + "0x2ab0053230052ab00531701b2b80053230052b800503101b2c8005323005", + "0x1b32300501b00701b2872ab2b82c80470052870053230052870056ec01b", + "0x52b00eb00702d01b0eb00532300501b00901b01b32300504700524d01b", + "0x1b2c80053230052c800504601b2860053230050ed0056ed01b0ed005323", + "0x52860056ec01b0cb0053230050cb00531701b2b30053230052b3005031", + "0x504700524d01b01b32300501b00701b2860cb2b32c8047005286005323", + "0x28500702d01b28500532300501b00901b01b3230052c50051bb01b01b323", + "0x53230052c800504601b0ef0053230052840056ed01b2840053230052bc", + "0x56ec01b42f00532300542f00531701b0c50053230050c500503101b2c8", + "0x524d01b01b32300501b00701b0ef42f0c52c80470050ef0053230050ef", + "0x901b01b3230050a700524d01b01b3230050450051bb01b01b323005047", + "0x3230050f00056ed01b0f000532300542a0f100702d01b0f100532300501b", + "0x31701b41b00532300541b00503101b2c80053230052c800504601b0ee005", + "0xee2d541b2c80470050ee0053230050ee0056ec01b2d50053230052d5005", + "0x1b32300504700524d01b01b3230050b900522501b01b32300501b00701b", + "0x3230052de00524d01b01b3230050a700524d01b01b3230050450051bb01b", + "0x528200502501b28200532300501b05401b28300532300501b31b01b01b", + "0xf90053230053b200503101b0f700532300528228300732401b282005323", + "0x501b19301b0f60053230050f700521f01b0f80053230053b300531701b", + "0x50450051bb01b01b32300504700524d01b01b32300501b00701b01b6ee", + "0xcd00503101b01b3230052de00524d01b01b3230050a700524d01b01b323", + "0xf60053230050b700521f01b0f80053230053b500531701b0f9005323005", + "0x2800056ed01b2800053230050f628100702d01b28100532300501b00901b", + "0xf90053230050f900503101b2c80053230052c800504601b0ff005323005", + "0xf92c80470050ff0053230050ff0056ec01b0f80053230050f800531701b", + "0x50450051bb01b01b32300504700524d01b01b32300501b00701b0ff0f8", + "0x890076d801b01b3230052fa0056ef01b01b32300502400524d01b01b323", + "0x532300501b31b01b10000532300532c1010076d801b1010053230052ec", + "0xfe00732401b27e00532300527e00502501b27e00532300501b05401b0fe", + "0x532300527d10700702d01b10700532300501b00901b27d00532300527e", + "0x503101b10000532300510000504601b1080053230051090056ed01b109", + "0x53230051080056ec01b00700532300500700531701b005005323005005", + "0x1b3230052fb00522501b01b32300501b00701b108007005100047005108", + "0x32300502400524d01b01b3230050450051bb01b01b32300504700524d01b", + "0x501b19301b10600532300506f00504601b01b32300504600524d01b01b", + "0x50450051bb01b01b32300504700524d01b01b32300501b00701b01b6f0", + "0x4300524d01b01b32300504600524d01b01b32300502400524d01b01b323", + "0x1b10600532300503600527101b03600532300501b00504601b01b323005", + "0x3230051130056ea01b11300532300527c00509201b27c00532300501b03f", + "0x31701b00500532300500500503101b10e00532300510f0056eb01b10f005", + "0x10e00700510604700510e00532300510e0056ec01b007005323005007005", + "0x450460470240473230050070056f201b00701b00732300501b0056f101b", + "0x3230050450056f301b01b3230050460056f301b01b3230050470056f301b", + "0x56f101b0430053230050440056f401b04400532300502400534101b01b", + "0x56f301b03f1930400410473230050420056f201b042005007323005005", + "0x34101b01b32300503f0056f301b01b3230051930056f301b01b323005040", + "0x50230430072d601b02300532300503e0056f401b03e005323005041005", + "0x56f501b32300707d00507e01b07d00532300507d00502501b07d005323", + "0x3210056f201b32101b00732300501b0056f101b01b32300501b00701b020", + "0x32300531d0056f301b01b32300531f0056f301b31b31d31e31f047323005", + "0x31a0056f401b31a00532300531e00534101b01b32300531b0056f301b01b", + "0x473230053240056f201b3240050073230050050056f101b025005323005", + "0x6f301b01b3230050280056f301b01b3230050090056f301b03102802d009", + "0x53230053170056f401b31700532300502d00534101b01b323005031005", + "0x7e01b07c00532300507c00502501b07c0053230050b00250072d601b0b0", + "0x32300501b0056f101b01b32300501b00701b1f50056f601b32300707c005", + "0x3230050370056f301b0360380390370473230051920056f201b19201b007", + "0x503800534101b01b3230050360056f301b01b3230050390056f301b01b", + "0x2150050073230050050056f101b21300532300520d0056f401b20d005323", + "0x6f301b01b3230052160056f301b21e21b2172160473230052150056f201b", + "0x21f00532300521b00534101b01b32300521e0056f301b01b323005217005", + "0x502501b2230053230052222130072d601b22200532300521f0056f401b", + "0x32300501b00701b2250056f701b32300722300507e01b223005323005223", + "0x1b01b3230052290056f301b05322c04b22904732300501b0056f201b01b", + "0x532300505300534101b01b32300522c0056f301b01b32300504b0056f3", + "0x25124f2430540473230050050056f201b0510053230050500056f401b050", + "0x32300524f0056f301b01b3230052430056f301b01b3230050540056f301b", + "0x72d601b0580053230050560056f401b05600532300525100534101b01b", + "0x32300705700507e01b05700532300505700502501b057005323005058051", + "0x508d01b2c600532300501b03f01b01b32300501b00701b0550056f801b", + "0x501b00701b2c90050052c90053230052c900508f01b2c90053230052c6", + "0x2d300509201b2d300532300501b03f01b01b3230050550052de01b01b323", + "0x32300501b00701b03300500503300532300503300508f01b033005323005", + "0x501b00552101b01b32300500500552101b01b3230052250052de01b01b", + "0x3230051f50052de01b01b32300501b00701b01b6f900501b19301b01b323", + "0x6f900501b19301b01b32300501b00552101b01b32300500500552101b01b", + "0x32300500500552101b01b3230050200052de01b01b32300501b00701b01b", + "0x506000509201b06000532300501b03f01b01b32300501b00552101b01b", + "0x532300501b03701b2ef0050052ef0053230052ef00508f01b2ef005323", + "0x1b6fa01b32300704704600711901b04602400732300502400503901b047", + "0x4300503901b0430440450243230050050056fb01b01b32300501b00701b", + "0x4104201b02467301b04102400732300502400503901b042043007323005", + "0x32300501b52801b01b32300501b00701b03e03f0076fc193040007323007", + "0x1b02300532300502300503601b07d19300732300519300503901b023005", + "0x1b32300501b00701b31e31f0076fd32102000732300702307d0400241d2", + "0x32300519300503901b31d00532300501b52801b01b32300532100522201b", + "0x6fe01b32300731d31b00711901b02000532300502000504601b31b193007", + "0x532300501b52801b01b32300502400522201b01b32300501b00701b01b", + "0x32402500732300731a1930200241d201b31a00532300531a00503601b31a", + "0x503901b02800532300501b65901b01b32300501b00701b02d0090076ff", + "0x702803100711901b02500532300502500504601b031324007323005324", + "0x503901b31700532300501b65901b01b32300501b00701b01b70001b323", + "0x3170b00250241d201b31700532300531700503601b0b0324007323005324", + "0x51f500522201b01b32300501b00701b0371920077011f507c007323007", + "0x1b00701b21320d03602470203803900732300700707c00729a01b01b323", + "0x16501b21600532300503900504601b21500532300501b14d01b01b323005", + "0x1b70300501b19301b21b00532300521500516501b217005323005038005", + "0x32300521300516501b21600532300503600504601b01b32300501b00701b", + "0x503901b21e00532300501b65901b21b00532300520d00516501b217005", + "0x21e21f2160241d201b21e00532300521e00503601b21f324007323005324", + "0x522200504601b01b32300501b00701b229225007704223222007323007", + "0x4b00732300522322200770501b22300532300522300503601b222005323", + "0x70801b01b32300501b00701b05000570705300532300722c00570601b22c", + "0x501b00701b05400570a01b32300705100570901b051005323005053005", + "0x4300522201b01b32300532400522201b01b32300504500534001b01b323", + "0x528601b01b32300504400531d01b01b32300521700528601b01b323005", + "0x2501b24f00532300501b05401b24300532300501b31b01b01b32300521b", + "0x504b00504601b25100532300524f24300732401b24f00532300524f005", + "0x1b00701b01b70b00501b19301b05800532300525100521f01b056005323", + "0x52c60050bb01b2c605505702432300505421b04b02420601b01b323005", + "0x1b0330053230050550050bb01b2d30053230052170050bb01b2c9005323", + "0x506000503601b2ef04300732300504300503901b06000532300501b528", + "0x701b00630600770c0620630073230072ef0600570241d201b060005323", + "0x6c00532300506a2c900720201b06a00532300501b20301b01b32300501b", + "0x1b65901b3070053230052d306c0072b301b06c00532300506c00502501b", + "0x532300506f00503601b07006200732300506200503901b06f005323005", + "0x30507200732300706f0700630241d201b30700532300530700502501b06f", + "0x1b65901b01b32300530500522201b01b32300501b00701b07703400770d", + "0x3230073020620720241d201b30200532300530200503601b302005323005", + "0x532300507400504601b01b32300501b00701b07507b00770e073074007", + "0x1b2ff30000732300507307400770501b07300532300507300503601b074", + "0x2fe00570801b01b32300501b00701b2fd00570f2fe0053230072ff005706", + "0x1b2fa00532300501b20301b2fb0053230052fc0050bb01b2fc005323005", + "0x2f600502501b08800532300530000504601b2f60053230052fa2fb007202", + "0x4500534001b01b32300501b00701b01b71000501b19301b2f5005323005", + "0x531d01b01b32300504300522201b01b32300532400522201b01b323005", + "0x17501b01b32300504400531d01b01b32300503300531d01b01b323005307", + "0x32300530000504601b01b3230052f400524401b0862f40073230052fd005", + "0x501b00701b01b71100501b19301b2f200532300508600521f01b2f3005", + "0x32400522201b01b32300504500534001b01b32300507500522201b01b323", + "0x531d01b01b32300530700531d01b01b32300504300522201b01b323005", + "0x33301b08400532300501b31b01b01b32300503300531d01b01b323005044", + "0x3230052f108400732401b2f10053230052f100502501b2f100532300501b", + "0x19301b2f20053230052f000521f01b2f300532300507b00504601b2f0005", + "0x504601b01b32300507700522201b01b32300501b00701b01b71100501b", + "0x32300506203400770501b06200532300506200503601b034005323005034", + "0x1b32300501b00701b2ec00571232c00532300708900570601b08907f007", + "0x7f00504601b2ea0053230052eb0050bb01b2eb00532300532c00570801b", + "0x53230052f504400720201b2f50053230052ea00502501b088005323005", + "0x2501b2e80053230052e90330072b301b2e90053230052e900502501b2e9", + "0x1b2e50057142e62e70073230072e808800771301b2e80053230052e8005", + "0x433072e402452901b2e40053230052e604500771501b01b32300501b007", + "0x2e10053230052e300552a01b2e20053230052e700504601b2e3005323005", + "0x1b01b32300504500534001b01b32300501b00701b01b71600501b19301b", + "0x1b32300530700531d01b01b32300504300522201b01b323005324005222", + "0x32300507e00502501b07e00532300501b05401b2df00532300501b31b01b", + "0x1b0560053230052e500504601b08d00532300507e2df00732401b07e005", + "0x1b01b32300501b00701b01b70b00501b19301b05800532300508d00521f", + "0x1b32300504300522201b01b32300532400522201b01b323005045005340", + "0x32300504400531d01b01b32300503300531d01b01b32300530700531d01b", + "0x504601b01b32300508f00524401b2de08f0073230052ec00517501b01b", + "0x53230052f300527101b2f20053230052de00521f01b2f300532300507f", + "0x32300501b00701b01b70b00501b19301b0580053230052f200571701b056", + "0x532400522201b01b32300504500534001b01b32300500600522201b01b", + "0x4400531d01b01b3230052c900531d01b01b32300504300522201b01b323", + "0x1b31b01b01b3230052d300531d01b01b32300503300531d01b01b323005", + "0x1b2dd0053230052dd00502501b2dd00532300501b33301b092005323005", + "0x9000521f01b05600532300530600504601b0900053230052dd092007324", + "0x4500534001b01b32300501b00701b01b70b00501b19301b058005323005", + "0x528601b01b32300504300522201b01b32300532400522201b01b323005", + "0x17501b01b32300521b00528601b01b32300504400531d01b01b323005217", + "0x32300504b00504601b01b32300508700524401b2dc087007323005050005", + "0x501b00701b01b70b00501b19301b0580053230052dc00521f01b056005", + "0x4500534001b01b32300521b00528601b01b32300522900522201b01b323", + "0x528601b01b32300504300522201b01b32300532400522201b01b323005", + "0x33301b2da00532300501b31b01b01b32300504400531d01b01b323005217", + "0x3230050982da00732401b09800532300509800502501b09800532300501b", + "0x901b0580053230052d900521f01b05600532300522500504601b2d9005", + "0x32300509b00571801b09b00532300505809f00702d01b09f00532300501b", + "0x70052d80053230052d800571901b05600532300505600504601b2d8005", + "0x719200729a01b01b32300503700522201b01b32300501b00701b2d8056", + "0x501b14d01b01b32300501b00701b0a70a52d402471a0a32d6007323007", + "0x1b2cf0053230050a300516501b0aa0053230052d600504601b2d2005323", + "0x1b01b32300501b00701b01b71b00501b19301b2ce0053230052d2005165", + "0x50a500516501b2cf0053230050a700516501b0aa0053230052d4005046", + "0x2cd32400732300532400503901b0aa0053230050aa00504601b2ce005323", + "0x70601b2cb2cc0073230052cd0aa00770501b2cd0053230052cd00503601b", + "0x50af00570801b01b32300501b00701b2ca00571c0af0053230072cb005", + "0x1b01b32300501b00701b2c700571d01b3230072c800570901b2c8005323", + "0x1b32300504300522201b01b32300532400522201b01b323005045005340", + "0x3230052cf00528601b01b32300504400531d01b01b3230052ce00528601b", + "0x53b200502501b3b200532300501b05401b04900532300501b31b01b01b", + "0x3b40053230052cc00504601b3b30053230053b204900732401b3b2005323", + "0x1b32300501b00701b01b71e00501b19301b0cd0053230053b300521f01b", + "0xb90053230052ce0050bb01b0b60b73b50243230052c72cf2cc02420601b", + "0xbb00503601b0bf32400732300532400503901b0bb00532300501b65901b", + "0x1b42a2d500771f41b2c50073230070bf0bb3b50241d201b0bb005323005", + "0x532300541b00503601b2c50053230052c500504601b01b32300501b007", + "0x7202be0053230070c400570601b0c42bf00732300541b2c500770501b41b", + "0x42f0050bb01b42f0053230052be00570801b01b32300501b00701b0c5005", + "0x2ba0053230050b60050bb01b2bb0053230050b70050bb01b2bc005323005", + "0x2b900503601b2b304300732300504300503901b2b900532300501b52801b", + "0x1b0c22ae0077212b00cb0073230072b32b92bf0241d201b2b9005323005", + "0x3230052b100502501b2b10053230052bc0b900720201b01b32300501b007", + "0x3901b2b800532300501b65901b0cc0053230052bb2b10072b301b2b1005", + "0x50cc00502501b2b80053230052b800503601b2ab2b00073230052b0005", + "0x701b2b70d00077222a92aa0073230072b82ab0cb0241d201b0cc005323", + "0x3601b0d200532300501b65901b01b3230052a900522201b01b32300501b", + "0xd40077232b52b40073230070d22b02aa0241d201b0d20053230050d2005", + "0x52b500503601b2b40053230052b400504601b01b32300501b00701b2b6", + "0x53230072a000570601b2a02a80073230052b52b400770501b2b5005323", + "0xbb01b29c0053230052a200570801b01b32300501b00701b29d0057242a2", + "0x32300529a0da00720201b29a00532300501b20301b0da00532300529c005", + "0x19301b0de00532300529800502501b2970053230052a800504601b298005", + "0x522201b01b32300504500534001b01b32300501b00701b01b72500501b", + "0x31d01b01b3230052ba00531d01b01b32300504300522201b01b323005324", + "0x29500732300529d00517501b01b32300504400531d01b01b3230050cc005", + "0x29300521f01b0df0053230052a800504601b01b32300529500524401b293", + "0x2b600522201b01b32300501b00701b01b72600501b19301b0e3005323005", + "0x522201b01b32300532400522201b01b32300504500534001b01b323005", + "0x31d01b01b32300504400531d01b01b3230052ba00531d01b01b323005043", + "0x1b28f00532300501b33301b29200532300501b31b01b01b3230050cc005", + "0xd400504601b28e00532300528f29200732401b28f00532300528f005025", + "0x701b01b72600501b19301b0e300532300528e00521f01b0df005323005", + "0x1b0d00053230050d000504601b01b3230052b700522201b01b32300501b", + "0x570601b28c28d0073230052b00d000770501b2b00053230052b0005036", + "0x32300528b00570801b01b32300501b00701b28a00572728b00532300728c", + "0x2501b29700532300528d00504601b0eb0053230052870050bb01b287005", + "0x50ed00502501b0ed0053230050de04400720201b0de0053230050eb005", + "0x28600532300528600502501b2860053230050ed0cc0072b301b0ed005323", + "0x1b01b32300501b00701b0ef00572828428500732300728629700771301b", + "0x4601b0f00053230050432ba0f102452901b0f1005323005284045007715", + "0x3230052e200527101b2e10053230050f000552a01b2e2005323005285005", + "0x501b00701b01b72a00501b19301b2830053230052e100572901b0ee005", + "0x4300522201b01b32300532400522201b01b32300504500534001b01b323", + "0x1b05401b28200532300501b31b01b01b3230052ba00531d01b01b323005", + "0x53230050f728200732401b0f70053230050f700502501b0f7005323005", + "0x1b19301b0cd0053230050f900521f01b3b40053230050ef00504601b0f9", + "0x32400522201b01b32300504500534001b01b32300501b00701b01b71e005", + "0x531d01b01b3230052ba00531d01b01b32300504300522201b01b323005", + "0xf60f800732300528a00517501b01b32300504400531d01b01b3230050cc", + "0x50f600521f01b0df00532300528d00504601b01b3230050f800524401b", + "0x1b0cd0053230050e300571701b3b40053230050df00527101b0e3005323", + "0x34001b01b3230050c200522201b01b32300501b00701b01b71e00501b193", + "0x1b01b32300504300522201b01b32300532400522201b01b323005045005", + "0x1b3230050b900531d01b01b32300504400531d01b01b3230052ba00531d", + "0x532300501b31b01b01b3230052bb00531d01b01b3230052bc00531d01b", + "0x28100732401b28000532300528000502501b28000532300501b33301b281", + "0x53230050ff00521f01b3b40053230052ae00504601b0ff005323005280", + "0x1b32300504500534001b01b32300501b00701b01b71e00501b19301b0cd", + "0x32300504400531d01b01b32300504300522201b01b32300532400522201b", + "0x50b600528601b01b3230050b700528601b01b3230050b900531d01b01b", + "0x4601b01b32300510100524401b1001010073230050c500517501b01b323", + "0x1b71e00501b19301b0cd00532300510000521f01b3b40053230052bf005", + "0x1b32300504500534001b01b32300542a00522201b01b32300501b00701b", + "0x3230050b600528601b01b32300504300522201b01b32300532400522201b", + "0x50b700528601b01b3230050b900531d01b01b32300504400531d01b01b", + "0x27e00502501b27e00532300501b33301b0fe00532300501b31b01b01b323", + "0x53230052d500504601b27d00532300527e0fe00732401b27e005323005", + "0x32300501b00701b01b71e00501b19301b0cd00532300527d00521f01b3b4", + "0x504300522201b01b32300532400522201b01b32300504500534001b01b", + "0x2cf00528601b01b32300504400531d01b01b3230052ce00528601b01b323", + "0x1b01b32300510700524401b1091070073230052ca00517501b01b323005", + "0x32300501b00901b0cd00532300510900521f01b3b40053230052cc005046", + "0x1b27c00532300510600571801b1060053230050cd10800702d01b108005", + "0x1b27c3b400700527c00532300527c00571901b3b40053230053b4005046", + "0x11527b10e02472b10f11300732300700702500729a01b01b32300501b007", + "0x532300511300504601b11700532300501b14d01b01b32300501b00701b", + "0x1b19301b27700532300511700516501b27800532300510f00516501b279", + "0x516501b27900532300510e00504601b01b32300501b00701b01b72c005", + "0x53230052770050bb01b27700532300527b00516501b278005323005115", + "0x4300503901b11b00532300501b52801b11a0053230052780050bb01b276", + "0x701811b2790241d201b11b00532300511b00503601b018043007323005", + "0x532300501b65901b01b32300501b00701b12127300772d275119007323", + "0x1d201b12000532300512000503601b27127500732300527500503901b120", + "0x1b01b32300501b00701b12626f00772e270048007323007120271119024", + "0x532300512500503601b12500532300501b65901b01b323005270005222", + "0x501b00701b12d12b00772f26c26d0073230071252750480241d201b125", + "0x70501b26c00532300526c00503601b26d00532300526d00504601b01b323", + "0x1b26a00573026b00532300712a00570601b12a12c00732300526c26d007", + "0x53230052690050bb01b26900532300526b00570801b01b32300501b007", + "0x504601b26700532300513313400720201b13300532300501b20301b134", + "0x1b01b73100501b19301b26500532300526700502501b26600532300512c", + "0x1b01b32300532400522201b01b32300504500534001b01b32300501b007", + "0x1b32300527600531d01b01b32300511a00531d01b01b323005043005222", + "0x14500524401b13c14500732300526a00517501b01b32300504400531d01b", + "0x1b14000532300513c00521f01b13e00532300512c00504601b01b323005", + "0x34001b01b32300512d00522201b01b32300501b00701b01b73200501b193", + "0x1b01b32300504300522201b01b32300532400522201b01b323005045005", + "0x1b32300527600531d01b01b32300504400531d01b01b32300511a00531d", + "0x32300514300502501b14300532300501b33301b14100532300501b31b01b", + "0x1b13e00532300512b00504601b26200532300514314100732401b143005", + "0x1b01b32300501b00701b01b73200501b19301b14000532300526200521f", + "0x32300527500503601b26f00532300526f00504601b01b323005126005222", + "0x14d00532300726400570601b26426000732300527526f00770501b275005", + "0x50bb01b14b00532300514d00570801b01b32300501b00701b14c005733", + "0x532300514a00502501b26600532300526000504601b14a00532300514b", + "0x2b301b14900532300514900502501b14900532300526504400720201b265", + "0x14826600771301b14800532300514800502501b148005323005149276007", + "0x514604500771501b01b32300501b00701b157005734146147007323007", + "0x532300514700504601b25d00532300504311a25e02452901b25e005323", + "0x1b25a25b25c0243230052830056fb01b28300532300525d00552a01b0ee", + "0x501b03f01b25800532300532425b25c02452901b01b32300525a005222", + "0x25500532300525600573601b25600532300525725800773501b257005323", + "0x2550ee00700525500532300525500571901b0ee0053230050ee00504601b", + "0x1b32300532400522201b01b32300504500534001b01b32300501b00701b", + "0x532300501b31b01b01b32300511a00531d01b01b32300504300522201b", + "0x16000732401b16200532300516200502501b16200532300501b05401b160", + "0x532300525300521f01b16400532300515700504601b253005323005162", + "0x1b32300504500534001b01b32300501b00701b01b73700501b19301b252", + "0x32300511a00531d01b01b32300504300522201b01b32300532400522201b", + "0x514c00517501b01b32300504400531d01b01b32300527600531d01b01b", + "0x1b13e00532300526000504601b01b32300516500524401b167165007323", + "0x514000571701b16400532300513e00527101b14000532300516700521f", + "0x512100522201b01b32300501b00701b01b73700501b19301b252005323", + "0x4300522201b01b32300532400522201b01b32300504500534001b01b323", + "0x531d01b01b32300504400531d01b01b32300511a00531d01b01b323005", + "0x2501b16a00532300501b33301b16800532300501b31b01b01b323005276", + "0x527300504601b25000532300516a16800732401b16a00532300516a005", + "0x2d01b13900532300501b00901b25200532300525000521f01b164005323", + "0x516400504601b24d00532300513800571801b138005323005252139007", + "0x32300501b00701b24d16400700524d00532300524d00571901b164005323", + "0x504500534001b01b32300504400531d01b01b32300502d00522201b01b", + "0x501b31b01b01b32300504300522201b01b32300500700531d01b01b323", + "0x32401b24800532300524800502501b24800532300501b33301b249005323", + "0x524724600702d01b24600532300501b00901b247005323005248249007", + "0x1b00900532300500900504601b17000532300524500571801b245005323", + "0x522201b01b32300501b00701b170009007005170005323005170005719", + "0x3901b17200532300501b65901b01b32300519300522201b01b323005043", + "0x1730200241d201b17200532300517200503601b173024007323005024005", + "0x24400522201b01b32300501b00701b178177007738244175007323007172", + "0x1d201b17a00532300517a00503601b17a00532300501b65901b01b323005", + "0x1b01b32300501b00701b18218000773918124200732300717a024175024", + "0x18124200770501b18100532300518100503601b242005323005242005046", + "0x501b00701b23e00573a17b00532300723d00570601b23d183007323005", + "0x20301b24b0053230051870050bb01b18700532300517b00570801b01b323", + "0x32300518300504601b23900532300524a24b00720201b24a00532300501b", + "0x501b00701b01b73b00501b19301b18c00532300523900502501b18a005", + "0x4400531d01b01b32300500700531d01b01b32300504500534001b01b323", + "0x1b01b32300523800524401b18e23800732300523e00517501b01b323005", + "0x73c00501b19301b23700532300518e00521f01b190005323005183005046", + "0x32300504500534001b01b32300518200522201b01b32300501b00701b01b", + "0x32300501b31b01b01b32300500700531d01b01b32300504400531d01b01b", + "0x732401b23500532300523500502501b23500532300501b33301b23b005", + "0x32300523300521f01b19000532300518000504601b23300532300523523b", + "0x32300517800522201b01b32300501b00701b01b73c00501b19301b237005", + "0x770501b02400532300502400503601b17700532300517700504601b01b", + "0x701b22700573d22800532300722a00570601b22a22b007323005024177", + "0x2240053230051980050bb01b19800532300522800570801b01b32300501b", + "0x4400720201b18c00532300522400502501b18a00532300522b00504601b", + "0x3230052210070072b301b22100532300522100502501b22100532300518c", + "0x19e19c00732300721d18a00771301b21d00532300521d00502501b21d005", + "0x5001b21a00532300519e04500771501b01b32300501b00701b21c00573e", + "0x3230051a321921a02452901b1a300532300501b03701b21900532300501b", + "0x73601b20e00532300521021400773501b21000532300501b03f01b214005", + "0x32300520c00571901b19c00532300519c00504601b20c00532300520e005", + "0x1b01b32300504500534001b01b32300501b00701b20c19c00700520c005", + "0x532300520600502501b20600532300501b05401b20a00532300501b31b", + "0x702d01b20200532300501b00901b20300532300520620a00732401b206", + "0x32300521c00504601b2010053230051ac00571801b1ac005323005203202", + "0x1b32300501b00701b20121c00700520100532300520100571901b21c005", + "0x32300504400531d01b01b32300500700531d01b01b32300504500534001b", + "0x504601b01b3230051ae00524401b1b01ae00732300522700517501b01b", + "0x20000532300501b00901b2370053230051b000521f01b19000532300522b", + "0x504601b1ff00532300517c00571801b17c00532300523720000702d01b", + "0x1b00701b1ff1900070051ff0053230051ff00571901b190005323005190", + "0x1b03701b01b32300519300522201b01b32300531e00522201b01b323005", + "0x532300531f00504601b1b404300732300504300503901b204005323005", + "0x1b65901b01b32300501b00701b01b73f01b3230072041b400711901b31f", + "0x53230051fd00503601b1fc02400732300502400503901b1fd005323005", + "0x501b00701b1b91b70077401f81fb0073230071fd1fc31f0241d201b1fd", + "0x2400503901b1f600532300501b65901b01b3230051f800522201b01b323", + "0x71f61bb1fb0241d201b1f60053230051f600503601b1bb024007323005", + "0x3230051f300504601b01b32300501b00701b1ed1ee0077411f91f3007323", + "0x1eb1ec0073230051f91f300770501b1f90053230051f900503601b1f3005", + "0x570801b01b32300501b00701b1e90057421ea0053230071eb00570601b", + "0x1e300532300501b20301b1c20053230051e80050bb01b1e80053230051ea", + "0x502501b1de0053230051ec00504601b1e10053230051e31c200720201b", + "0x531d01b01b32300501b00701b01b74300501b19301b1dc0053230051e1", + "0x22201b01b32300500700531d01b01b32300504500534001b01b323005044", + "0x1d90073230051e900517501b01b32300504300522201b01b323005024005", + "0x1d200521f01b1df0053230051ec00504601b01b3230051d900524401b1d2", + "0x1ed00522201b01b32300501b00701b01b74400501b19301b000005323005", + "0x534001b01b32300504300522201b01b32300504400531d01b01b323005", + "0x31b01b01b32300502400522201b01b32300500700531d01b01b323005045", + "0x4bd0053230054bd00502501b4bd00532300501b33301b4bc00532300501b", + "0x521f01b1df0053230051ee00504601b4be0053230054bd4bc00732401b", + "0x522201b01b32300501b00701b01b74400501b19301b0000053230054be", + "0x2400732300502400503901b1b70053230051b700504601b01b3230051b9", + "0x1b4c14c00073230054bf1b700770501b4bf0053230054bf00503601b4bf", + "0x4c200570801b01b32300501b00701b4c30057454c20053230074c1005706", + "0x1de0053230054c000504601b4c50053230054c40050bb01b4c4005323005", + "0x7464c74c60073230070240431de02467301b1dc0053230054c500502501b", + "0x2501b32b0053230051dc04400720201b01b32300501b00701b4c94c8007", + "0x4cb04502452901b4cb00532300532b0070072b301b32b00532300532b005", + "0x53230054ce4cc00773501b4ce00532300501b03f01b4cc0053230054c7", + "0x571901b4c60053230054c600504601b4d00053230054cf00573601b4cf", + "0x54c900522201b01b32300501b00701b4d04c60070054d00053230054d0", + "0x4500534001b01b3230051dc00531d01b01b32300504400531d01b01b323", + "0x1b67601b4d100532300501b31b01b01b32300500700531d01b01b323005", + "0x53230054d34d100732401b4d30053230054d300502501b4d3005323005", + "0x571801b4d50053230054d432a00702d01b32a00532300501b00901b4d4", + "0x53230054d600571901b4c80053230054c800504601b4d60053230054d5", + "0x34001b01b32300504400531d01b01b32300501b00701b4d64c80070054d6", + "0x1b01b32300502400522201b01b32300500700531d01b01b323005045005", + "0x54d800524401b4d94d80073230054c300517501b01b323005043005222", + "0x901b0000053230054d900521f01b1df0053230054c000504601b01b323", + "0x3230054dc00571801b4dc0053230050004da00702d01b4da00532300501b", + "0x70054dd0053230054dd00571901b1df0053230051df00504601b4dd005", + "0x504300522201b01b32300504400531d01b01b32300501b00701b4dd1df", + "0x1b4df00532300501b03f01b4de00532300502400704502452901b01b323", + "0x31f00504601b4e10053230054e000573601b4e00053230054df4de007735", + "0x501b00701b4e131f0070054e10053230054e100571901b31f005323005", + "0x4500534001b01b32300504400531d01b01b32300503e00522201b01b323", + "0x522201b01b32300504300522201b01b32300500700531d01b01b323005", + "0x2501b4e300532300501b67601b4e200532300501b31b01b01b323005024", + "0x32300501b00901b4e40053230054e34e200732401b4e30053230054e3005", + "0x1b4e600532300532900571801b3290053230054e44e500702d01b4e5005", + "0x1b4e603f0070054e60053230054e600571901b03f00532300503f005046", + "0x1b01b32300500700531d01b01b32300502400522201b01b32300501b007", + "0x54e800573601b4e80053230054e700500773501b4e700532300501b03f", + "0x54e90053230054e900571901b01b00532300501b00504601b4e9005323", + "0x74704604700732300700501b00700501b01b32300501b02001b4e901b007", + "0x1b04701b04300532300500700574801b01b32300501b00701b044045007", + "0x4104200732300704300574901b04700532300504700504601b01b323005", + "0x574c01b19300532300504100574b01b01b32300501b00701b04000574a", + "0x1b01b74e00501b19301b03e00532300519300574d01b03f005323005042", + "0x7d00532300502300574f01b02300532300501b03f01b01b32300501b007", + "0x3e00575001b03e00532300507d00574d01b03f00532300504000574c01b", + "0x1b01b32300501b02001b01b32300501b00701b321005751020005323007", + "0x531e00575301b31e00532300531f00575201b31f00532300502000533e", + "0x31b00532300531d02400732401b31d00532300531d00502501b31d005323", + "0x4600503101b04700532300504700504601b31a00532300503f00553a01b", + "0x31b00532300531b00521f01b31a00532300531a00553b01b046005323005", + "0x701b00932402502400500932402502432300531b31a04604704753d01b", + "0x554001b01b32300532100522501b01b32300501b02001b01b32300501b", + "0x2800532300502d02400775401b02d00532300501b03f01b01b32300503f", + "0x4600503101b04700532300504700504601b03100532300502800575501b", + "0x1b00701b03104604702400503100532300503100575601b046005323005", + "0x1b31b01b01b32300500700575701b01b32300502400521601b01b323005", + "0x1b0b00053230050b000502501b0b000532300501b22301b317005323005", + "0x7c1f500702d01b1f500532300501b00901b07c0053230050b0317007324", + "0x4500532300504500504601b03700532300519200575801b192005323005", + "0x4404502400503700532300503700575601b04400532300504400503101b", + "0x575904702400732300700700504501b00700532300500500502401b037", + "0x504500504301b04500532300504700504401b01b32300501b00701b046", + "0x1b04200532300502400504101b04300532300504400504201b044005323", + "0x1b01b32300501b00701b01b75a00501b19301b041005323005043005040", + "0x32300504600504101b19300532300504000503e01b04000532300501b03f", + "0x575b03f00532300704100502301b04100532300519300504001b042005", + "0x1b02000575c07d02300732300704200504501b01b32300501b00701b03e", + "0x532300502300504101b32100532300507d00505801b01b32300501b007", + "0x32300501b00701b01b75d00501b19301b31e00532300532100505701b31f", + "0x2000504101b31b00532300531d00505501b31d00532300501b03f01b01b", + "0x31f00732300531f0052a901b31e00532300531b00505701b31f005323005", + "0x900575e32400532300731e0052c601b02500532300531a00521701b31a", + "0x32300502d00504301b02d00532300532400504401b01b32300501b00701b", + "0x31703100732300702801b00706f01b02800532300502800502501b028005", + "0x3100504601b01b32300502500522c01b01b32300501b00701b0b000575f", + "0x501b00701b1920057601f507c00732300731f00504501b031005323005", + "0x5701b03900532300507c00504101b0370053230051f500505801b01b323", + "0x3f01b01b32300501b00701b01b76100501b19301b038005323005037005", + "0x532300519200504101b20d00532300503600505501b03600532300501b", + "0x52c601b21300532300503900521701b03800532300520d00505701b039", + "0x32300521500504401b01b32300501b00701b216005762215005323007038", + "0x29a01b21b00532300521b00502501b21b00532300521700504301b217005", + "0x1b01b32300501b00701b22522322202476321f21e00732300721b031007", + "0x504601b04b00532300522900576501b22900532300521f31703f024764", + "0x532300504b00576601b2130053230052130052c901b21e00532300521e", + "0x1b01b32300522300528601b01b32300501b00701b04b21321e02400504b", + "0x1b32300531700507001b01b32300503f00531d01b01b323005225005286", + "0x1b32300501b00701b01b76700501b19301b22c00532300522200504601b", + "0x32300531700507001b01b32300503f00531d01b01b32300521600522501b", + "0x5300576801b05300532300501b03f01b22c00532300503100504601b01b", + "0x5000532300505000576601b2130053230052130052c901b050005323005", + "0x32101b01b32300503f00531d01b01b32300501b00701b05021322c024005", + "0x1b01b76900501b19301b0510053230050b000504601b01b32300531f005", + "0x1b01b32300503f00531d01b01b32300500900522501b01b32300501b007", + "0x532300501b03f01b05100532300501b00504601b01b32300531f005321", + "0x576601b0250053230050250052c901b24300532300505400576801b054", + "0x4200521701b01b32300501b00701b243025051024005243005323005243", + "0x1b00532300501b00504601b25100532300503e00576801b24f005323005", + "0x24f01b02400525100532300525100576601b24f00532300524f0052c901b", + "0x520a01b04600532300501b76a01b04702400732300500700516401b251", + "0x776b01b04304404502432300504602401b02420601b046005323005046", + "0x4200776b01b01b32300501b00701b04000576c041042007323007044045", + "0x3f00500713901b01b32300501b00701b03e00576d03f193007323007043", + "0x2000532300501b76a01b07d00532300504102300713901b023005323005", + "0x31e31f32102432300502004719302420601b02000532300502000520a01b", + "0x576e31b31d00732300731f32100776b01b07d00532300507d00525e01b", + "0x900576f32402500732300731e31d00776b01b01b32300501b00701b31a", + "0x31b02d00713901b02d00532300532407d00713901b01b32300501b00701b", + "0x31700532300503102800765f01b03100532300501b03f01b028005323005", + "0xb000533901b02500532300502500504601b0b000532300531700566001b", + "0x32300507d00516001b01b32300501b00701b0b00250070050b0005323005", + "0x32300501b05401b07c00532300501b31b01b01b32300531b00507001b01b", + "0x1b1920053230051f507c00732401b1f50053230051f500502501b1f5005", + "0x77000501b19301b03900532300519200521f01b037005323005009005046", + "0x32300531e00528601b01b32300507d00516001b01b32300501b00701b01b", + "0x503600502501b03600532300501b05401b03800532300501b31b01b01b", + "0x3700532300531a00504601b20d00532300503603800732401b036005323", + "0x3921300702d01b21300532300501b00901b03900532300520d00521f01b", + "0x3700532300503700504601b21600532300521500564701b215005323005", + "0x28601b01b32300501b00701b21603700700521600532300521600533901b", + "0x1b01b32300504100507001b01b32300500500516001b01b323005047005", + "0x532300521b00502501b21b00532300501b05401b21700532300501b31b", + "0x21f01b21f00532300503e00504601b21e00532300521b21700732401b21b", + "0x28601b01b32300501b00701b01b77100501b19301b22200532300521e005", + "0x1b01b32300504300528601b01b32300500500516001b01b323005047005", + "0x532300522500502501b22500532300501b05401b22300532300501b31b", + "0x21f01b21f00532300504000504601b22900532300522522300732401b225", + "0x32300522204b00702d01b04b00532300501b00901b222005323005229005", + "0x33901b21f00532300521f00504601b05300532300522c00564701b22c005", + "0x1b00700501b01b32300501b02001b05321f007005053005323005053005", + "0x501b4f601b01b32300501b00701b044045007772046047007323007005", + "0x4700532300504700504601b04202400732300502400503901b043005323", + "0x501b03401b01b32300501b00701b01b77301b32300704304200711901b", + "0x4000532300504100700713901b04100532300504100530201b041005323", + "0x504000525e01b19300532300519300503601b19300532300501b4f601b", + "0x701b07d02300777403e03f0073230071930240470241d201b040005323", + "0x4600532300504600503101b03f00532300503f00504601b01b32300501b", + "0x3f04765c01b03e00532300503e00503601b04000532300504000525e01b", + "0x1b32300501b00701b31f32102002400531f32102002432300503e040046", + "0x532300501b31b01b01b32300504000516001b01b32300507d00522201b", + "0x31e00732401b31d00532300531d00502501b31d00532300501b33301b31e", + "0x532300531b31a00702d01b31a00532300501b00901b31b00532300531d", + "0x503101b02300532300502300504601b32400532300502500564701b025", + "0x701b32404602302400532400532300532400533901b046005323005046", + "0x30201b00900532300501b65d01b01b32300502400522201b01b32300501b", + "0x32300501b03f01b02d00532300500900700713901b009005323005009005", + "0x1b31700532300503100566001b03100532300502802d00765f01b028005", + "0x531700533901b04600532300504600503101b047005323005047005046", + "0x32300500700516001b01b32300501b00701b317046047024005317005323", + "0x32300501b22301b0b000532300501b31b01b01b32300502400522201b01b", + "0x1b1f500532300507c0b000732401b07c00532300507c00502501b07c005", + "0x503700564701b0370053230051f519200702d01b19200532300501b009", + "0x1b04400532300504400503101b04500532300504500504601b039005323", + "0x50073230050050052cd01b039044045024005039005323005039005339", + "0x531d01b01b32300501b00701b02400577501b32300700700507e01b007", + "0x32300501b00701b01b00500501b00532300501b00524201b01b323005005", + "0x504700503601b04700532300501b03701b01b3230050240052de01b01b", + "0x1b04500532300501b05101b04600532300504701b00717a01b047005323", + "0x502501b0430053230050450440072d601b0440050073230050050052cd", + "0x1b32300704300507e01b04600532300504600524201b043005323005043", + "0x4600524201b01b32300500500531d01b01b32300501b00701b042005776", + "0x1b3230050420052de01b01b32300501b00701b046005005046005323005", + "0x4104600717a01b04100532300504100503601b04100532300501b03701b", + "0x3f0050073230050050052cd01b19300532300501b14101b040005323005", + "0x524201b03e00532300503e00502501b03e00532300519303f0072d601b", + "0x32300501b00701b02300577701b32300703e00507e01b040005323005040", + "0x1b04000500504000532300504000524201b01b32300500500531d01b01b", + "0x1b07d00532300501b03701b01b3230050230052de01b01b32300501b007", + "0x501b77801b02000532300507d04000717a01b07d00532300507d005036", + "0x532300532131f0072d601b31f0050073230050050052cd01b321005323", + "0x507e01b02000532300502000524201b31e00532300531e00502501b31e", + "0x1b32300500500531d01b01b32300501b00701b31d00577901b32300731e", + "0x52de01b01b32300501b00701b02000500502000532300502000524201b", + "0x1b31b00532300531b00503601b31b00532300501b03701b01b32300531d", + "0x50050052cd01b02500532300501b77a01b31a00532300531b02000717a", + "0x532300500900502501b0090053230050253240072d601b324005007323", + "0x1b02d00577b01b32300700900507e01b31a00532300531a00524201b009", + "0x31a00532300531a00524201b01b32300500500531d01b01b32300501b007", + "0x501b03701b01b32300502d0052de01b01b32300501b00701b31a005005", + "0x3100532300502831a00717a01b02800532300502800503601b028005323", + "0xb00072d601b0b00050073230050050052cd01b31700532300501b77c01b", + "0x532300503100524201b07c00532300507c00502501b07c005323005317", + "0x531d01b01b32300501b00701b1f500577d01b32300707c00507e01b031", + "0x32300501b00701b03100500503100532300503100524201b01b323005005", + "0x519200503601b19200532300501b03701b01b3230051f50052de01b01b", + "0x1b03900532300501b33801b03700532300519203100717a01b192005323", + "0x502501b0360053230050390380072d601b0380050073230050050052cd", + "0x1b32300703600507e01b03700532300503700524201b036005323005036", + "0x3700524201b01b32300500500531d01b01b32300501b00701b20d00577e", + "0x1b32300520d0052de01b01b32300501b00701b037005005037005323005", + "0x21303700717a01b21300532300521300503601b21300532300501b03701b", + "0x2170050073230050050052cd01b21600532300501b77f01b215005323005", + "0x524201b21b00532300521b00502501b21b0053230052162170072d601b", + "0x32300501b00701b21e00578001b32300721b00507e01b215005323005215", + "0x1b21500500521500532300521500524201b01b32300500500531d01b01b", + "0x1b21f00532300501b03701b01b32300521e0052de01b01b32300501b007", + "0x501b78101b22200532300521f21500717a01b21f00532300521f005036", + "0x53230052232250072d601b2250050073230050050052cd01b223005323", + "0x507e01b22200532300522200524201b22900532300522900502501b229", + "0x1b32300500500531d01b01b32300501b00701b04b00578201b323007229", + "0x52de01b01b32300501b00701b22200500522200532300522200524201b", + "0x1b22c00532300522c00503601b22c00532300501b03701b01b32300504b", + "0x50050052cd01b05000532300501b78301b05300532300522c22200717a", + "0x532300505400502501b0540053230050500510072d601b051005007323", + "0x1b24300578401b32300705400507e01b05300532300505300524201b054", + "0x5300532300505300524201b01b32300500500531d01b01b32300501b007", + "0x501b03701b01b3230052430052de01b01b32300501b00701b053005005", + "0x25100532300524f05300717a01b24f00532300524f00503601b24f005323", + "0x580072d601b0580050073230050050052cd01b05600532300501b78501b", + "0x532300525100524201b05700532300505700502501b057005323005056", + "0x531d01b01b32300501b00701b05500578601b32300705700507e01b251", + "0x32300501b00701b25100500525100532300525100524201b01b323005005", + "0x52c600503601b2c600532300501b03701b01b3230050550052de01b01b", + "0x1b2d300532300501b78701b2c90053230052c625100717a01b2c6005323", + "0x502501b0600053230052d30330072d601b0330050073230050050052cd", + "0x1b32300706000507e01b2c90053230052c900524201b060005323005060", + "0x2c900524201b01b32300500500531d01b01b32300501b00701b2ef005788", + "0x1b3230052ef0052de01b01b32300501b00701b2c90050052c9005323005", + "0x632c900717a01b06300532300506300503601b06300532300501b03701b", + "0x60050073230050050052cd01b30600532300501b42a01b062005323005", + "0x524201b06a00532300506a00502501b06a0053230053060060072d601b", + "0x32300501b00701b06c00578901b32300706a00507e01b062005323005062", + "0x1b06200500506200532300506200524201b01b32300500500531d01b01b", + "0x1b30700532300501b03701b01b32300506c0052de01b01b32300501b007", + "0x501b78a01b06f00532300530706200717a01b307005323005307005036", + "0x53230050700720072d601b0720050073230050050052cd01b070005323", + "0x507e01b06f00532300506f00524201b30500532300530500502501b305", + "0x1b32300500500531d01b01b32300501b00701b03400578b01b323007305", + "0x52de01b01b32300501b00701b06f00500506f00532300506f00524201b", + "0x1b07700532300507700503601b07700532300501b03701b01b323005034", + "0x50050052cd01b07400532300501b78c01b30200532300507706f00717a", + "0x532300507b00502501b07b0053230050740730072d601b073005007323", + "0x1b07500578d01b32300707b00507e01b30200532300530200524201b07b", + "0x30200532300530200524201b01b32300500500531d01b01b32300501b007", + "0x501b03701b01b3230050750052de01b01b32300501b00701b302005005", + "0x2ff00532300530030200717a01b30000532300530000503601b300005323", + "0x2fd00502501b2fd0053230052fe0050072d601b2fe00532300501b05301b", + "0x78e01b3230072fd00507e01b2ff0053230052ff00524201b2fd005323005", + "0x1b2ff0050052ff0053230052ff00524201b01b32300501b00701b2fc005", + "0x1b2fb00532300501b03701b01b3230052fc0052de01b01b32300501b007", + "0x2fa00524201b2fa0053230052fb2ff00717a01b2fb0053230052fb005036", + "0x521901b04404504602432300504700569801b2fa0050052fa005323005", + "0x79004004104202432300704404300700504778f01b043046007323005046", + "0x3101b04000532300504000519801b01b32300501b00701b03e03f193024", + "0x32300704000522401b04100532300504100531701b042005323005042005", + "0x79301b02000532300501b79201b01b32300501b00701b07d005791023005", + "0x532300532100514b01b02000532300502000514b01b32100532300501b", + "0x1b02531a31b02479431d31e31f02432300732102004104204722a01b321", + "0x532300531f00503101b31d00532300531d00519801b01b32300501b007", + "0x900579532400532300731d00522401b31e00532300531e00531701b31f", + "0x732300502d0056d401b02d00532300501b79601b01b32300501b00701b", + "0x3104132300702804601b0246d601b0280053230050280056d501b02802d", + "0x1b32300501b00701b21521320d0247970360380390371921f507c0b0317", + "0x6d801b2170053230050382160076d801b2160053230050360310076d801b", + "0x21e0076d801b21e00532300503721b0076d801b21b005323005039217007", + "0x507c2220076d801b2220053230051f521f0076d801b21f005323005192", + "0x2290053230053170056d901b2250053230050b02230076d801b223005323", + "0x22900521901b02400532300502400514b01b22500532300522500504601b", + "0x504b0242250246da01b04b00532300504b00514b01b04b229007323005", + "0x53230050500056d501b05002d00732300502d0056d401b05322c007323", + "0x6dc01b05705805625124f24305405104332300505005322c0246db01b050", + "0x50580550076d801b0550053230050570510076d801b01b323005054005", + "0x53230052512c90076d801b2c90053230050562c60076d801b2c6005323", + "0x516401b06000532300501b69c01b03300532300524f2d30076d801b2d3", + "0x506300516501b30606200732300524300516401b0632ef007323005060", + "0x701b30706c00779806a00600732300730606303302469e01b063005323", + "0x1b07000532300506f00509201b06f00532300501b03f01b01b32300501b", + "0x507000508f01b30500532300506a00516501b072005323005006005046", + "0x32300501b03f01b01b32300501b00701b01b79900501b19301b034005323", + "0x16501b07200532300506c00504601b30200532300507700508d01b077005", + "0x3230052ef00516501b03400532300530200508f01b305005323005307005", + "0x1b00701b07507b00779a0730740073230070622ef07202469e01b2ef005", + "0x1b2ff00532300507300516501b30000532300507400504601b01b323005", + "0x79b00501b19301b2fd00532300503400508f01b2fe005323005305005165", + "0x3230052fc00516501b2fc00532300501b26401b01b32300501b00701b01b", + "0x1b00701b0882f600779c2fa2fb0073230072fc30507b02469e01b2fc005", + "0x1b2ff00532300507500516501b3000053230052fb00504601b01b323005", + "0x79b00501b19301b2fd00532300503400508f01b2fe0053230052fa005165", + "0x532300501b03f01b01b3230050340052dd01b01b32300501b00701b01b", + "0x516501b3000053230052f600504601b2f40053230052f500508d01b2f5", + "0x53230052f400508f01b2fe00532300508800516501b2ff005323005075", + "0x22501b01b32300501b00701b2f300579d0860053230072fd00512001b2fd", + "0x532300504500514b01b30000532300530000504601b01b323005086005", + "0x842f20073230052290453000246da01b22900532300522900514b01b045", + "0x7f2f02f104332300502d0842f20246db01b02d00532300502d0056d501b", + "0x53230052ea2f10076d801b01b3230052f00056dc01b2ea2eb2ec32c089", + "0x1b2e70053230052ec2e80076d801b2e80053230052eb2e90076d801b2e9", + "0x714c01b2e50053230050892e60076d801b2e600532300532c2e70076d8", + "0x3230052e500504601b2e40053230052e400514b01b2e40053230052fe2ff", + "0x8d07e2df02479f2e12e22e30243230072e432431e31f04779e01b2e5005", + "0x3230052e10056b301b2e30053230052e300503101b01b32300501b00701b", + "0x870902dd0247a00922de08f02432300707f0232e22e304779e01b2e1005", + "0x3230050920056b301b08f00532300508f00503101b01b32300501b00701b", + "0x9b09f2d90247a20982da2dc0243230070922e12de08f0477a101b092005", + "0x3230052d80057a401b2d80053230050980057a301b01b32300501b00701b", + "0x3101b2e50053230052e500504601b0a30053230052d60057a501b2d6005", + "0x3230050a300533201b2da0053230052da00531701b2dc0053230052dc005", + "0x532300501b00901b01b32300501b00701b0a32da2dc2e50470050a3005", + "0x4601b0a70053230050a50057a601b0a500532300509b2d400702d01b2d4", + "0x32300509f00531701b2d90053230052d900503101b2e50053230052e5005", + "0x501b00701b0a709f2d92e50470050a70053230050a700533201b09f005", + "0x2d200702d01b2d200532300501b00901b01b3230052e100522101b01b323", + "0x53230052e500504601b2cf0053230050aa0057a601b0aa005323005087", + "0x533201b09000532300509000531701b2dd0053230052dd00503101b2e5", + "0x522101b01b32300501b00701b2cf0902dd2e50470052cf0053230052cf", + "0x2d01b2ce00532300501b00901b01b32300507f00524d01b01b323005023", + "0x52e500504601b2cc0053230052cd0057a601b2cd00532300508d2ce007", + "0x1b07e00532300507e00531701b2df0053230052df00503101b2e5005323", + "0x1b01b32300501b00701b2cc07e2df2e50470052cc0053230052cc005332", + "0x1b32300502300522101b01b3230052ff00528601b01b3230052f3005225", + "0x32300502d0056ef01b01b32300532400522101b01b3230052fe00528601b", + "0x32300501b31b01b01b32300504500524d01b01b32300522900524d01b01b", + "0x732401b0af0053230050af00502501b0af00532300501b7a701b2cb005", + "0x3230052ca2c800702d01b2c800532300501b00901b2ca0053230050af2cb", + "0x3101b30000532300530000504601b0490053230052c70057a601b2c7005", + "0x32300504900533201b31e00532300531e00531701b31f00532300531f005", + "0x32300502400524d01b01b32300501b00701b04931e31f300047005049005", + "0x532400522101b01b32300504500524d01b01b32300502300522101b01b", + "0x6d801b3b200532300521520d0076d801b01b32300502d0056ef01b01b323", + "0x532300501b05401b3b400532300501b31b01b3b30053230052133b2007", + "0x901b3b50053230050cd3b400732401b0cd0053230050cd00502501b0cd", + "0x3230050b60057a601b0b60053230053b50b700702d01b0b700532300501b", + "0x31701b31f00532300531f00503101b3b30053230053b300504601b0b9005", + "0xb931e31f3b30470050b90053230050b900533201b31e00532300531e005", + "0x1b32300502400524d01b01b32300500900522501b01b32300501b00701b", + "0x32300504600524d01b01b32300504500524d01b01b32300502300522101b", + "0x50bf00502501b0bf00532300501b05401b0bb00532300501b31b01b01b", + "0x41b00532300531f00503101b2c50053230050bf0bb00732401b0bf005323", + "0x501b19301b42a0053230052c500521f01b2d500532300531e00531701b", + "0x502300522101b01b32300502400524d01b01b32300501b00701b01b7a8", + "0x31b00503101b01b32300504600524d01b01b32300504500524d01b01b323", + "0x42a00532300502500521f01b2d500532300531a00531701b41b005323005", + "0xc40057a601b0c400532300542a2bf00702d01b2bf00532300501b00901b", + "0x41b00532300541b00503101b01b00532300501b00504601b2be005323005", + "0x41b01b0470052be0053230052be00533201b2d50053230052d500531701b", + "0x504500524d01b01b32300502400524d01b01b32300501b00701b2be2d5", + "0x57a401b0c500532300507d0057a901b01b32300504600524d01b01b323", + "0x532300501b00504601b2bc00532300542f0057a501b42f0053230050c5", + "0x533201b04100532300504100531701b04200532300504200503101b01b", + "0x524d01b01b32300501b00701b2bc04104201b0470052bc0053230052bc", + "0x901b01b32300504500524d01b01b32300504600524d01b01b323005024", + "0x3230052ba0057a601b2ba00532300503e2bb00702d01b2bb00532300501b", + "0x31701b19300532300519300503101b01b00532300501b00504601b2b9005", + "0x2b903f19301b0470052b90053230052b900533201b03f00532300503f005", + "0x1b32300501b24f01b04300532300501b28101b04500532300501b7aa01b", + "0x7ab0400410440420473230070470240050241a301b01b32300501b02001b", + "0x1b02300532300504004100733101b01b32300501b00701b03e03f193024", + "0x50200057ae01b01b32300507d0057ad01b02007d0073230050230057ac", + "0x1b31f0053230053210057b001b3210053230050200057af01b020005323", + "0x32300501b00504601b31d00532300531f00514601b31e00532300501b149", + "0x15701b00700532300500700509f01b04200532300504200503101b01b005", + "0x504404300710601b31e00532300531e00525e01b31d00532300531d005", + "0x7b101b02504631a31b04732300531e31d00704201b04634201b044005323", + "0x701b0090057b232400532300702500525c01b046005323005046045007", + "0x32300502d00525a01b03102802d02432300532400525b01b01b32300501b", + "0x32300501b03701b31700532300501b03401b01b32300503100522501b01b", + "0x25e01b31a00532300531a00503101b31b00532300531b00504601b0b0005", + "0x3230050b000503601b31700532300531700530201b028005323005028005", + "0x19200525701b1921f507c0243230050b031702831a31b04625801b0b0005", + "0x732300503700525601b01b32300501b00701b0390057b3037005323007", + "0x16001b21320d00732300503800525501b01b32300503600522501b036038", + "0x72150441f502425301b21500532300521300516201b01b32300520d005", + "0x21b00516401b01b32300501b00701b22221f21e0247b421b217216024323", + "0x3230052250460077b501b22500532300522500516501b225223007323005", + "0x22c0073230052232290077b501b22300532300522300516501b04b229007", + "0x5000520a01b05300532300505300516501b05000532300501b20c01b053", + "0x5400528601b24305405102432300505005307c02420601b050005323005", + "0x1b25100532300504b0050bb01b24f0053230052430050bb01b01b323005", + "0x505800502501b05800532300505624f00720201b05600532300501b203", + "0x570053230052510580072b301b25100532300525100502501b058005323", + "0x2c60057b701b2c60053230050550057b601b05500532300505700520001b", + "0x21600532300521600503101b05100532300505100504601b2c9005323005", + "0x2c90057b801b21700532300521700531701b22c00532300522c00509f01b", + "0x504601b01b32300501b00701b2c921722c2160510460052c9005323005", + "0x532300521f00531701b03300532300521e00503101b2d300532300507c", + "0x32300501b00701b01b7b900501b19301b2ef00532300522200521f01b060", + "0x504601b01b32300506300524401b06206300732300503900517501b01b", + "0x532300504400531701b0330053230051f500503101b2d300532300507c", + "0x32300501b00701b01b7b900501b19301b2ef00532300506200521f01b060", + "0x504601b01b32300530600524401b00630600732300500900517501b01b", + "0x532300504400531701b03300532300531a00503101b2d300532300531b", + "0x6a00702d01b06a00532300501b00901b2ef00532300500600521f01b060", + "0x53230052d300504601b30700532300506c0057ba01b06c0053230052ef", + "0x531701b04600532300504600509f01b03300532300503300503101b2d3", + "0x3070600460332d30460053070053230053070057b801b060005323005060", + "0x1b32300504300513c01b01b3230050450057bb01b01b32300501b00701b", + "0x700057ba01b07000532300503e06f00702d01b06f00532300501b00901b", + "0x19300532300519300503101b01b00532300501b00504601b072005323005", + "0x720057b801b03f00532300503f00531701b00700532300500700509f01b", + "0x4702400732300500500516401b07203f00719301b046005072005323005", + "0x69d01b04402400732300502400569d01b04504600732300500700516401b", + "0x6d801b0400410420243230050430440077bc01b043046007323005046005", + "0x240077bc01b03f04500732300504500569d01b19300532300504001b007", + "0x200247bd01b02000532300507d1930076d801b07d02303e02432300503f", + "0x1b7bf01b01b32300501b00701b31d31e0077be31f321007323007023042", + "0x2500532300531f00516501b31a00532300532100504601b31b005323005", + "0x1b32300501b00701b01b7c100501b19301b32400532300531b0057c001b", + "0x531d00516501b31a00532300531e00504601b00900532300501b7c201b", + "0x2d04700732300504700569d01b3240053230050090057c001b025005323", + "0xb000532300531731a0076d801b31703102802432300504602d0077bc01b", + "0x32300501b00701b0371920077c31f507c0073230070310250b00247bd01b", + "0x1f500516501b03800532300507c00504601b03900532300501b7bf01b01b", + "0x701b01b7c400501b19301b20d0053230050390057c001b036005323005", + "0x1b03800532300519200504601b21300532300501b7c201b01b32300501b", + "0x3e0380247bd01b20d0053230052130057c001b036005323005037005165", + "0x501b7bf01b01b32300501b00701b21b2170077c5216215007323007028", + "0x1b22200532300521600516501b21f00532300521500504601b21e005323", + "0x1b01b32300501b00701b01b7c600501b19301b22300532300521e0057c0", + "0x32300521b00516501b21f00532300521700504601b22500532300501b7c2", + "0x4b2290243230050450470077bc01b2230053230052250057c001b222005", + "0x5000732300704b2220530247bd01b05300532300522c21f0076d801b22c", + "0x4601b24f00532300501b7bf01b01b32300501b00701b2430540077c7051", + "0x32300524f0057c001b05600532300505100516501b251005323005050005", + "0x532300501b7c201b01b32300501b00701b01b7c800501b19301b058005", + "0x57c001b05600532300524300516501b25100532300505400504601b057", + "0x3230050550057c901b05500532300520d32400732e01b058005323005057", + "0x2c90073230072c60562510247bd01b2c60053230052c600516501b2c6005", + "0x4601b2ef00532300501b7bf01b01b32300501b00701b0600330077ca2d3", + "0x3230052ef0057c001b0620053230052d300516501b0630053230052c9005", + "0x532300501b7c201b01b32300501b00701b01b7cb00501b19301b306005", + "0x57c001b06200532300506000516501b06300532300503300504601b006", + "0x32300506a0057cc01b06a00532300505822300732e01b306005323005006", + "0x1b30700532300506c0057ce01b06c00532300530606a0077cd01b06a005", + "0x77cf07006f0073230073072290630247bd01b307005323005307005165", + "0x7000516501b03400532300506f00504601b01b32300501b00701b305072", + "0x7200504601b01b32300501b00701b01b7d000501b19301b077005323005", + "0x50770620360410477d101b07700532300530500516501b034005323005", + "0x53020053230053020057d201b03400532300503400504601b302005323", + "0x501b00701b0470057d402400700732300700501b0077d301b302034007", + "0x4601b0460053230050460057d601b0460053230050240057d501b01b323", + "0x430057d90440057d804500532307d0460057d701b007005323005007005", + "0x57e003e0057df03f0057de1930057dd0400057dc0410057db0420057da", + "0x1b31d0057e631e0057e531f0057e43210057e30200057e207d0057e1023", + "0x1b31b00532300501b26401b01b32300504500522501b01b32300501b007", + "0x1b01b32300501b00701b01b7e700501b19301b31a00532300531b005165", + "0x532300502500516501b02500532300501b7e801b01b323005044005225", + "0x1b32300504300522501b01b32300501b00701b01b7e700501b19301b31a", + "0x7e700501b19301b31a00532300532400516501b32400532300501b7e901b", + "0x532300501b7ea01b01b32300504200522501b01b32300501b00701b01b", + "0x32300501b00701b01b7e700501b19301b31a00532300500900516501b009", + "0x502d00516501b02d00532300501b7eb01b01b32300504100522501b01b", + "0x504000522501b01b32300501b00701b01b7e700501b19301b31a005323", + "0x1b19301b31a00532300502800516501b02800532300501b7ec01b01b323", + "0x501b7ed01b01b32300519300522501b01b32300501b00701b01b7e7005", + "0x1b00701b01b7e700501b19301b31a00532300503100516501b031005323", + "0x516501b31700532300501b7ee01b01b32300503f00522501b01b323005", + "0x522501b01b32300501b00701b01b7e700501b19301b31a005323005317", + "0x1b31a0053230050b000516501b0b000532300501b7ef01b01b32300503e", + "0x7f001b01b32300502300522501b01b32300501b00701b01b7e700501b193", + "0x1b01b7e700501b19301b31a00532300507c00516501b07c00532300501b", + "0x1b1f500532300501b7f101b01b32300507d00522501b01b32300501b007", + "0x1b01b32300501b00701b01b7e700501b19301b31a0053230051f5005165", + "0x532300519200516501b19200532300501b7f201b01b323005020005225", + "0x1b32300532100522501b01b32300501b00701b01b7e700501b19301b31a", + "0x7e700501b19301b31a00532300503700516501b03700532300501b7f301b", + "0x532300501b7f401b01b32300531f00522501b01b32300501b00701b01b", + "0x32300501b00701b01b7e700501b19301b31a00532300503900516501b039", + "0x503800516501b03800532300501b7f501b01b32300531e00522501b01b", + "0x531d00522501b01b32300501b00701b01b7e700501b19301b31a005323", + "0x57f701b31a00532300503600516501b03600532300501b7f601b01b323", + "0x532300500700504601b21300532300520d0057f801b20d00532300531a", + "0x1b01b32300501b00701b21300700700521300532300521300534401b007", + "0x532300521600502501b21600532300501b7f901b21500532300501b31b", + "0x702d01b21b00532300501b00901b21700532300521621500732401b216", + "0x32300504700504601b21f00532300521e0057fa01b21e00532300521721b", + "0x1b32300501b02001b21f04700700521f00532300521f00534401b047005", + "0x1b32300501b00701b0430440077fb04504600732300700501b00700501b", + "0x32300504600504601b01b32300501b04701b04200532300502400557601b", + "0x1b32300501b00701b1930057fc04004100732300704200557701b046005", + "0x3f00557a01b03e00532300504100557901b03f00532300504000557801b", + "0x501b03f01b01b32300501b00701b01b7fd00501b19301b023005323005", + "0x1b03e00532300519300557901b02000532300507d00533501b07d005323", + "0x702300557b01b32100532300503e00514601b02300532300502000557a", + "0x31d00532300531f00557c01b01b32300501b00701b31e0057fe31f005323", + "0x700509f01b04600532300504600504601b31b00532300531d00557d01b", + "0x31b00532300531b00514b01b04700532300504700525e01b007005323005", + "0x532300732400525701b32402531a02432300531b0470070460477ff01b", + "0x900525601b01b32300501b02001b01b32300501b00701b02d005800009", + "0x31a00532300531a00504601b01b32300503100522501b031028007323005", + "0x32100515701b02500532300502500509f01b04500532300504500503101b", + "0x2832102504531a04634201b02800532300502800525e01b321005323005", + "0x1b01b32300501b00701b1f507c0b03170470051f507c0b0317047323005", + "0x19200532300502d00557f01b01b32300532100525a01b01b32300501b020", + "0x2500509f01b04500532300504500503101b31a00532300531a00504601b", + "0x701b19202504531a04700519200532300519200558001b025005323005", + "0x1b03f01b01b32300531e00522501b01b32300501b02001b01b32300501b", + "0x32300503900558201b03900532300503704732102458101b037005323005", + "0x9f01b04500532300504500503101b04600532300504600504601b038005", + "0x3800704504604700503800532300503800558001b007005323005007005", + "0x1b32300502400525a01b01b32300504700516001b01b32300501b00701b", + "0x32300520d00502501b20d00532300501b22301b03600532300501b31b01b", + "0x2d01b21500532300501b00901b21300532300520d03600732401b20d005", + "0x504400504601b21700532300521600557f01b216005323005213215007", + "0x1b00700532300500700509f01b04300532300504300503101b044005323", + "0x732300502400516401b217007043044047005217005323005217005580", + "0x1b04300532300501b76a01b0440450073230050460050077b501b046047", + "0x4401b02420601b04300532300504300520a01b044005323005044005165", + "0x4104200776b01b04500532300504500509f01b040041042024323005043", + "0x704019300776b01b01b32300501b00701b03e00580103f193007323007", + "0x32300507d00700713901b01b32300501b00701b02000580207d023007323", + "0x31e0073230050470450077b501b31f00532300503f32100713901b321005", + "0x31b00520a01b31d00532300531d00516501b31b00532300501b76a01b31d", + "0x31f00525e01b32402531a02432300531b31d02302420601b31b005323005", + "0x732300702531a00776b01b31e00532300531e00509f01b31f005323005", + "0x3100732300732400900776b01b01b32300501b00701b02800580302d009", + "0x1b07c00532300531731f00713901b01b32300501b00701b0b0005804317", + "0x1921f500765f01b19200532300501b03f01b1f500532300502d07c007139", + "0x3100532300503100504601b03900532300503700566001b037005323005", + "0x31e03102400503900532300503900533901b31e00532300531e00509f01b", + "0x32300502d00507001b01b32300531f00516001b01b32300501b00701b039", + "0x503600502501b03600532300501b05401b03800532300501b31b01b01b", + "0x2130053230050b000504601b20d00532300503603800732401b036005323", + "0x1b32300501b00701b01b80500501b19301b21500532300520d00521f01b", + "0x532300501b31b01b01b32300532400528601b01b32300531f00516001b", + "0x21600732401b21700532300521700502501b21700532300501b05401b216", + "0x532300521b00521f01b21300532300502800504601b21b005323005217", + "0x564701b21f00532300521521e00702d01b21e00532300501b00901b215", + "0x532300531e00509f01b21300532300521300504601b22200532300521f", + "0x1b32300501b00701b22231e21302400522200532300522200533901b31e", + "0x32300503f00507001b01b32300504700528601b01b32300500700516001b", + "0x522500502501b22500532300501b05401b22300532300501b31b01b01b", + "0x4b00532300502000504601b22900532300522522300732401b225005323", + "0x1b32300501b00701b01b80600501b19301b22c00532300522900521f01b", + "0x32300504000528601b01b32300504700528601b01b32300500700516001b", + "0x505000502501b05000532300501b05401b05300532300501b31b01b01b", + "0x4b00532300503e00504601b05100532300505005300732401b050005323", + "0x22c05400702d01b05400532300501b00901b22c00532300505100521f01b", + "0x4b00532300504b00504601b24f00532300524300564701b243005323005", + "0x4504b02400524f00532300524f00533901b04500532300504500509f01b", + "0x1df01b04701b02400700501b1de1871df01b0471781871df01b04706f24f", + "0x1df01b0471781871df01b0470cb02400700501b1de1871df01b047178187", + "0x700501b1de1871df01b0471781871df01b04714c02400700501b1de187", + "0x1df01b0477ed02400700501b1de1871df01b0471781871df01b04752f024", + "0x1df01b0471781871df01b04780702400700501b1de1871df01b047178187", + "0x700501b1de1871df01b0471781871df01b04780802400700501b1de187", + "0x1df01b04780a02400700501b1de1871df01b0471781871df01b047809024", + "0x1b0461781871df20a01b04680b02400700501b1de1871df01b047178187", + "0x1de1871df01b0471781871df01b04780c04702400700501b1de1871df20a", + "0x80e02400700501b1de1871df01b0471781871df01b04780d02400700501b", + "0x1871df03101b04680f02400700501b1de1871df01b0471781871df01b047", + "0x1b0471781871df01b04781004702400700501b1de1871df03101b046178", + "0x501b1de1871df01b0471781871df01b04781102400700501b1de1871df", + "0x1b04781302400700501b1de1871df01b0471781871df01b047812024007", + "0x1b0471781871df01b04781402400700501b1de1871df01b0471781871df", + "0x501b1de1871df01b0471781871df01b04781502400700501b1de1871df", + "0x22104681702400700501b1de1871df01b0471781871df01b047816024007", + "0x3101b22104581804702400700501b1de1871df01b2210461781871df01b", + "0x1df01b04781904604702400700501b1de1871df03101b2210451781871df", + "0x1b0461781871df22801b04681a02400700501b1de1871df01b047178187", + "0x1df01b2210461781871df01b22104681b04702400700501b1de1871df228", + "0x501b1de1871df01b0471781871df01b04781c04702400700501b1de187", + "0x1b1de1871df0d00d40d201b0441781871df0d00d40d201b04481d024007", + "0x1b1de1871df0d201b0461781871df0d201b04681e045046047024007005", + "0x82002400700501b1de1871df01b0471781871df01b04781f047024007005", + "0x1781871df01b04782102400700501b1de1871df01b0471781871df01b047", + "0x1f61df01b0240060511781df01b04682202400700501b1de1871df01b047", + "0x1b1fd1871df01b0471770891770891871df01b04482304702400700501b", + "0x1df01b02482500501b1ff17801b02417801b007824045046047024007005", + "0x4700600600617b17c19c1871df01b04282600700501b2001df01b024178", + "0x620619c1871df04382704304404504604702400700501b2011871df01b", + "0x1df20a01b04782804404504604702400700501b1de1871df024006006006", + "0x1871df01b04719c1871df01b04782902400700501b20e1df20a01b04720c", + "0x2400700501b2141871df01b04719c1871df01b04782a02400700501b214", + "0x4782c04702400700501b2141870311df01b04619c1870311df01b04682b", + "0x5119c1871df01b04682d02400700501b2141871df01b04719c1871df01b", + "0x2141df01b02400619c1df01b04782e04702400700501b21c1871df01b047", + "0x4383002400700501b2141df01b02400619c1df01b04782f02400700501b", + "0x4604702400700501b2141872211df01b04600600600619c1872211df01b", + "0x19c1872210311df01b04483200501b22417801b02417801b007831044045", + "0x1df22801b04683304504604702400700501b2141872210311df01b045198", + "0x19c1872211df01b04583404702400700501b2141871df22801b04619c187", + "0x1df0d20d00d401b04583504604702400700501b2141872211df01b046006", + "0x2010d20070d200583604604702400700501b2141df0d20d00d401b04519c", + "0x1df01b0240061701781df01b04683800501b23701b00717801b00783701b", + "0x2400700501b2421df01b0241781781df01b04783904702400700501b238", + "0x1601681df01b04783b02400700501b2441df01b0241731731df01b04783a", + "0x1b2521df01b02407b0891601df01b04683c02400700501b2501df01b024", + "0x1b04683e02400700501b25e01b00707b07b13c01b04783d047024007005", + "0x1870311df01b04483f04702400700501b2621871df01b0471411401871df", + "0x1df01b04484004504604702400700501b2791870311df01b04606a27802d", + "0x2c500784104504604702400700501b2861871df01b04711302d02d02d187", + "0x4784302400700501b2ca01b00707b0060aa01b04784200501b0eb0052c5", + "0x8717801b02417801b00784402400700501b2d41df01b0240512d21df01b", + "0x2407b1601df01b04784600700501b25201b00702d16001b02484500501b", + "0x1871df01b04684800501b13c00500613c00784702400700501b2521df01b", + "0x4606f1870311df01b04684904702400700501b3051871df01b04727802d", + "0x501b2c601b00702d02d01b02484a04702400700501b3071870311df01b", + "0x1df01b0471601680311df01b04684c00501b24301b00707b01b00784b007", + "0x700501b25203101b02402d16003101b04784d04702400700501b250031", + "0x84e024" + ], + "sierra_program_debug_info": { + "type_names": [], + "libfunc_names": [], + "user_func_names": [] + }, + "contract_class_version": "0.1.0", + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0x1143aa89c8e3ebf8ed14df2a3606c1cd2dd513fac8040b0f8ab441f5c52fe4", + "function_idx": 20 + }, + { + "selector": "0x3541591104188daef4379e06e92ecce09094a3b381da2e654eb041d00566d8", + "function_idx": 29 + }, + { + "selector": "0x3c118a68e16e12e97ed25cb4901c12f4d3162818669cc44c391d8049924c14", + "function_idx": 5 + }, + { + "selector": "0x5562b3e932b4d139366854d5a2e578382e6a3b6572ac9943d55e7efbe43d00", + "function_idx": 16 + }, + { + "selector": "0x600c98a299d72ef1e09a2e1503206fbc76081233172c65f7e2438ef0069d8d", + "function_idx": 21 + }, + { + "selector": "0x62c83572d28cb834a3de3c1e94977a4191469a4a8c26d1d7bc55305e640ed5", + "function_idx": 17 + }, + { + "selector": "0x679c22735055a10db4f275395763a3752a1e3a3043c192299ab6b574fba8d6", + "function_idx": 25 + }, + { + "selector": "0x7772be8b80a8a33dc6c1f9a6ab820c02e537c73e859de67f288c70f92571bb", + "function_idx": 23 + }, + { + "selector": "0xd47144c49bce05b6de6bce9d5ff0cc8da9420f8945453e20ef779cbea13ad4", + "function_idx": 1 + }, + { + "selector": "0xe7510edcf6e9f1b70f7bd1f488767b50f0363422f3c563160ab77adf62467b", + "function_idx": 8 + }, + { + "selector": "0xf818e4530ec36b83dfe702489b4df537308c3b798b0cc120e32c2056d68b7d", + "function_idx": 12 + }, + { + "selector": "0x10d2fede95e3ec06a875a67219425c27c5bd734d57f1b221d729a2337b6b556", + "function_idx": 10 + }, + { + "selector": "0x12ead94ae9d3f9d2bdb6b847cf255f1f398193a1f88884a0ae8e18f24a037b6", + "function_idx": 27 + }, + { + "selector": "0x14dae1999ae9ab799bc72def6dc6e90890cf8ac0d64525021b7e71d05cb13e8", + "function_idx": 3 + }, + { + "selector": "0x169f135eddda5ab51886052d777a57f2ea9c162d713691b5e04a6d4ed71d47f", + "function_idx": 11 + }, + { + "selector": "0x1ae1a515cf2d214b29bdf63a79ee2d490efd4dd1acc99d383a8e549c3cecb5d", + "function_idx": 26 + }, + { + "selector": "0x23039bef544cff56442d9f61ae9b13cf9e36fcce009102c5b678aac93f37b36", + "function_idx": 4 + }, + { + "selector": "0x27c3334165536f239cfd400ed956eabff55fc60de4fb56728b6a4f6b87db01c", + "function_idx": 2 + }, + { + "selector": "0x2d7cf5d5a324a320f9f37804b1615a533fde487400b41af80f13f7ac5581325", + "function_idx": 9 + }, + { + "selector": "0x30f842021fbf02caf80d09a113997c1e00a32870eee0c6136bed27acb348bea", + "function_idx": 24 + }, + { + "selector": "0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f", + "function_idx": 22 + }, + { + "selector": "0x32564d7e0fe091d49b4c20f4632191e4ed6986bf993849879abfef9465def25", + "function_idx": 18 + }, + { + "selector": "0x3604cea1cdb094a73a31144f14a3e5861613c008e1e879939ebc4827d10cd50", + "function_idx": 6 + }, + { + "selector": "0x382be990ca34815134e64a9ac28f41a907c62e5ad10547f97174362ab94dc89", + "function_idx": 13 + }, + { + "selector": "0x38be5d5f7bf135b52888ba3e440a457d11107aca3f6542e574b016bf3f074d8", + "function_idx": 14 + }, + { + "selector": "0x3a6a8bae4c51d5959683ae246347ffdd96aa5b2bfa68cc8c3a6a7c2ed0be331", + "function_idx": 7 + }, + { + "selector": "0x3b097c62d3e4b85742aadd0dfb823f96134b886ec13bda57b68faf86f294d97", + "function_idx": 0 + }, + { + "selector": "0x3d3da80997f8be5d16e9ae7ee6a4b5f7191d60765a1a6c219ab74269c85cf97", + "function_idx": 28 + }, + { + "selector": "0x3d95049b565ec2d4197a55108ef03996381d31c84acf392a0a42b28163d69d1", + "function_idx": 15 + }, + { + "selector": "0x3eb640b15f75fcc06d43182cdb94ed38c8e71755d5fb57c16dd673b466db1d4", + "function_idx": 19 + } + ], + "L1_HANDLER": [ + { + "selector": "0x205500a208d0d49d79197fea83cc3f5fde99ac2e1909ae0a5d9f394c0c52ed0", + "function_idx": 31 + }, + { + "selector": "0x39edbbb129ad752107a94d40c3873cae369a46fd2fc578d075679aa67e85d12", + "function_idx": 30 + } + ], + "CONSTRUCTOR": [ + { + "selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "function_idx": 32 + } + ] + }, + "abi": [ + { + "type": "constructor", + "name": "constructor", + "inputs": [ + { + "name": "arg1", + "type": "core::felt252" + }, + { + "name": "arg2", + "type": "core::felt252" + } + ] + }, + { + "type": "function", + "name": "test_storage_read_write", + "inputs": [ + { + "name": "address", + "type": "core::starknet::storage_access::StorageAddress" + }, + { + "name": "value", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "test_count_actual_storage_changes", + "inputs": [], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "function", + "name": "test_call_contract", + "inputs": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "entry_point_selector", + "type": "core::felt252" + }, + { + "name": "calldata", + "type": "core::array::Array::" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "test_emit_events", + "inputs": [ + { + "name": "events_number", + "type": "core::integer::u64" + }, + { + "name": "keys", + "type": "core::array::Array::" + }, + { + "name": "data", + "type": "core::array::Array::" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "function", + "name": "test_get_block_hash", + "inputs": [ + { + "name": "block_number", + "type": "core::integer::u64" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "struct", + "name": "core::starknet::info::BlockInfo", + "members": [ + { + "name": "block_number", + "type": "core::integer::u64" + }, + { + "name": "block_timestamp", + "type": "core::integer::u64" + }, + { + "name": "sequencer_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "struct", + "name": "core::starknet::info::v2::ResourceBounds", + "members": [ + { + "name": "resource", + "type": "core::felt252" + }, + { + "name": "max_amount", + "type": "core::integer::u64" + }, + { + "name": "max_price_per_unit", + "type": "core::integer::u128" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "core::starknet::info::v2::TxInfo", + "members": [ + { + "name": "version", + "type": "core::felt252" + }, + { + "name": "account_contract_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "max_fee", + "type": "core::integer::u128" + }, + { + "name": "signature", + "type": "core::array::Span::" + }, + { + "name": "transaction_hash", + "type": "core::felt252" + }, + { + "name": "chain_id", + "type": "core::felt252" + }, + { + "name": "nonce", + "type": "core::felt252" + }, + { + "name": "resource_bounds", + "type": "core::array::Span::" + }, + { + "name": "tip", + "type": "core::integer::u128" + }, + { + "name": "paymaster_data", + "type": "core::array::Span::" + }, + { + "name": "nonce_data_availability_mode", + "type": "core::integer::u32" + }, + { + "name": "fee_data_availability_mode", + "type": "core::integer::u32" + }, + { + "name": "account_deployment_data", + "type": "core::array::Span::" + } + ] + }, + { + "type": "function", + "name": "test_get_execution_info", + "inputs": [ + { + "name": "expected_block_info", + "type": "core::starknet::info::BlockInfo" + }, + { + "name": "expected_tx_info", + "type": "core::starknet::info::v2::TxInfo" + }, + { + "name": "expected_caller_address", + "type": "core::felt252" + }, + { + "name": "expected_contract_address", + "type": "core::felt252" + }, + { + "name": "expected_entry_point_selector", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "function", + "name": "test_library_call", + "inputs": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + }, + { + "name": "function_selector", + "type": "core::felt252" + }, + { + "name": "calldata", + "type": "core::array::Array::" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "test_nested_library_call", + "inputs": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + }, + { + "name": "lib_selector", + "type": "core::felt252" + }, + { + "name": "nested_selector", + "type": "core::felt252" + }, + { + "name": "a", + "type": "core::felt252" + }, + { + "name": "b", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "test_replace_class", + "inputs": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "function", + "name": "test_send_message_to_l1", + "inputs": [ + { + "name": "to_address", + "type": "core::felt252" + }, + { + "name": "payload", + "type": "core::array::Array::" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "function", + "name": "segment_arena_builtin", + "inputs": [], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "l1_handler", + "name": "l1_handle", + "inputs": [ + { + "name": "from_address", + "type": "core::felt252" + }, + { + "name": "arg", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "l1_handler", + "name": "l1_handler_set_value", + "inputs": [ + { + "name": "from_address", + "type": "core::felt252" + }, + { + "name": "key", + "type": "core::starknet::storage_access::StorageAddress" + }, + { + "name": "value", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "function", + "name": "test_deploy", + "inputs": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + }, + { + "name": "contract_address_salt", + "type": "core::felt252" + }, + { + "name": "calldata", + "type": "core::array::Array::" + }, + { + "name": "deploy_from_zero", + "type": "core::bool" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "function", + "name": "test_keccak", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "test_sha256", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "test_secp256k1", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "test_secp256r1", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "assert_eq", + "inputs": [ + { + "name": "x", + "type": "core::felt252" + }, + { + "name": "y", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "invoke_call_chain", + "inputs": [ + { + "name": "call_chain", + "type": "core::array::Array::" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "fail", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "recursive_fail", + "inputs": [ + { + "name": "depth", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "recurse", + "inputs": [ + { + "name": "depth", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "recursive_syscall", + "inputs": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "function_selector", + "type": "core::felt252" + }, + { + "name": "depth", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "advance_counter", + "inputs": [ + { + "name": "index", + "type": "core::felt252" + }, + { + "name": "diff_0", + "type": "core::felt252" + }, + { + "name": "diff_1", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "struct", + "name": "test_contract::test_contract::TestContract::IndexAndValues", + "members": [ + { + "name": "index", + "type": "core::felt252" + }, + { + "name": "values", + "type": "(core::integer::u128, core::integer::u128)" + } + ] + }, + { + "type": "function", + "name": "xor_counters", + "inputs": [ + { + "name": "index_and_x", + "type": "test_contract::test_contract::TestContract::IndexAndValues" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "call_xor_counters", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "index_and_x", + "type": "test_contract::test_contract::TestContract::IndexAndValues" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "test_ec_op", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "add_signature_to_counters", + "inputs": [ + { + "name": "index", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "send_message", + "inputs": [ + { + "name": "to_address", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "function", + "name": "test_circuit", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "test_rc96_holes", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "event", + "name": "test_contract::test_contract::TestContract::Event", + "kind": "enum", + "variants": [] + } + ] +} diff --git a/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract_entrypoint_a.sierra.json b/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract_entrypoint_a.sierra.json new file mode 100644 index 0000000000..1c4fcdf39f --- /dev/null +++ b/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract_entrypoint_a.sierra.json @@ -0,0 +1 @@ +{"sierra_program":["0x1","0x6","0x0","0x2","0x8","0x0","0xa7","0x59","0x18","0x52616e6765436865636b","0x800000000000000100000000000000000000000000000000","0x436f6e7374","0x800000000000000000000000000000000000000000000002","0x1","0x4","0x2","0x4661696c656420746f20646573657269616c697a6520706172616d202331","0x4661696c656420746f20646573657269616c697a6520706172616d202332","0x537472756374","0x800000000000000f00000000000000000000000000000001","0x0","0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3","0x66656c74323532","0x800000000000000700000000000000000000000000000000","0x456e756d","0x800000000000000700000000000000000000000000000003","0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511","0x3","0x4f7574206f6620676173","0x4172726179","0x800000000000000300000000000000000000000000000001","0x536e617073686f74","0x800000000000000700000000000000000000000000000001","0x7","0x800000000000000700000000000000000000000000000002","0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62","0x8","0x9","0xc","0x753332","0x49","0x53746f7261676541646472657373","0x53746f726167654261736541646472657373","0x4275696c74696e436f737473","0x53797374656d","0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672","0x800000000000000300000000000000000000000000000003","0x12","0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6","0xa","0x13","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x426f78","0x4761734275696c74696e","0x34","0x7265766f6b655f61705f747261636b696e67","0x77697468647261775f676173","0x6272616e63685f616c69676e","0x7374727563745f6465636f6e737472756374","0x73746f72655f74656d70","0x61727261795f736e617073686f745f706f705f66726f6e74","0x64726f70","0x16","0x61727261795f6e6577","0x636f6e73745f61735f696d6d656469617465","0x15","0x61727261795f617070656e64","0x7374727563745f636f6e737472756374","0x656e756d5f696e6974","0x14","0x17","0x11","0x6765745f6275696c74696e5f636f737473","0x10","0x77697468647261775f6761735f616c6c","0x73746f726167655f626173655f616464726573735f636f6e7374","0x1275130f95dda36bcbb6e9d28796c1d7e10b6e9fd5ed083e0ede4b12f613528","0x73746f726167655f616464726573735f66726f6d5f62617365","0xd","0xb","0x647570","0xe","0x73746f726167655f77726974655f73797363616c6c","0x66656c743235325f616464","0x736e617073686f745f74616b65","0x6","0x656e61626c655f61705f747261636b696e67","0x756e626f78","0x72656e616d65","0x5","0x6a756d70","0x656e756d5f6d61746368","0x64697361626c655f61705f747261636b696e67","0x13e","0xffffffffffffffff","0x4d","0xf","0x40","0x19","0x1a","0x1b","0x1c","0x1d","0x36","0x1e","0x1f","0x20","0x21","0x22","0x23","0x24","0x25","0x26","0x27","0x28","0x29","0x2a","0x2b","0x2c","0x2d","0x2e","0x2f","0x30","0x31","0x32","0x33","0x35","0x37","0x38","0x91","0x70","0x84","0x130","0xad","0xb2","0x120","0xbc","0xc1","0x10f","0xd6","0xff","0xf4","0x39","0x3a","0x3b","0x3c","0x3d","0x3e","0x3f","0x41","0x42","0x43","0x44","0x45","0x46","0x47","0x48","0x4a","0x4b","0x4c","0x4e","0x4f","0x50","0x51","0x52","0x53","0x54","0x55","0x56","0x57","0x58","0x59","0x5a","0x5b","0x9f","0xb06","0x40313050605120c11100f0e0d0c0b0a090706050403080706050403020100","0x1f0c071e0504031d050d0c1a0a1c051b0c1a0a190518170605161514070605","0x280c2610190527050d0c260a250c0b0a02240f230f220f212007060504030f","0xc0505331d0505320c310c300c2f2e022d0605182c2b07060504032a052905","0x5053b0605053a060505333905053806050537360505351c05053506050534","0xc42410505330c403d0505333f0505333e05053305073d05073c2a05053b27","0x4c0c4b0c4a490505331e0505330605054847050538460505380c4544070543","0x5354d050538060505350c073d05073c2905053b1d05053b19050535190505","0x5053b0c52510505331c0505330c075105073c060505500605054f0c4e1d05","0x56050c0c0c550505053807050538130505350c545105055305075105073c13","0x60c1c0556051305130c0c56050c070c194d07575106075607050c07050c0c","0xc56051d054d0c0c56050c070c470539291d0756071c05510c060556050605","0x470c460556054605290c460556050c1d0c1e0556050c1c0c0c56052905190c","0x3f0556054105490c41055605495807460c580556050c1e0c49055605461e07","0x556053f053f0c070556050705410c510556055105580c060556050605060c","0x27052a0c270556050c270c0c560547054d0c0c56050c070c3f07510606053f","0x556050c390c0c56050c070c363907593d2a075607275106133d0c27055605","0x5a0756055a055a0c5b0556050c000c5a0556050c3e0c000556053e05360c3e","0x56052a05060c5c0556055c05290c0005560500055c0c5b0556055b055b0c5c","0x56050c1c0c0c56050c070c626160135f5e5d0756075c005b073d515d0c2a05","0x56505290c65055605645a075e0c5a0556055a05290c640556050c3e0c6305","0x5620c0c56056705610c68670756056605600c66055605656307470c650556","0x580c2a0556052a05060c6b0556056a05640c6a0556056905630c6905560568","0xc070c6b5e5d2a06056b0556056b053f0c5e0556055e05410c5d0556055d05","0x56d05490c6d055605626c07460c6c0556050c1e0c0c56055a05650c0c5605","0x6e053f0c610556056105410c600556056005580c2a0556052a05060c6e0556","0xc700556050c660c6f0556050c1c0c0c56050c070c6e61602a06056e055605","0x55605717207460c720556050c1e0c71055605706f07470c70055605700529","0x56050705410c360556053605580c390556053905060c740556057305490c73","0x1c0c0c56051305670c0c56050c070c7407363906057405560574053f0c0705","0x1e0c760556052e7507470c2e0556052e05290c2e0556050c660c750556050c","0xc4d0556054d05060c780556057705490c77055605765f07460c5f0556050c","0xc0c7807194d06057805560578053f0c070556050705410c19055605190558","0x556051305130c0c56050c070c194d07795106075607050c07050c0c56050c","0x1d054d0c0c56050c070c47057a291d0756071c05510c060556050605060c1c","0x556054605290c460556050c1d0c1e0556050c1c0c0c56052905190c0c5605","0x54105490c41055605495807460c580556050c1e0c49055605461e07470c46","0x3f053f0c070556050705410c510556055105580c060556050605060c3f0556","0xc270556050c270c0c560547054d0c0c56050c070c3f07510606053f055605","0xc1c0c0c56050c070c3639077b3d2a075607275106133d0c2705560527052a","0x5600c5a055605003e07470c000556050005290c000556050c3e0c3e055605","0x640c5e0556055d05630c5d0556055c05620c0c56055b05610c5c5b0756055a","0xc070556050705410c3d0556053d05580c2a0556052a05060c600556055e05","0x56050c660c610556050c1c0c0c56050c070c60073d2a06056005560560053f","0x636407460c640556050c1e0c63055605626107470c620556056205290c6205","0x5410c360556053605580c390556053905060c660556056505490c65055605","0x56051305670c0c56050c070c6607363906056605560566053f0c0705560507","0x55605686707470c680556056805290c680556050c660c670556050c1c0c0c","0x56054d05060c6c0556056b05490c6b055605696a07460c6a0556050c1e0c69","0x7194d06056c0556056c053f0c070556050705410c190556051905580c4d05","0x1305130c0c56050c070c194d077c5106075607050c07050c0c56050c0c0c6c","0xc47057d291d0756071c05510c060556050605060c0c56050c680c1c055605","0x6c0c4905560546056b0c460556051e056a0c1e0556052905690c0c56050c07","0x56050c6f0c0c56050c070c0c7e050c6e0c4105560549056d0c580556051d05","0x74105710c4105560527056d0c5805560547056c0c270556053f05700c3f05","0xc0c56050c070c3e058036390756075805510c0c56050c070c3d057f2a0556","0x5c05560539056c0c5b0556055a056b0c5a05560500056a0c00055605360569","0x5e05700c5e0556050c6f0c0c56050c070c0c81050c6e0c5d0556055b056d0c","0x620582610556075d05710c5d05560560056d0c5c0556053e056c0c60055605","0xc0c56050c720c0c56050c070c65058364630756075c05510c0c56050c070c","0x50c1c0c0c56052a05650c0c56056105650c0c56056405190c0c560563054d","0x50c1e0c68055605676607470c670556056705290c670556050c1d0c660556","0x5580c060556050605060c6b0556056a05490c6a055605686907460c690556","0x50c070c6b07510606056b0556056b053f0c070556050705410c5105560551","0x76c5106133d0c6c0556056c052a0c6c0556050c270c0c560565054d0c0c56","0x5a0c720556057105360c710556050c390c0c56050c070c706f07846e6d0756","0x7505560575055b0c750556050c000c740556056173075e0c732a0756052a05","0x7275076e515d0c6d0556056d05060c740556057405290c7205560572055c0c","0xc860556050c1c0c0c56050c720c0c56050c070c78775f1385762e07560774","0x556058905620c0c56058805610c89880756058705600c870556052a860747","0x56052e05580c6d0556056d05060c8c0556058b05640c8b0556058a05630c8a","0xc0c56050c070c8c762e6d06058c0556058c053f0c760556057605410c2e05","0x5490c8d055605785907460c590556050c1e0c0c56052a05650c0c56050c72","0x3f0c770556057705410c5f0556055f05580c6d0556056d05060c8e0556058d","0xc56056105650c0c56050c720c0c56050c070c8e775f6d06058e0556058e05","0x470c900556059005290c900556050c660c8f0556050c1c0c0c56052a05650c","0x940556059305490c93055605919207460c920556050c1e0c91055605908f07","0x5560594053f0c070556050705410c700556057005580c6f0556056f05060c","0x55c054d0c0c56056205730c0c56050c720c0c56050c070c9407706f060594","0x950556059505290c950556050c740c200556050c1c0c0c56052a05650c0c56","0x56055705490c57055605969707460c970556050c1e0c96055605952007470c","0x598053f0c070556050705410c510556055105580c060556050605060c9805","0x54d0c0c56053d05730c0c56050c720c0c56050c070c980751060605980556","0x9a9907470c9a0556059a05290c9a0556050c750c990556050c1c0c0c560558","0x5060c9e0556059d05490c9d0556059b9c07460c9c0556050c1e0c9b055605","0x6059e0556059e053f0c070556050705410c510556055105580c0605560506","0xa00556050c660c9f0556050c1c0c0c56051305670c0c56050c070c9e075106","0x5605a1a207460ca20556050c1e0ca1055605a09f07470ca0055605a005290c","0x50705410c190556051905580c4d0556054d05060ca4055605a305490ca305","0x7050c3d3f3e0c061d3f3e0c0613a407194d0605a4055605a4053f0c070556","0x1307050c3d3f3e0c061d3f3e0c06a51307050c3d3f3e0c061d3f3e0c060c13","0xa6"],"sierra_program_debug_info":{"type_names":[[0,"RangeCheck"],[1,"Const"],[2,"Const"],[3,"Unit"],[4,"felt252"],[5,"core::option::Option::"],[6,"Const"],[7,"Array"],[8,"Snapshot>"],[9,"core::array::Span::"],[10,"Tuple>"],[11,"Const"],[12,"u32"],[13,"Const"],[14,"StorageAddress"],[15,"StorageBaseAddress"],[16,"BuiltinCosts"],[17,"System"],[18,"core::panics::Panic"],[19,"Tuple>"],[20,"core::panics::PanicResult::<(core::array::Span::,)>"],[21,"Const"],[22,"Box"],[23,"GasBuiltin"]],"libfunc_names":[[0,"revoke_ap_tracking"],[1,"withdraw_gas"],[2,"branch_align"],[3,"struct_deconstruct>"],[4,"store_temp"],[5,"array_snapshot_pop_front"],[6,"drop>>"],[7,"drop>"],[8,"array_new"],[9,"const_as_immediate>"],[10,"store_temp"],[11,"array_append"],[12,"struct_construct"],[13,"struct_construct>>"],[14,"enum_init,)>, 1>"],[15,"store_temp"],[16,"store_temp"],[17,"store_temp,)>>"],[18,"get_builtin_costs"],[19,"store_temp"],[20,"withdraw_gas_all"],[21,"storage_base_address_const<521780245902522698637863835114646400086704280925471510886115468919502353704>"],[22,"storage_address_from_base"],[23,"const_as_immediate>"],[24,"const_as_immediate>"],[25,"dup"],[26,"store_temp"],[27,"store_temp"],[28,"storage_write_syscall"],[29,"felt252_add"],[30,"snapshot_take>"],[31,"drop>"],[32,"struct_construct>"],[33,"struct_construct>>"],[34,"enum_init,)>, 0>"],[35,"drop"],[36,"const_as_immediate>"],[37,"drop>"],[38,"enable_ap_tracking"],[39,"unbox"],[40,"rename"],[41,"enum_init, 0>"],[42,"store_temp>>"],[43,"store_temp>"],[44,"jump"],[45,"struct_construct"],[46,"enum_init, 1>"],[47,"enum_match>"],[48,"disable_ap_tracking"],[49,"drop"],[50,"const_as_immediate>"],[51,"const_as_immediate>"]],"user_func_names":[[0,"test_contracts::TestContract::__wrapper__get_num"],[1,"test_contracts::TestContract::__wrapper__number_a"],[2,"test_contracts::TestContract::__wrapper__constructor"]]},"contract_class_version":"0.1.0","entry_points_by_type":{"EXTERNAL":[{"selector":"0x15d9e3ddc3010201d5746658f5fe8ace001ef8f271b83fa78558aa1e2adef1a","function_idx":1},{"selector":"0x1c659e9390feb38b127ccb1d3c1101dd77161ebdc45a31d8a64f586187cc3a2","function_idx":0}],"L1_HANDLER":[],"CONSTRUCTOR":[{"selector":"0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194","function_idx":2}]},"abi":[{"type":"constructor","name":"constructor","inputs":[{"name":"arg1","type":"core::felt252"},{"name":"arg2","type":"core::felt252"}]},{"type":"function","name":"get_num","inputs":[],"outputs":[{"type":"core::felt252"}],"state_mutability":"external"},{"type":"function","name":"number_a","inputs":[],"outputs":[{"type":"core::felt252"}],"state_mutability":"external"},{"type":"event","name":"test_contracts::TestContract::Event","kind":"enum","variants":[]}]} \ No newline at end of file diff --git a/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract_entrypoint_b.sierra.json b/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract_entrypoint_b.sierra.json new file mode 100644 index 0000000000..29c6f18084 --- /dev/null +++ b/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract_entrypoint_b.sierra.json @@ -0,0 +1 @@ +{"sierra_program":["0x1","0x6","0x0","0x2","0x8","0x0","0xa7","0x59","0x18","0x52616e6765436865636b","0x800000000000000100000000000000000000000000000000","0x436f6e7374","0x800000000000000000000000000000000000000000000002","0x1","0x4","0x2","0x4661696c656420746f20646573657269616c697a6520706172616d202331","0x4661696c656420746f20646573657269616c697a6520706172616d202332","0x537472756374","0x800000000000000f00000000000000000000000000000001","0x0","0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3","0x66656c74323532","0x800000000000000700000000000000000000000000000000","0x456e756d","0x800000000000000700000000000000000000000000000003","0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511","0x3","0x4f7574206f6620676173","0x4172726179","0x800000000000000300000000000000000000000000000001","0x536e617073686f74","0x800000000000000700000000000000000000000000000001","0x7","0x800000000000000700000000000000000000000000000002","0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62","0x8","0x9","0xc","0x753332","0x49","0x53746f7261676541646472657373","0x53746f726167654261736541646472657373","0x4275696c74696e436f737473","0x53797374656d","0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672","0x800000000000000300000000000000000000000000000003","0x12","0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6","0xa","0x13","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x426f78","0x4761734275696c74696e","0x34","0x7265766f6b655f61705f747261636b696e67","0x77697468647261775f676173","0x6272616e63685f616c69676e","0x7374727563745f6465636f6e737472756374","0x73746f72655f74656d70","0x61727261795f736e617073686f745f706f705f66726f6e74","0x64726f70","0x16","0x61727261795f6e6577","0x636f6e73745f61735f696d6d656469617465","0x15","0x61727261795f617070656e64","0x7374727563745f636f6e737472756374","0x656e756d5f696e6974","0x14","0x17","0x11","0x6765745f6275696c74696e5f636f737473","0x10","0x77697468647261775f6761735f616c6c","0x73746f726167655f626173655f616464726573735f636f6e7374","0x1275130f95dda36bcbb6e9d28796c1d7e10b6e9fd5ed083e0ede4b12f613528","0x73746f726167655f616464726573735f66726f6d5f62617365","0xd","0xb","0x647570","0xe","0x73746f726167655f77726974655f73797363616c6c","0x66656c743235325f616464","0x736e617073686f745f74616b65","0x6","0x656e61626c655f61705f747261636b696e67","0x756e626f78","0x72656e616d65","0x5","0x6a756d70","0x656e756d5f6d61746368","0x64697361626c655f61705f747261636b696e67","0x13e","0xffffffffffffffff","0x4d","0xf","0x40","0x19","0x1a","0x1b","0x1c","0x1d","0x36","0x1e","0x1f","0x20","0x21","0x22","0x23","0x24","0x25","0x26","0x27","0x28","0x29","0x2a","0x2b","0x2c","0x2d","0x2e","0x2f","0x30","0x31","0x32","0x33","0x35","0x37","0x38","0x91","0x70","0x84","0x130","0xad","0xb2","0x120","0xbc","0xc1","0x10f","0xd6","0xff","0xf4","0x39","0x3a","0x3b","0x3c","0x3d","0x3e","0x3f","0x41","0x42","0x43","0x44","0x45","0x46","0x47","0x48","0x4a","0x4b","0x4c","0x4e","0x4f","0x50","0x51","0x52","0x53","0x54","0x55","0x56","0x57","0x58","0x59","0x5a","0x5b","0x9f","0xb06","0x40313050605120c11100f0e0d0c0b0a090706050403080706050403020100","0x1f0c071e0504031d050d0c1a0a1c051b0c1a0a190518170605161514070605","0x280c2610190527050d0c260a250c0b0a02240f230f220f212007060504030f","0xc0505331d0505320c310c300c2f2e022d0605182c2b07060504032a052905","0x5053b0605053a060505333905053806050537360505351c05053506050534","0xc42410505330c403d0505333f0505333e05053305073d05073c2a05053b27","0x4c0c4b0c4a490505331e0505330605054847050538460505380c4544070543","0x5354d050538060505350c073d05073c2905053b1d05053b19050535190505","0x5053b0c52510505331c0505330c075105073c060505500605054f0c4e1d05","0x56050c0c0c550505053807050538130505350c545105055305075105073c13","0x60c1c0556051305130c0c56050c070c194d07575106075607050c07050c0c","0xc56051d054d0c0c56050c070c470539291d0756071c05510c060556050605","0x470c460556054605290c460556050c1d0c1e0556050c1c0c0c56052905190c","0x3f0556054105490c41055605495807460c580556050c1e0c49055605461e07","0x556053f053f0c070556050705410c510556055105580c060556050605060c","0x27052a0c270556050c270c0c560547054d0c0c56050c070c3f07510606053f","0x556050c390c0c56050c070c363907593d2a075607275106133d0c27055605","0x5a0756055a055a0c5b0556050c000c5a0556050c3e0c000556053e05360c3e","0x56052a05060c5c0556055c05290c0005560500055c0c5b0556055b055b0c5c","0x56050c1c0c0c56050c070c626160135f5e5d0756075c005b073d515d0c2a05","0x56505290c65055605645a075e0c5a0556055a05290c640556050c3e0c6305","0x5620c0c56056705610c68670756056605600c66055605656307470c650556","0x580c2a0556052a05060c6b0556056a05640c6a0556056905630c6905560568","0xc070c6b5e5d2a06056b0556056b053f0c5e0556055e05410c5d0556055d05","0x56d05490c6d055605626c07460c6c0556050c1e0c0c56055a05650c0c5605","0x6e053f0c610556056105410c600556056005580c2a0556052a05060c6e0556","0xc700556050c660c6f0556050c1c0c0c56050c070c6e61602a06056e055605","0x55605717207460c720556050c1e0c71055605706f07470c70055605700529","0x56050705410c360556053605580c390556053905060c740556057305490c73","0x1c0c0c56051305670c0c56050c070c7407363906057405560574053f0c0705","0x1e0c760556052e7507470c2e0556052e05290c2e0556050c660c750556050c","0xc4d0556054d05060c780556057705490c77055605765f07460c5f0556050c","0xc0c7807194d06057805560578053f0c070556050705410c19055605190558","0x556051305130c0c56050c070c194d07795106075607050c07050c0c56050c","0x1d054d0c0c56050c070c47057a291d0756071c05510c060556050605060c1c","0x556054605290c460556050c1d0c1e0556050c1c0c0c56052905190c0c5605","0x54105490c41055605495807460c580556050c1e0c49055605461e07470c46","0x3f053f0c070556050705410c510556055105580c060556050605060c3f0556","0xc270556050c270c0c560547054d0c0c56050c070c3f07510606053f055605","0xc1c0c0c56050c070c3639077b3d2a075607275106133d0c2705560527052a","0x5600c5a055605003e07470c000556050005290c000556050c3e0c3e055605","0x640c5e0556055d05630c5d0556055c05620c0c56055b05610c5c5b0756055a","0xc070556050705410c3d0556053d05580c2a0556052a05060c600556055e05","0x56050c660c610556050c1c0c0c56050c070c60073d2a06056005560560053f","0x636407460c640556050c1e0c63055605626107470c620556056205290c6205","0x5410c360556053605580c390556053905060c660556056505490c65055605","0x56051305670c0c56050c070c6607363906056605560566053f0c0705560507","0x55605686707470c680556056805290c680556050c660c670556050c1c0c0c","0x56054d05060c6c0556056b05490c6b055605696a07460c6a0556050c1e0c69","0x7194d06056c0556056c053f0c070556050705410c190556051905580c4d05","0x1305130c0c56050c070c194d077c5106075607050c07050c0c56050c0c0c6c","0xc47057d291d0756071c05510c060556050605060c0c56050c680c1c055605","0x6c0c4905560546056b0c460556051e056a0c1e0556052905690c0c56050c07","0x56050c6f0c0c56050c070c0c7e050c6e0c4105560549056d0c580556051d05","0x74105710c4105560527056d0c5805560547056c0c270556053f05700c3f05","0xc0c56050c070c3e058036390756075805510c0c56050c070c3d057f2a0556","0x5c05560539056c0c5b0556055a056b0c5a05560500056a0c00055605360569","0x5e05700c5e0556050c6f0c0c56050c070c0c81050c6e0c5d0556055b056d0c","0x620582610556075d05710c5d05560560056d0c5c0556053e056c0c60055605","0xc0c56050c720c0c56050c070c65058364630756075c05510c0c56050c070c","0x50c1c0c0c56052a05650c0c56056105650c0c56056405190c0c560563054d","0x50c1e0c68055605676607470c670556056705290c670556050c1d0c660556","0x5580c060556050605060c6b0556056a05490c6a055605686907460c690556","0x50c070c6b07510606056b0556056b053f0c070556050705410c5105560551","0x76c5106133d0c6c0556056c052a0c6c0556050c270c0c560565054d0c0c56","0x5a0c720556057105360c710556050c390c0c56050c070c706f07846e6d0756","0x7505560575055b0c750556050c000c740556056173075e0c732a0756052a05","0x7275076e515d0c6d0556056d05060c740556057405290c7205560572055c0c","0xc860556050c1c0c0c56050c720c0c56050c070c78775f1385762e07560774","0x556058905620c0c56058805610c89880756058705600c870556052a860747","0x56052e05580c6d0556056d05060c8c0556058b05640c8b0556058a05630c8a","0xc0c56050c070c8c762e6d06058c0556058c053f0c760556057605410c2e05","0x5490c8d055605785907460c590556050c1e0c0c56052a05650c0c56050c72","0x3f0c770556057705410c5f0556055f05580c6d0556056d05060c8e0556058d","0xc56056105650c0c56050c720c0c56050c070c8e775f6d06058e0556058e05","0x470c900556059005290c900556050c660c8f0556050c1c0c0c56052a05650c","0x940556059305490c93055605919207460c920556050c1e0c91055605908f07","0x5560594053f0c070556050705410c700556057005580c6f0556056f05060c","0x55c054d0c0c56056205730c0c56050c720c0c56050c070c9407706f060594","0x950556059505290c950556050c740c200556050c1c0c0c56052a05650c0c56","0x56055705490c57055605969707460c970556050c1e0c96055605952007470c","0x598053f0c070556050705410c510556055105580c060556050605060c9805","0x54d0c0c56053d05730c0c56050c720c0c56050c070c980751060605980556","0x9a9907470c9a0556059a05290c9a0556050c750c990556050c1c0c0c560558","0x5060c9e0556059d05490c9d0556059b9c07460c9c0556050c1e0c9b055605","0x6059e0556059e053f0c070556050705410c510556055105580c0605560506","0xa00556050c660c9f0556050c1c0c0c56051305670c0c56050c070c9e075106","0x5605a1a207460ca20556050c1e0ca1055605a09f07470ca0055605a005290c","0x50705410c190556051905580c4d0556054d05060ca4055605a305490ca305","0x7050c3d3f3e0c061d3f3e0c0613a407194d0605a4055605a4053f0c070556","0x1307050c3d3f3e0c061d3f3e0c06a51307050c3d3f3e0c061d3f3e0c060c13","0xa6"],"sierra_program_debug_info":{"type_names":[[0,"RangeCheck"],[1,"Const"],[2,"Const"],[3,"Unit"],[4,"felt252"],[5,"core::option::Option::"],[6,"Const"],[7,"Array"],[8,"Snapshot>"],[9,"core::array::Span::"],[10,"Tuple>"],[11,"Const"],[12,"u32"],[13,"Const"],[14,"StorageAddress"],[15,"StorageBaseAddress"],[16,"BuiltinCosts"],[17,"System"],[18,"core::panics::Panic"],[19,"Tuple>"],[20,"core::panics::PanicResult::<(core::array::Span::,)>"],[21,"Const"],[22,"Box"],[23,"GasBuiltin"]],"libfunc_names":[[0,"revoke_ap_tracking"],[1,"withdraw_gas"],[2,"branch_align"],[3,"struct_deconstruct>"],[4,"store_temp"],[5,"array_snapshot_pop_front"],[6,"drop>>"],[7,"drop>"],[8,"array_new"],[9,"const_as_immediate>"],[10,"store_temp"],[11,"array_append"],[12,"struct_construct"],[13,"struct_construct>>"],[14,"enum_init,)>, 1>"],[15,"store_temp"],[16,"store_temp"],[17,"store_temp,)>>"],[18,"get_builtin_costs"],[19,"store_temp"],[20,"withdraw_gas_all"],[21,"storage_base_address_const<521780245902522698637863835114646400086704280925471510886115468919502353704>"],[22,"storage_address_from_base"],[23,"const_as_immediate>"],[24,"const_as_immediate>"],[25,"dup"],[26,"store_temp"],[27,"store_temp"],[28,"storage_write_syscall"],[29,"felt252_add"],[30,"snapshot_take>"],[31,"drop>"],[32,"struct_construct>"],[33,"struct_construct>>"],[34,"enum_init,)>, 0>"],[35,"drop"],[36,"const_as_immediate>"],[37,"drop>"],[38,"enable_ap_tracking"],[39,"unbox"],[40,"rename"],[41,"enum_init, 0>"],[42,"store_temp>>"],[43,"store_temp>"],[44,"jump"],[45,"struct_construct"],[46,"enum_init, 1>"],[47,"enum_match>"],[48,"disable_ap_tracking"],[49,"drop"],[50,"const_as_immediate>"],[51,"const_as_immediate>"]],"user_func_names":[[0,"test_contracts::TestContract::__wrapper__get_num"],[1,"test_contracts::TestContract::__wrapper__number_b"],[2,"test_contracts::TestContract::__wrapper__constructor"]]},"contract_class_version":"0.1.0","entry_points_by_type":{"EXTERNAL":[{"selector":"0x1c659e9390feb38b127ccb1d3c1101dd77161ebdc45a31d8a64f586187cc3a2","function_idx":0},{"selector":"0x1e387efac81ec38762d5cbdc900314fb40c0d2d16e9fea8624ddd8043a3b056","function_idx":1}],"L1_HANDLER":[],"CONSTRUCTOR":[{"selector":"0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194","function_idx":2}]},"abi":[{"type":"constructor","name":"constructor","inputs":[{"name":"arg1","type":"core::felt252"},{"name":"arg2","type":"core::felt252"}]},{"type":"function","name":"get_num","inputs":[],"outputs":[{"type":"core::felt252"}],"state_mutability":"external"},{"type":"function","name":"number_b","inputs":[],"outputs":[{"type":"core::felt252"}],"state_mutability":"external"},{"type":"event","name":"test_contracts::TestContract::Event","kind":"enum","variants":[]}]} \ No newline at end of file diff --git a/crates/blockifier/feature_contracts/cairo1/compiled/test_contract_execution_info_v1.sierra.json b/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract_execution_info_v1.sierra.json similarity index 99% rename from crates/blockifier/feature_contracts/cairo1/compiled/test_contract_execution_info_v1.sierra.json rename to crates/blockifier/feature_contracts/cairo_native/compiled/test_contract_execution_info_v1.sierra.json index 3ca68f45db..7ed0ada701 100644 --- a/crates/blockifier/feature_contracts/cairo1/compiled/test_contract_execution_info_v1.sierra.json +++ b/crates/blockifier/feature_contracts/cairo_native/compiled/test_contract_execution_info_v1.sierra.json @@ -4,7 +4,7 @@ "0x6", "0x0", "0x2", - "0x7", + "0x8", "0x0", "0x17a", "0x86", @@ -95,7 +95,7 @@ "0x800000000000000f00000000000000000000000000000002", "0xcc5e86243f861d2d64b08c35db21013e773ac5cf10097946fe0011304886d5", "0x36", - "0x36e3bf0277e7c1bb9cd72f230a2d616855c6cadbec152c14c3477ef805df7e2", + "0x371a38276a14d2475f9072073e9ab9b154a40bb41edce5be7d1ade8ccbeb2e4", "0x4275696c74696e436f737473", "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", "0x35", @@ -892,9 +892,9 @@ }, { "type": "event", - "name": "sierra_test_contract::sierra_test_contract::TestContract::Event", + "name": "test_contract_execution_info_v1::test_contract_execution_info_v1::TestContract::Event", "kind": "enum", "variants": [] } ] -} \ No newline at end of file +} diff --git a/crates/blockifier/feature_contracts/cairo_native/test_contract.cairo b/crates/blockifier/feature_contracts/cairo_native/test_contract.cairo new file mode 100644 index 0000000000..5816db5c59 --- /dev/null +++ b/crates/blockifier/feature_contracts/cairo_native/test_contract.cairo @@ -0,0 +1,573 @@ +#[starknet::contract] +mod TestContract { + use box::BoxTrait; + use core::sha256::{compute_sha256_u32_array, sha256_state_handle_init, SHA256_INITIAL_STATE}; + use dict::Felt252DictTrait; + use ec::EcPointTrait; + use starknet::ClassHash; + use starknet::ContractAddress; + use starknet::get_execution_info; + use starknet::StorageAddress; + use array::ArrayTrait; + use clone::Clone; + use core::bytes_31::POW_2_128; + use core::integer::bitwise; + use traits::Into; + use traits::TryInto; + use starknet::{ + class_hash_try_from_felt252, contract_address_try_from_felt252, + eth_address::U256IntoEthAddress, EthAddress, secp256_trait::{Signature, is_valid_signature}, + secp256r1::{Secp256r1Point, Secp256r1Impl}, eth_signature::verify_eth_signature, + info::{BlockInfo, SyscallResultTrait}, info::v2::{ExecutionInfo, TxInfo, ResourceBounds,}, + syscalls + }; + use core::circuit::{ + CircuitElement, CircuitInput, circuit_add, circuit_sub, circuit_mul, circuit_inverse, + EvalCircuitResult, EvalCircuitTrait, u384, CircuitOutputsTrait, + CircuitModulus, CircuitInputs, AddInputResultTrait + }; + + #[storage] + struct Storage { + my_storage_var: felt252, + two_counters: starknet::storage::Map, + ec_point: (felt252, felt252), + } + + #[constructor] + fn constructor(ref self: ContractState, arg1: felt252, arg2: felt252) -> felt252 { + self.my_storage_var.write(arg1 + arg2); + arg1 + } + + #[external(v0)] + fn test_storage_read_write( + self: @ContractState, address: StorageAddress, value: felt252 + ) -> felt252 { + let address_domain = 0; + syscalls::storage_write_syscall(address_domain, address, value).unwrap_syscall(); + syscalls::storage_read_syscall(address_domain, address).unwrap_syscall() + } + + #[external(v0)] + fn test_count_actual_storage_changes(self: @ContractState) { + let storage_address = 15.try_into().unwrap(); + let address_domain = 0; + syscalls::storage_write_syscall(address_domain, storage_address, 0).unwrap_syscall(); + syscalls::storage_write_syscall(address_domain, storage_address, 1).unwrap_syscall(); + } + + #[external(v0)] + #[raw_output] + fn test_call_contract( + self: @ContractState, + contract_address: ContractAddress, + entry_point_selector: felt252, + calldata: Array:: + ) -> Span:: { + syscalls::call_contract_syscall(contract_address, entry_point_selector, calldata.span()) + .unwrap_syscall() + .snapshot + .span() + } + + #[external(v0)] + fn test_emit_events( + self: @ContractState, events_number: u64, keys: Array::, data: Array:: + ) { + let mut c = 0_u64; + loop { + if c == events_number { + break; + } + syscalls::emit_event_syscall(keys.span(), data.span()).unwrap_syscall(); + c += 1; + }; + } + + #[external(v0)] + fn test_get_block_hash(self: @ContractState, block_number: u64) -> felt252 { + syscalls::get_block_hash_syscall(block_number).unwrap_syscall() + } + + #[external(v0)] + fn test_get_execution_info( + self: @ContractState, + expected_block_info: BlockInfo, + expected_tx_info: TxInfo, + // Expected call info. + expected_caller_address: felt252, + expected_contract_address: felt252, + expected_entry_point_selector: felt252, + ) { + let execution_info = starknet::get_execution_info().unbox(); + let block_info = execution_info.block_info.unbox(); + assert(block_info == expected_block_info, 'BLOCK_INFO_MISMATCH'); + + let tx_info = execution_info.tx_info.unbox(); + assert(tx_info == expected_tx_info, 'TX_INFO_MISMATCH'); + + assert(execution_info.caller_address.into() == expected_caller_address, 'CALLER_MISMATCH'); + assert( + execution_info.contract_address.into() == expected_contract_address, 'CONTRACT_MISMATCH' + ); + assert( + execution_info.entry_point_selector == expected_entry_point_selector, + 'SELECTOR_MISMATCH' + ); + } + + #[external(v0)] + #[raw_output] + fn test_library_call( + self: @ContractState, + class_hash: ClassHash, + function_selector: felt252, + calldata: Array + ) -> Span:: { + starknet::library_call_syscall(class_hash, function_selector, calldata.span()) + .unwrap_syscall() + .snapshot + .span() + } + + #[external(v0)] + #[raw_output] + fn test_nested_library_call( + self: @ContractState, + class_hash: ClassHash, + lib_selector: felt252, + nested_selector: felt252, + a: felt252, + b: felt252 + ) -> Span:: { + let mut nested_library_calldata: Array:: = Default::default(); + nested_library_calldata.append(class_hash.into()); + nested_library_calldata.append(nested_selector); + nested_library_calldata.append(2); + nested_library_calldata.append(a + 1); + nested_library_calldata.append(b + 1); + let _res = starknet::library_call_syscall( + class_hash, lib_selector, nested_library_calldata.span(), + ) + .unwrap_syscall(); + + let mut calldata: Array:: = Default::default(); + calldata.append(a); + calldata.append(b); + starknet::library_call_syscall(class_hash, nested_selector, calldata.span()) + .unwrap_syscall() + } + + #[external(v0)] + fn test_replace_class(self: @ContractState, class_hash: ClassHash) { + syscalls::replace_class_syscall(class_hash).unwrap_syscall(); + } + + #[external(v0)] + fn test_send_message_to_l1( + self: @ContractState, to_address: felt252, payload: Array:: + ) { + starknet::send_message_to_l1_syscall(to_address, payload.span()).unwrap_syscall(); + } + + /// An external method that requires the `segment_arena` builtin. + #[external(v0)] + fn segment_arena_builtin(self: @ContractState) { + let x = felt252_dict_new::(); + x.squash(); + } + + #[l1_handler] + fn l1_handle(self: @ContractState, from_address: felt252, arg: felt252) -> felt252 { + arg + } + + #[l1_handler] + fn l1_handler_set_value( + self: @ContractState, from_address: felt252, key: StorageAddress, value: felt252 + ) -> felt252 { + let address_domain = 0; + syscalls::storage_write_syscall(address_domain, key, value).unwrap_syscall(); + value + } + + #[external(v0)] + fn test_deploy( + self: @ContractState, + class_hash: ClassHash, + contract_address_salt: felt252, + calldata: Array::, + deploy_from_zero: bool, + ) { + syscalls::deploy_syscall( + class_hash, contract_address_salt, calldata.span(), deploy_from_zero + ) + .unwrap_syscall(); + } + + + #[external(v0)] + fn test_keccak(ref self: ContractState) { + let mut input: Array:: = Default::default(); + input.append(u256 { low: 1, high: 0 }); + + let res = keccak::keccak_u256s_le_inputs(input.span()); + assert(res.low == 0x587f7cc3722e9654ea3963d5fe8c0748, 'Wrong hash value'); + assert(res.high == 0xa5963aa610cb75ba273817bce5f8c48f, 'Wrong hash value'); + + let mut input: Array:: = Default::default(); + input.append(1_u64); + match syscalls::keccak_syscall(input.span()) { + Result::Ok(_) => panic_with_felt252('Should fail'), + Result::Err(revert_reason) => assert( + *revert_reason.at(0) == 'Invalid input length', 'Wrong error msg' + ), + } + } + + #[external(v0)] + fn test_sha256(ref self: ContractState) { + let mut input: Array:: = Default::default(); + input.append('aaaa'); + + // Test the sha256 syscall computation of the string 'aaaa'. + let [res, _, _, _, _, _, _, _,] = compute_sha256_u32_array(input, 0, 0); + assert(res == 0x61be55a8, 'Wrong hash value'); + } + + #[external(v0)] + fn test_secp256k1(ref self: ContractState) { + // Test a point not on the curve. + assert( + starknet::secp256k1::secp256k1_new_syscall(x: 0, y: 1).unwrap_syscall().is_none(), + 'Should be none' + ); + + let secp256k1_prime = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f; + match starknet::secp256k1::secp256k1_new_syscall(x: secp256k1_prime, y: 1) { + Result::Ok(_) => panic_with_felt252('Should fail'), + Result::Err(revert_reason) => assert( + *revert_reason.at(0) == 'Invalid argument', 'Wrong error msg' + ), + } + + // Test a point on the curve. + let x = 0xF728B4FA42485E3A0A5D2F346BAA9455E3E70682C2094CAC629F6FBED82C07CD; + let y = 0x8E182CA967F38E1BD6A49583F43F187608E031AB54FC0C4A8F0DC94FAD0D0611; + let p0 = starknet::secp256k1::secp256k1_new_syscall(x, y).unwrap_syscall().unwrap(); + + let (x_coord, y_coord) = starknet::secp256k1::secp256k1_get_xy_syscall(p0).unwrap_syscall(); + assert(x_coord == x && y_coord == y, 'Unexpected coordinates'); + + let (msg_hash, signature, _expected_public_key_x, _expected_public_key_y, eth_address) = + get_message_and_secp256k1_signature(); + verify_eth_signature(:msg_hash, :signature, :eth_address); + } + + /// Returns a golden valid message hash and its signature, for testing. + fn get_message_and_secp256k1_signature() -> (u256, Signature, u256, u256, EthAddress) { + let msg_hash = 0xe888fbb4cf9ae6254f19ba12e6d9af54788f195a6f509ca3e934f78d7a71dd85; + let r = 0x4c8e4fbc1fbb1dece52185e532812c4f7a5f81cf3ee10044320a0d03b62d3e9a; + let s = 0x4ac5e5c0c0e8a4871583cc131f35fb49c2b7f60e6a8b84965830658f08f7410c; + + let (public_key_x, public_key_y) = ( + 0xa9a02d48081294b9bb0d8740d70d3607feb20876964d432846d9b9100b91eefd, + 0x18b410b5523a1431024a6ab766c89fa5d062744c75e49efb9925bf8025a7c09e + ); + + let eth_address = 0x767410c1bb448978bd42b984d7de5970bcaf5c43_u256.into(); + + (msg_hash, Signature { r, s, y_parity: true }, public_key_x, public_key_y, eth_address) + } + + + #[external(v0)] + fn test_secp256r1(ref self: ContractState) { + // Test a point not on the curve. + assert( + starknet::secp256r1::secp256r1_new_syscall(x: 0, y: 1).unwrap_syscall().is_none(), + 'Should be none' + ); + + let secp256r1_prime = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff; + match starknet::secp256r1::secp256r1_new_syscall(x: secp256r1_prime, y: 1) { + Result::Ok(_) => panic_with_felt252('Should fail'), + Result::Err(revert_reason) => assert( + *revert_reason.at(0) == 'Invalid argument', 'Wrong error msg' + ), + } + + // Test a point on the curve. + let x = 0x502A43CE77C6F5C736A82F847FA95F8C2D483FE223B12B91047D83258A958B0F; + let y = 0xDB0A2E6710C71BA80AFEB3ABDF69D306CE729C7704F4DDF2EAAF0B76209FE1B0; + let p0 = starknet::secp256r1::secp256r1_new_syscall(x, y).unwrap_syscall().unwrap(); + + let (x_coord, y_coord) = starknet::secp256r1::secp256r1_get_xy_syscall(p0).unwrap_syscall(); + assert(x_coord == x && y_coord == y, 'Unexpected coordinates'); + + let (msg_hash, signature, expected_public_key_x, expected_public_key_y, _eth_address) = + get_message_and_secp256r1_signature(); + let public_key = Secp256r1Impl::secp256_ec_new_syscall( + expected_public_key_x, expected_public_key_y + ) + .unwrap_syscall() + .unwrap(); + is_valid_signature::(msg_hash, signature.r, signature.s, public_key); + } + + + /// Returns a golden valid message hash and its signature, for testing. + fn get_message_and_secp256r1_signature() -> (u256, Signature, u256, u256, EthAddress) { + let msg_hash = 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855; + let r = 0xb292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a; + let s = 0x177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e2; + + let (public_key_x, public_key_y) = ( + 0x04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5, + 0x0087d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d + ); + let eth_address = 0x492882426e1cda979008bfaf874ff796eb3bb1c0_u256.into(); + + (msg_hash, Signature { r, s, y_parity: true }, public_key_x, public_key_y, eth_address) + } + + impl ResourceBoundsPartialEq of PartialEq { + #[inline(always)] + fn eq(lhs: @ResourceBounds, rhs: @ResourceBounds) -> bool { + (*lhs.resource == *rhs.resource) + && (*lhs.max_amount == *rhs.max_amount) + && (*lhs.max_price_per_unit == *rhs.max_price_per_unit) + } + #[inline(always)] + fn ne(lhs: @ResourceBounds, rhs: @ResourceBounds) -> bool { + !(*lhs == *rhs) + } + } + + impl TxInfoPartialEq of PartialEq { + #[inline(always)] + fn eq(lhs: @TxInfo, rhs: @TxInfo) -> bool { + (*lhs.version == *rhs.version) + && (*lhs.account_contract_address == *rhs.account_contract_address) + && (*lhs.max_fee == *rhs.max_fee) + && (*lhs.signature == *rhs.signature) + && (*lhs.transaction_hash == *rhs.transaction_hash) + && (*lhs.chain_id == *rhs.chain_id) + && (*lhs.nonce == *rhs.nonce) + && (*lhs.resource_bounds == *rhs.resource_bounds) + && (*lhs.tip == *rhs.tip) + && (*lhs.paymaster_data == *rhs.paymaster_data) + && (*lhs.nonce_data_availability_mode == *rhs.nonce_data_availability_mode) + && (*lhs.fee_data_availability_mode == *rhs.fee_data_availability_mode) + && (*lhs.account_deployment_data == *rhs.account_deployment_data) + } + #[inline(always)] + fn ne(lhs: @TxInfo, rhs: @TxInfo) -> bool { + !(*lhs == *rhs) + } + } + + impl BlockInfoPartialEq of PartialEq { + #[inline(always)] + fn eq(lhs: @BlockInfo, rhs: @BlockInfo) -> bool { + (*lhs.block_number == *rhs.block_number) + && (*lhs.block_timestamp == *rhs.block_timestamp) + && (*lhs.sequencer_address == *rhs.sequencer_address) + } + #[inline(always)] + fn ne(lhs: @BlockInfo, rhs: @BlockInfo) -> bool { + !(*lhs == *rhs) + } + } + + #[external(v0)] + fn assert_eq(ref self: ContractState, x: felt252, y: felt252) -> felt252 { + assert(x == y, 'x != y'); + 'success' + } + + #[external(v0)] + fn invoke_call_chain(ref self: ContractState, mut call_chain: Array::,) -> felt252 { + // If the chain is too short, fail with division by zero. + let len = call_chain.len(); + if len < 3 { + return (1_u8 / 0_u8).into(); + } + + // Pop the parameters for the next call in the chain. + let contract_id = call_chain.pop_front().unwrap(); + let function_selector = call_chain.pop_front().unwrap(); + let call_type = call_chain.pop_front().unwrap(); + + // Choose call type according to the following options: + // 0 - call contract syscall. 1 - library call syscall. other - regular inner call. + // The remaining items of the call_chain array are passed on as calldata. + if call_type == 0 { + let contract_address = contract_address_try_from_felt252(contract_id).unwrap(); + syscalls::call_contract_syscall(contract_address, function_selector, call_chain.span()) + .unwrap_syscall(); + } else if call_type == 1 { + let class_hash = class_hash_try_from_felt252(contract_id).unwrap(); + syscalls::library_call_syscall(class_hash, function_selector, call_chain.span()) + .unwrap_syscall(); + } else { + let invoke_call_chain_selector: felt252 = + 0x0062c83572d28cb834a3de3c1e94977a4191469a4a8c26d1d7bc55305e640ed5; + let fail_selector: felt252 = + 0x032564d7e0fe091d49b4c20f4632191e4ed6986bf993849879abfef9465def25; + if function_selector == invoke_call_chain_selector { + return invoke_call_chain(ref self, call_chain); + } + if function_selector == fail_selector { + fail(ref self); + } + } + return 0; + } + + #[external(v0)] + fn fail(ref self: ContractState) { + panic_with_felt252('fail'); + } + + #[external(v0)] + fn recursive_fail(ref self: ContractState, depth: felt252) { + if depth == 0 { + panic_with_felt252('recursive_fail'); + } + recursive_fail(ref self, depth - 1) + } + + #[external(v0)] + fn recurse(ref self: ContractState, depth: felt252) { + if depth == 0 { + return; + } + recurse(ref self, depth - 1) + } + + #[external(v0)] + fn recursive_syscall( + ref self: ContractState, + contract_address: ContractAddress, + function_selector: felt252, + depth: felt252, + ) { + if depth == 0 { + return; + } + let calldata: Array:: = array![ + contract_address.into(), function_selector, depth - 1 + ]; + syscalls::call_contract_syscall(contract_address, function_selector, calldata.span()) + .unwrap_syscall(); + return; + } + + #[derive(Drop, Serde)] + struct IndexAndValues { + index: felt252, + values: (u128, u128), + } + + #[starknet::interface] + trait MyContract { + fn xor_counters(ref self: TContractState, index_and_x: IndexAndValues); + } + + // Advances the 'two_counters' storage variable by 'diff'. + #[external(v0)] + fn advance_counter(ref self: ContractState, index: felt252, diff_0: felt252, diff_1: felt252) { + let val = self.two_counters.read(index); + let (val_0, val_1) = val; + self.two_counters.write(index, (val_0 + diff_0, val_1 + diff_1)); + } + + #[external(v0)] + fn xor_counters(ref self: ContractState, index_and_x: IndexAndValues) { + let index = index_and_x.index; + let (val_0, val_1) = index_and_x.values; + let counters = self.two_counters.read(index); + let (counter_0, counter_1) = counters; + let counter_0: u128 = counter_0.try_into().unwrap(); + let counter_1: u128 = counter_1.try_into().unwrap(); + let res_0: felt252 = (counter_0 ^ val_0).into(); + let res_1: felt252 = (counter_1 ^ val_1).into(); + self.two_counters.write(index, (res_0, res_1)); + } + + #[external(v0)] + fn call_xor_counters( + ref self: ContractState, address: ContractAddress, index_and_x: IndexAndValues + ) { + MyContractDispatcher { contract_address: address }.xor_counters(index_and_x); + } + + #[external(v0)] + fn test_ec_op(ref self: ContractState) { + let p = EcPointTrait::new( + 0x654fd7e67a123dd13868093b3b7777f1ffef596c2e324f25ceaf9146698482c, + 0x4fad269cbf860980e38768fe9cb6b0b9ab03ee3fe84cfde2eccce597c874fd8 + ) + .unwrap(); + let q = EcPointTrait::new( + 0x3dbce56de34e1cfe252ead5a1f14fd261d520d343ff6b7652174e62976ef44d, + 0x4b5810004d9272776dec83ecc20c19353453b956e594188890b48467cb53c19 + ) + .unwrap(); + let m: felt252 = 0x6d232c016ef1b12aec4b7f88cc0b3ab662be3b7dd7adbce5209fcfdbd42a504; + let res = q.mul(m) + p; + let res_nz = res.try_into().unwrap(); + self.ec_point.write(res_nz.coordinates()); + } + + #[external(v0)] + fn add_signature_to_counters(ref self: ContractState, index: felt252) { + let signature = get_execution_info().unbox().tx_info.unbox().signature; + let val = self.two_counters.read(index); + let (val_0, val_1) = val; + self.two_counters.write(index, (val_0 + *signature.at(0), val_1 + *signature.at(1))); + } + + #[external(v0)] + fn send_message(self: @ContractState, to_address: felt252) { + let mut payload = ArrayTrait::::new(); + payload.append(12); + payload.append(34); + starknet::send_message_to_l1_syscall(to_address, payload.span()).unwrap_syscall(); + } + + #[external(v0)] + fn test_circuit(ref self: ContractState) { + let in1 = CircuitElement::> {}; + let in2 = CircuitElement::> {}; + let add = circuit_add(in1, in2); + let inv = circuit_inverse(add); + let sub = circuit_sub(inv, in2); + let mul = circuit_mul(inv, sub); + + let modulus = TryInto::<_, CircuitModulus>::try_into([7, 0, 0, 0]).unwrap(); + let outputs = + (mul,).new_inputs().next([3, 0, 0, 0]).next([6, 0, 0, 0]).done().eval(modulus).unwrap(); + + assert!(outputs.get_output(mul) == u384 { limb0: 6, limb1: 0, limb2: 0, limb3: 0 }); + } + + // Add drop for these objects as they only have PanicDestruct. + impl AddInputResultDrop of Drop>; + impl CircuitDataDrop of Drop>; + impl CircuitInputAccumulatorDrop of Drop>; + + #[external(v0)] + fn test_rc96_holes(ref self: ContractState) { + test_rc96_holes_helper(); + test_rc96_holes_helper(); + } + + #[inline(never)] + fn test_rc96_holes_helper() { + let in1 = CircuitElement::> {}; + (in1,).new_inputs().next([3, 0, 0, 0]); + } +} \ No newline at end of file diff --git a/crates/blockifier/feature_contracts/cairo_native/test_contract_entrypoint_a.cairo b/crates/blockifier/feature_contracts/cairo_native/test_contract_entrypoint_a.cairo new file mode 100644 index 0000000000..5a0d2f2515 --- /dev/null +++ b/crates/blockifier/feature_contracts/cairo_native/test_contract_entrypoint_a.cairo @@ -0,0 +1,55 @@ +// Basic contract with an external entrypoint function. +// Used for comparison to its counterpart. +// `test_contract_entrypoint_a.cairo` : Has an external entrypoint for function: `number_a`. +// `test_contract_entrypoint_b.cairo` : Has an external entrypoint for function: `number_b`. +// These two contracts both have the same `sierra_program`, and both have an entrypoint with the same signature, +// However, they are different contracts because the function names used for the entrypoints are different. + +#[starknet::contract] +mod TestContract { + #[storage] + struct Storage { + my_storage_var: felt252, + two_counters: starknet::storage::Map, + ec_point: (felt252, felt252), + } + + #[constructor] + fn constructor(ref self: ContractState, arg1: felt252, arg2: felt252) -> felt252 { + self.my_storage_var.write(arg1 + arg2); + arg1 + } + + #[external(v0)] + fn get_num( + ref self: ContractState + ) -> felt252 { + let val_a = number_a(ref self); + let val_b = number_b(ref self); + self.my_storage_var.write(val_a); + val_a + val_b + } + + // Functions for external entrypoints. + // Reference: https://book.cairo-lang.org/ch14-02-contract-functions.html#external-functions + + // Note that although the function signatures are identical, the selector will be different. + // Reference: https://book.cairo-lang.org/ch15-01-contract-class-abi.html?highlight=abi#function-selector + // In the blockifier: `selector_from_name` uses `starknet_keccak` on `entry_point_name`. + + // First contract entrypoint. + #[external(v0)] + fn number_a( + ref self: ContractState + ) -> felt252 { + 73 + } + + // Second contract entrypoint. + // #[external(v0)] + fn number_b( + ref self: ContractState + ) -> felt252 { + 73 + } +} diff --git a/crates/blockifier/feature_contracts/cairo_native/test_contract_entrypoint_b.cairo b/crates/blockifier/feature_contracts/cairo_native/test_contract_entrypoint_b.cairo new file mode 100644 index 0000000000..6a7eb578e8 --- /dev/null +++ b/crates/blockifier/feature_contracts/cairo_native/test_contract_entrypoint_b.cairo @@ -0,0 +1,61 @@ +// Basic contract with an external entrypoint function. +// Used for comparison to its counterpart. +// `test_contract_entrypoint_a.cairo` : Has an external entrypoint for function: `number_a`. +// `test_contract_entrypoint_b.cairo` : Has an external entrypoint for function: `number_b`. +// These two contracts both have the same `sierra_program`, and both have an entrypoint with the same signature, +// However, they are different contracts because the function names used for the entrypoints are different. + +// Compiled with: scarb build +// scarb --version +// scarb 2.8.0 (09590f5fc 2024-08-27) +// cairo: 2.8.0 (https://crates.io/crates/cairo-lang-compiler/2.8.0) +// sierra: 1.6.0 + +#[starknet::contract] +mod TestContract { + #[storage] + struct Storage { + my_storage_var: felt252, + two_counters: starknet::storage::Map, + ec_point: (felt252, felt252), + } + + #[constructor] + fn constructor(ref self: ContractState, arg1: felt252, arg2: felt252) -> felt252 { + self.my_storage_var.write(arg1 + arg2); + arg1 + } + + #[external(v0)] + fn get_num( + ref self: ContractState + ) -> felt252 { + let val_a = number_a(ref self); + let val_b = number_b(ref self); + self.my_storage_var.write(val_a); + val_a + val_b + } + + // Functions for external entrypoints. + // Reference: https://book.cairo-lang.org/ch14-02-contract-functions.html#external-functions + + // Note that although the function signatures are identical, the selector will be different. + // Reference: https://book.cairo-lang.org/ch15-01-contract-class-abi.html?highlight=abi#function-selector + // In the blockifier: `selector_from_name` uses `starknet_keccak` on `entry_point_name`. + + // First contract entrypoint. + // #[external(v0)] + fn number_a( + ref self: ContractState + ) -> felt252 { + 73 + } + + // Second contract entrypoint. + #[external(v0)] + fn number_b( + ref self: ContractState + ) -> felt252 { + 73 + } +} diff --git a/crates/blockifier/feature_contracts/cairo1/test_contract_execution_info_v1.cairo b/crates/blockifier/feature_contracts/cairo_native/test_contract_execution_info_v1.cairo similarity index 100% rename from crates/blockifier/feature_contracts/cairo1/test_contract_execution_info_v1.cairo rename to crates/blockifier/feature_contracts/cairo_native/test_contract_execution_info_v1.cairo diff --git a/crates/blockifier/oz_erc20/Scarb.toml b/crates/blockifier/oz_erc20/Scarb.toml index 009fe12103..67b49138b6 100644 --- a/crates/blockifier/oz_erc20/Scarb.toml +++ b/crates/blockifier/oz_erc20/Scarb.toml @@ -9,4 +9,4 @@ edition = "2023_10" openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts", branch = "release-v0.10.0" } starknet = "2.5.3" -[[target.starknet-contract]] \ No newline at end of file +[[target.starknet-contract]] diff --git a/crates/blockifier/resources/versioned_constants.json b/crates/blockifier/resources/versioned_constants.json index 9789f0fb80..662b22b353 100644 --- a/crates/blockifier/resources/versioned_constants.json +++ b/crates/blockifier/resources/versioned_constants.json @@ -9,18 +9,18 @@ "max_contract_bytecode_size": 81920 }, "invoke_tx_max_n_steps": 10000000, - "l2_resource_gas_costs": { + "archival_data_gas_costs": { "gas_per_data_felt": [ - 128, - 1000 + 5120, + 1 ], "event_key_factor": [ 2, 1 ], "gas_per_code_byte": [ - 875, - 1000 + 1280, + 1 ] }, "disable_cairo0_redeclaration": true, @@ -32,7 +32,6 @@ "entry_point_gas_cost": 1, "step_gas_cost": 827, "range_check_gas_cost": 15 - }, "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", "default_entry_point_selector": 0, @@ -68,7 +67,6 @@ "get_block_hash_gas_cost": { "step_gas_cost": 104, "range_check_gas_cost": 2 - }, "get_execution_info_gas_cost": { "step_gas_cost": 100, @@ -85,6 +83,8 @@ "l1_gas_index": 0, "l1_handler_version": 0, "l2_gas": "L2_GAS", + "l1_data_gas": "L1_DATA", + "l1_data_gas_index": 2, "l2_gas_index": 1, "library_call_gas_cost": { "entry_point_gas_cost": 1, @@ -102,6 +102,10 @@ "range_check_gas_cost": 70, "pedersen_gas_cost": 4130, "bitwise_builtin_gas_cost": 594, + "ecop_gas_cost": 256, + "poseidon_gas_cost": 500, + "add_mod_gas_cost": 234, + "mul_mod_gas_cost": 616, "replace_class_gas_cost": { "step_gas_cost": 100, "range_check_gas_cost": 1 @@ -190,7 +194,7 @@ "os_resources": { "execute_syscalls": { "CallContract": { - "n_steps": 827, + "n_steps": 860, "builtin_instance_counter": { "range_check_builtin": 15 }, @@ -211,7 +215,7 @@ "n_memory_holes": 0 }, "Deploy": { - "n_steps": 1097, + "n_steps": 1128, "builtin_instance_counter": { "pedersen_builtin": 7, "range_check_builtin": 18 @@ -290,7 +294,7 @@ "n_memory_holes": 0 }, "LibraryCall": { - "n_steps": 818, + "n_steps": 836, "builtin_instance_counter": { "range_check_builtin": 15 }, @@ -304,7 +308,7 @@ "n_memory_holes": 0 }, "ReplaceClass": { - "n_steps": 98, + "n_steps": 104, "builtin_instance_counter": { "range_check_builtin": 1 }, @@ -396,14 +400,14 @@ "n_memory_holes": 0 }, "StorageRead": { - "n_steps": 87, + "n_steps": 89, "builtin_instance_counter": { "range_check_builtin": 1 }, "n_memory_holes": 0 }, "StorageWrite": { - "n_steps": 89, + "n_steps": 93, "builtin_instance_counter": { "range_check_builtin": 1 }, @@ -414,10 +418,11 @@ "Declare": { "deprecated_resources": { "constant": { - "n_steps": 2973, + "n_steps": 3161, "builtin_instance_counter": { "pedersen_builtin": 16, - "range_check_builtin": 53 + "range_check_builtin": 56, + "poseidon_builtin": 4 }, "n_memory_holes": 0 }, @@ -429,11 +434,11 @@ }, "resources": { "constant": { - "n_steps": 3079, + "n_steps": 3293, "builtin_instance_counter": { "pedersen_builtin": 4, - "range_check_builtin": 58, - "poseidon_builtin": 10 + "range_check_builtin": 64, + "poseidon_builtin": 14 }, "n_memory_holes": 0 }, @@ -447,7 +452,7 @@ "DeployAccount": { "deprecated_resources": { "constant": { - "n_steps": 4015, + "n_steps": 4114, "builtin_instance_counter": { "pedersen_builtin": 23, "range_check_builtin": 72 @@ -464,10 +469,10 @@ }, "resources": { "constant": { - "n_steps": 4137, + "n_steps": 4263, "builtin_instance_counter": { "pedersen_builtin": 11, - "range_check_builtin": 77, + "range_check_builtin": 80, "poseidon_builtin": 10 }, "n_memory_holes": 0 @@ -484,7 +489,7 @@ "InvokeFunction": { "deprecated_resources": { "constant": { - "n_steps": 3763, + "n_steps": 3854, "builtin_instance_counter": { "pedersen_builtin": 14, "range_check_builtin": 69 @@ -501,10 +506,10 @@ }, "resources": { "constant": { - "n_steps": 3904, + "n_steps": 4027, "builtin_instance_counter": { "pedersen_builtin": 4, - "range_check_builtin": 74, + "range_check_builtin": 77, "poseidon_builtin": 11 }, "n_memory_holes": 0 @@ -521,7 +526,7 @@ "L1Handler": { "deprecated_resources": { "constant": { - "n_steps": 1233, + "n_steps": 1257, "builtin_instance_counter": { "pedersen_builtin": 11, "range_check_builtin": 16 diff --git a/crates/blockifier/resources/versioned_constants_13_0.json b/crates/blockifier/resources/versioned_constants_13_0.json index 103ea7fca0..4cfe84c042 100644 --- a/crates/blockifier/resources/versioned_constants_13_0.json +++ b/crates/blockifier/resources/versioned_constants_13_0.json @@ -24,6 +24,12 @@ "stored_block_hash_buffer": 10, "step_gas_cost": 100, "range_check_gas_cost": 70, + "pedersen_gas_cost": 0, + "bitwise_builtin_gas_cost": 0, + "ecop_gas_cost": 0, + "poseidon_gas_cost": 0, + "add_mod_gas_cost": 0, + "mul_mod_gas_cost": 0, "memory_hole_gas_cost": 10, "initial_gas_cost": { "step_gas_cost": 100000000 diff --git a/crates/blockifier/resources/versioned_constants_13_1.json b/crates/blockifier/resources/versioned_constants_13_1.json index 279612a501..5c46d30d55 100644 --- a/crates/blockifier/resources/versioned_constants_13_1.json +++ b/crates/blockifier/resources/versioned_constants_13_1.json @@ -11,16 +11,16 @@ "invoke_tx_max_n_steps": 4000000, "l2_resource_gas_costs": { "gas_per_data_felt": [ - 128, - 1000 + 5120, + 1 ], "event_key_factor": [ 2, 1 ], "gas_per_code_byte": [ - 875, - 1000 + 35000, + 1 ] }, "max_recursion_depth": 50, @@ -43,6 +43,12 @@ "stored_block_hash_buffer": 10, "step_gas_cost": 100, "range_check_gas_cost": 70, + "pedersen_gas_cost": 0, + "bitwise_builtin_gas_cost": 0, + "ecop_gas_cost": 0, + "poseidon_gas_cost": 0, + "add_mod_gas_cost": 0, + "mul_mod_gas_cost": 0, "memory_hole_gas_cost": 10, "initial_gas_cost": { "step_gas_cost": 100000000 diff --git a/crates/blockifier/resources/versioned_constants_13_1_1.json b/crates/blockifier/resources/versioned_constants_13_1_1.json index a80475fa16..b88333ffc1 100644 --- a/crates/blockifier/resources/versioned_constants_13_1_1.json +++ b/crates/blockifier/resources/versioned_constants_13_1_1.json @@ -11,16 +11,16 @@ "invoke_tx_max_n_steps": 4000000, "l2_resource_gas_costs": { "gas_per_data_felt": [ - 128, - 1000 + 5120, + 1 ], "event_key_factor": [ 2, 1 ], "gas_per_code_byte": [ - 32, - 1000 + 1280, + 1 ] }, "max_recursion_depth": 50, @@ -43,6 +43,12 @@ "stored_block_hash_buffer": 10, "step_gas_cost": 100, "range_check_gas_cost": 70, + "pedersen_gas_cost": 0, + "bitwise_builtin_gas_cost": 0, + "ecop_gas_cost": 0, + "poseidon_gas_cost": 0, + "add_mod_gas_cost": 0, + "mul_mod_gas_cost": 0, "memory_hole_gas_cost": 10, "initial_gas_cost": { "step_gas_cost": 100000000 diff --git a/crates/blockifier/resources/versioned_constants_13_2.json b/crates/blockifier/resources/versioned_constants_13_2.json index a0dd34a749..4df4b0ea41 100644 --- a/crates/blockifier/resources/versioned_constants_13_2.json +++ b/crates/blockifier/resources/versioned_constants_13_2.json @@ -11,16 +11,16 @@ "invoke_tx_max_n_steps": 10000000, "l2_resource_gas_costs": { "gas_per_data_felt": [ - 128, - 1000 + 5120, + 1 ], "event_key_factor": [ 2, 1 ], "gas_per_code_byte": [ - 875, - 1000 + 35000, + 1 ] }, "disable_cairo0_redeclaration": true, @@ -95,7 +95,12 @@ "memory_hole_gas_cost": 10, "nop_entry_point_offset": -1, "range_check_gas_cost": 70, + "pedersen_gas_cost": 0, "bitwise_builtin_gas_cost": 594, + "ecop_gas_cost": 0, + "poseidon_gas_cost": 0, + "add_mod_gas_cost": 0, + "mul_mod_gas_cost": 0, "replace_class_gas_cost": { "step_gas_cost": 50, "syscall_base_gas_cost": 1 diff --git a/crates/papyrus_execution/resources/versioned_constants_13_1.json b/crates/blockifier/resources/versioned_constants_13_2_1.json similarity index 72% rename from crates/papyrus_execution/resources/versioned_constants_13_1.json rename to crates/blockifier/resources/versioned_constants_13_2_1.json index cad391a781..74558bcf5b 100644 --- a/crates/papyrus_execution/resources/versioned_constants_13_1.json +++ b/crates/blockifier/resources/versioned_constants_13_2_1.json @@ -1,24 +1,31 @@ { + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, "gateway": { - "max_calldata_length": 4000, + "max_calldata_length": 5000, "max_contract_bytecode_size": 81920 }, - "invoke_tx_max_n_steps": 4000000, + "invoke_tx_max_n_steps": 10000000, "l2_resource_gas_costs": { + "gas_per_data_felt": [ + 5120, + 1 + ], "event_key_factor": [ 2, 1 ], "gas_per_code_byte": [ - 875, - 1000 - ], - "gas_per_data_felt": [ - 128, - 1000 + 1280, + 1 ] }, + "disable_cairo0_redeclaration": true, "max_recursion_depth": 50, + "segment_arena_cells": false, "os_constants": { "block_hash_contract_address": 1, "call_contract_gas_cost": { @@ -48,8 +55,8 @@ "entry_point_type_external": 0, "entry_point_type_l1_handler": 1, "error_block_number_out_of_range": "Block number out of range", - "error_invalid_argument": "Invalid argument", "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", "error_out_of_gas": "Out of gas", "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", "fee_transfer_gas_cost": { @@ -79,9 +86,21 @@ "library_call_gas_cost": { "call_contract_gas_cost": 1 }, + "sha256_process_block_gas_cost": { + "step_gas_cost": 1852, + "range_check_gas_cost": 65, + "bitwise_builtin_gas_cost": 1115, + "syscall_base_gas_cost": 1 + }, "memory_hole_gas_cost": 10, "nop_entry_point_offset": -1, "range_check_gas_cost": 70, + "pedersen_gas_cost": 0, + "bitwise_builtin_gas_cost": 594, + "ecop_gas_cost": 0, + "poseidon_gas_cost": 0, + "add_mod_gas_cost": 0, + "mul_mod_gas_cost": 0, "replace_class_gas_cost": { "step_gas_cost": 50, "syscall_base_gas_cost": 1 @@ -138,11 +157,6 @@ "step_gas_cost": 50, "syscall_base_gas_cost": 1 }, - "sha256_process_block_gas_cost": { - "range_check_gas_cost": 0, - "step_gas_cost": 0, - "syscall_base_gas_cost": 0 - }, "sierra_array_len_bound": 4294967296, "step_gas_cost": 100, "storage_read_gas_cost": { @@ -173,380 +187,384 @@ "validated": "VALID" }, "os_resources": { - "compute_os_kzg_commitment_info": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, "execute_syscalls": { "CallContract": { + "n_steps": 827, "builtin_instance_counter": { - "range_check_builtin": 20 + "range_check_builtin": 15 }, - "n_memory_holes": 0, - "n_steps": 760 + "n_memory_holes": 0 }, "DelegateCall": { + "n_steps": 713, "builtin_instance_counter": { "range_check_builtin": 19 }, - "n_memory_holes": 0, - "n_steps": 713 + "n_memory_holes": 0 }, "DelegateL1Handler": { + "n_steps": 692, "builtin_instance_counter": { "range_check_builtin": 15 }, - "n_memory_holes": 0, - "n_steps": 692 + "n_memory_holes": 0 }, "Deploy": { + "n_steps": 1097, "builtin_instance_counter": { "pedersen_builtin": 7, - "range_check_builtin": 19 + "range_check_builtin": 18 }, - "n_memory_holes": 0, - "n_steps": 1012 + "n_memory_holes": 0 }, "EmitEvent": { + "n_steps": 61, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 61 + "n_memory_holes": 0 }, "GetBlockHash": { + "n_steps": 104, "builtin_instance_counter": { "range_check_builtin": 2 }, - "n_memory_holes": 0, - "n_steps": 104 + "n_memory_holes": 0 }, "GetBlockNumber": { + "n_steps": 40, "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 40 + "n_memory_holes": 0 }, "GetBlockTimestamp": { + "n_steps": 38, "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 38 + "n_memory_holes": 0 }, "GetCallerAddress": { + "n_steps": 64, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 64 + "n_memory_holes": 0 }, "GetContractAddress": { + "n_steps": 64, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 64 + "n_memory_holes": 0 }, "GetExecutionInfo": { + "n_steps": 64, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 64 + "n_memory_holes": 0 }, "GetSequencerAddress": { + "n_steps": 34, "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 34 + "n_memory_holes": 0 }, "GetTxInfo": { + "n_steps": 64, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 64 + "n_memory_holes": 0 }, "GetTxSignature": { + "n_steps": 44, "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 44 + "n_memory_holes": 0 }, "Keccak": { + "n_steps": 381, "builtin_instance_counter": { "bitwise_builtin": 6, "keccak_builtin": 1, "range_check_builtin": 56 }, - "n_memory_holes": 0, - "n_steps": 381 + "n_memory_holes": 0 }, "LibraryCall": { + "n_steps": 818, "builtin_instance_counter": { - "range_check_builtin": 20 + "range_check_builtin": 15 }, - "n_memory_holes": 0, - "n_steps": 751 + "n_memory_holes": 0 }, "LibraryCallL1Handler": { + "n_steps": 659, "builtin_instance_counter": { "range_check_builtin": 15 }, - "n_memory_holes": 0, - "n_steps": 659 + "n_memory_holes": 0 }, "ReplaceClass": { + "n_steps": 98, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 98 + "n_memory_holes": 0 }, "Secp256k1Add": { + "n_steps": 410, "builtin_instance_counter": { "range_check_builtin": 29 }, - "n_memory_holes": 0, - "n_steps": 408 + "n_memory_holes": 0 }, "Secp256k1GetPointFromX": { + "n_steps": 395, "builtin_instance_counter": { "range_check_builtin": 30 }, - "n_memory_holes": 0, - "n_steps": 393 + "n_memory_holes": 0 }, "Secp256k1GetXy": { + "n_steps": 207, "builtin_instance_counter": { "range_check_builtin": 11 }, - "n_memory_holes": 0, - "n_steps": 205 + "n_memory_holes": 0 }, "Secp256k1Mul": { + "n_steps": 76505, "builtin_instance_counter": { "range_check_builtin": 7045 }, - "n_memory_holes": 0, - "n_steps": 76503 + "n_memory_holes": 0 }, "Secp256k1New": { + "n_steps": 461, "builtin_instance_counter": { "range_check_builtin": 35 }, - "n_memory_holes": 0, - "n_steps": 459 + "n_memory_holes": 0 }, "Secp256r1Add": { + "n_steps": 593, "builtin_instance_counter": { "range_check_builtin": 57 }, - "n_memory_holes": 0, - "n_steps": 591 + "n_memory_holes": 0 }, "Secp256r1GetPointFromX": { + "n_steps": 514, "builtin_instance_counter": { "range_check_builtin": 44 }, - "n_memory_holes": 0, - "n_steps": 512 + "n_memory_holes": 0 }, "Secp256r1GetXy": { + "n_steps": 209, "builtin_instance_counter": { "range_check_builtin": 11 }, - "n_memory_holes": 0, - "n_steps": 207 + "n_memory_holes": 0 }, "Secp256r1Mul": { + "n_steps": 125344, "builtin_instance_counter": { "range_check_builtin": 13961 }, - "n_memory_holes": 0, - "n_steps": 125342 + "n_memory_holes": 0 }, "Secp256r1New": { + "n_steps": 580, "builtin_instance_counter": { "range_check_builtin": 49 }, - "n_memory_holes": 0, - "n_steps": 578 + "n_memory_holes": 0 }, "SendMessageToL1": { + "n_steps": 141, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 139 + "n_memory_holes": 0 }, "Sha256ProcessBlock": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 + "n_steps": 1855, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 1115 + }, + "n_memory_holes": 0 }, "StorageRead": { + "n_steps": 87, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 87 + "n_memory_holes": 0 }, "StorageWrite": { + "n_steps": 89, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 89 + "n_memory_holes": 0 } }, "execute_txs_inner": { "Declare": { "deprecated_resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, "constant": { + "n_steps": 2973, "builtin_instance_counter": { "pedersen_builtin": 16, - "range_check_builtin": 63 + "range_check_builtin": 53 }, - "n_memory_holes": 0, - "n_steps": 2839 + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 } }, "resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, "constant": { + "n_steps": 3079, "builtin_instance_counter": { - "pedersen_builtin": 16, - "range_check_builtin": 63 + "pedersen_builtin": 4, + "range_check_builtin": 58, + "poseidon_builtin": 10 }, - "n_memory_holes": 0, - "n_steps": 2839 + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 } } }, "DeployAccount": { "deprecated_resources": { - "calldata_factor": { + "constant": { + "n_steps": 4015, "builtin_instance_counter": { - "pedersen_builtin": 2 + "pedersen_builtin": 23, + "range_check_builtin": 72 }, - "n_memory_holes": 0, - "n_steps": 21 + "n_memory_holes": 0 }, - "constant": { + "calldata_factor": { + "n_steps": 21, "builtin_instance_counter": { - "pedersen_builtin": 23, - "range_check_builtin": 83 + "pedersen_builtin": 2 }, - "n_memory_holes": 0, - "n_steps": 3792 + "n_memory_holes": 0 } }, "resources": { - "calldata_factor": { + "constant": { + "n_steps": 4137, "builtin_instance_counter": { - "pedersen_builtin": 2 + "pedersen_builtin": 11, + "range_check_builtin": 77, + "poseidon_builtin": 10 }, - "n_memory_holes": 0, - "n_steps": 21 + "n_memory_holes": 0 }, - "constant": { + "calldata_factor": { + "n_steps": 21, "builtin_instance_counter": { - "pedersen_builtin": 23, - "range_check_builtin": 83 + "pedersen_builtin": 2 }, - "n_memory_holes": 0, - "n_steps": 3792 + "n_memory_holes": 0 } } }, "InvokeFunction": { "deprecated_resources": { - "calldata_factor": { + "constant": { + "n_steps": 3763, "builtin_instance_counter": { - "pedersen_builtin": 1 + "pedersen_builtin": 14, + "range_check_builtin": 69 }, - "n_memory_holes": 0, - "n_steps": 8 + "n_memory_holes": 0 }, - "constant": { + "calldata_factor": { + "n_steps": 8, "builtin_instance_counter": { - "pedersen_builtin": 14, - "range_check_builtin": 80 + "pedersen_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 3546 + "n_memory_holes": 0 } }, "resources": { - "calldata_factor": { + "constant": { + "n_steps": 3904, "builtin_instance_counter": { - "pedersen_builtin": 1 + "pedersen_builtin": 4, + "range_check_builtin": 74, + "poseidon_builtin": 11 }, - "n_memory_holes": 0, - "n_steps": 8 + "n_memory_holes": 0 }, - "constant": { + "calldata_factor": { + "n_steps": 8, "builtin_instance_counter": { - "pedersen_builtin": 14, - "range_check_builtin": 80 + "pedersen_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 3546 + "n_memory_holes": 0 } } }, "L1Handler": { "deprecated_resources": { - "calldata_factor": { + "constant": { + "n_steps": 1233, "builtin_instance_counter": { - "pedersen_builtin": 1 + "pedersen_builtin": 11, + "range_check_builtin": 16 }, - "n_memory_holes": 0, - "n_steps": 13 + "n_memory_holes": 0 }, - "constant": { + "calldata_factor": { + "n_steps": 13, "builtin_instance_counter": { - "pedersen_builtin": 11, - "range_check_builtin": 17 + "pedersen_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 1146 + "n_memory_holes": 0 } }, "resources": { + "constant": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, "calldata_factor": { + "n_steps": 13, "builtin_instance_counter": { "pedersen_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 13 - }, - "constant": { - "builtin_instance_counter": { - "pedersen_builtin": 11, - "range_check_builtin": 17 - }, - "n_memory_holes": 0, - "n_steps": 1146 + "n_memory_holes": 0 } } } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 113, + "builtin_instance_counter": { + "range_check_builtin": 17 + }, + "n_memory_holes": 0 } }, - "tx_event_limits": { - "max_data_length": 300, - "max_keys_length": 50, - "max_n_emitted_events": 1000 - }, "validate_max_n_steps": 1000000, "vm_resource_fee_cost": { + "add_mod_builtin": [ + 4, + 100 + ], "bitwise_builtin": [ 16, 100 @@ -563,6 +581,10 @@ 512, 100 ], + "mul_mod_builtin": [ + 4, + 100 + ], "n_steps": [ 25, 10000 @@ -582,6 +604,10 @@ "range_check_builtin": [ 4, 100 + ], + "range_check96_builtin": [ + 4, + 100 ] } } diff --git a/crates/blockifier/src/abi/constants.rs b/crates/blockifier/src/abi/constants.rs index 9b4818fd77..edf924694d 100644 --- a/crates/blockifier/src/abi/constants.rs +++ b/crates/blockifier/src/abi/constants.rs @@ -30,7 +30,9 @@ pub const CONSUMED_MSG_TO_L2_ENCODED_DATA_SIZE: usize = (L1_TO_L2_MSG_HEADER_SIZE + 1) - CONSUMED_MSG_TO_L2_N_TOPICS; // Transaction resource names. +// TODO(Amos, 1/10/2024): Rename to l1_gas_weight. pub const L1_GAS_USAGE: &str = "gas_weight"; +pub const L2_GAS_USAGE: &str = "l2_gas_weight"; pub const BLOB_GAS_USAGE: &str = "l1_blob_gas_usage"; pub const N_STEPS_RESOURCE: &str = "n_steps"; pub const N_EVENTS: &str = "n_events"; diff --git a/crates/blockifier/src/blockifier/block.rs b/crates/blockifier/src/blockifier/block.rs index 7fdf2fb30a..986bd10720 100644 --- a/crates/blockifier/src/blockifier/block.rs +++ b/crates/blockifier/src/blockifier/block.rs @@ -47,16 +47,16 @@ impl GasPrices { strk_l2_gas_price: NonZeroU128, ) -> Self { // TODO(Aner): fix backwards compatibility. - let expected_eth_l2_gas_price = VersionedConstants::latest_constants() - .l1_to_l2_gas_price_conversion(eth_l1_gas_price.into()); + let expected_eth_l2_gas_price = + VersionedConstants::latest_constants().convert_l1_to_l2_gas(eth_l1_gas_price.into()); if u128::from(eth_l2_gas_price) != expected_eth_l2_gas_price { warn!( "eth_l2_gas_price does not match expected! eth_l2_gas_price:{eth_l2_gas_price}, \ expected:{expected_eth_l2_gas_price}." ) } - let expected_strk_l2_gas_price = VersionedConstants::latest_constants() - .l1_to_l2_gas_price_conversion(strk_l1_gas_price.into()); + let expected_strk_l2_gas_price = + VersionedConstants::latest_constants().convert_l1_to_l2_gas(strk_l1_gas_price.into()); if u128::from(strk_l2_gas_price) != expected_strk_l2_gas_price { warn!( "strk_l2_gas_price does not match expected! \ diff --git a/crates/blockifier/src/blockifier/stateful_validator_test.rs b/crates/blockifier/src/blockifier/stateful_validator_test.rs index f9d66bb235..09fb79496e 100644 --- a/crates/blockifier/src/blockifier/stateful_validator_test.rs +++ b/crates/blockifier/src/blockifier/stateful_validator_test.rs @@ -1,6 +1,6 @@ use assert_matches::assert_matches; use rstest::rstest; -use starknet_api::transaction::{DeprecatedResourceBoundsMapping, Fee, TransactionVersion}; +use starknet_api::transaction::{Fee, TransactionVersion, ValidResourceBounds}; use crate::blockifier::stateful_validator::StatefulValidator; use crate::context::BlockContext; @@ -33,7 +33,7 @@ fn test_transaction_validator( #[case] validate_constructor: bool, #[case] tx_version: TransactionVersion, block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, ) { let chain_info = &block_context.chain_info; @@ -75,7 +75,7 @@ fn test_transaction_validator( } #[rstest] -fn test_transaction_validator_skip_validate(max_resource_bounds: DeprecatedResourceBoundsMapping) { +fn test_transaction_validator_skip_validate(max_resource_bounds: ValidResourceBounds) { let block_context = BlockContext::create_for_testing(); let faulty_account = FeatureContract::FaultyAccount(CairoVersion::Cairo1); let state = test_state(&block_context.chain_info, BALANCE, &[(faulty_account, 1)]); diff --git a/crates/blockifier/src/blockifier/transaction_executor_test.rs b/crates/blockifier/src/blockifier/transaction_executor_test.rs index b3f649d5c4..98b8db93bf 100644 --- a/crates/blockifier/src/blockifier/transaction_executor_test.rs +++ b/crates/blockifier/src/blockifier/transaction_executor_test.rs @@ -1,8 +1,8 @@ use assert_matches::assert_matches; use pretty_assertions::assert_eq; use rstest::rstest; -use starknet_api::felt; use starknet_api::transaction::{Fee, TransactionVersion}; +use starknet_api::{declare_tx_args, deploy_account_tx_args, felt, invoke_tx_args}; use starknet_types_core::felt::Felt; use crate::blockifier::config::TransactionExecutorConfig; @@ -13,6 +13,7 @@ use crate::blockifier::transaction_executor::{ }; use crate::bouncer::{Bouncer, BouncerWeights}; use crate::context::BlockContext; +use crate::nonce; use crate::state::cached_state::CachedState; use crate::state::state_api::StateReader; use crate::test_utils::contracts::FeatureContract; @@ -39,7 +40,6 @@ use crate::transaction::test_utils::{ }; use crate::transaction::transaction_execution::Transaction; use crate::transaction::transactions::L1HandlerTransaction; -use crate::{declare_tx_args, deploy_account_tx_args, invoke_tx_args, nonce}; fn tx_executor_test_body( state: CachedState, diff --git a/crates/blockifier/src/concurrency/fee_utils_test.rs b/crates/blockifier/src/concurrency/fee_utils_test.rs index dba9053156..8a1bddc578 100644 --- a/crates/blockifier/src/concurrency/fee_utils_test.rs +++ b/crates/blockifier/src/concurrency/fee_utils_test.rs @@ -1,14 +1,13 @@ use num_bigint::BigUint; use rstest::rstest; -use starknet_api::felt; -use starknet_api::transaction::{DeprecatedResourceBoundsMapping, Fee}; +use starknet_api::transaction::{Fee, ValidResourceBounds}; +use starknet_api::{felt, invoke_tx_args}; use starknet_types_core::felt::Felt; use crate::concurrency::fee_utils::{add_fee_to_sequencer_balance, fill_sequencer_balance_reads}; use crate::concurrency::test_utils::create_fee_transfer_call_info; use crate::context::BlockContext; use crate::fee::fee_utils::get_sequencer_balance_keys; -use crate::invoke_tx_args; use crate::state::state_api::StateReader; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::{fund_account, test_state, test_state_inner}; @@ -19,7 +18,7 @@ use crate::transaction::test_utils::{account_invoke_tx, block_context, max_resou #[rstest] pub fn test_fill_sequencer_balance_reads( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] erc20_version: CairoVersion, ) { let account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1); diff --git a/crates/blockifier/src/concurrency/versioned_state_test.rs b/crates/blockifier/src/concurrency/versioned_state_test.rs index 71a6c460e1..bf387babea 100644 --- a/crates/blockifier/src/concurrency/versioned_state_test.rs +++ b/crates/blockifier/src/concurrency/versioned_state_test.rs @@ -11,8 +11,15 @@ use starknet_api::core::{ Nonce, PatriciaKey, }; -use starknet_api::transaction::{Calldata, ContractAddressSalt, DeprecatedResourceBoundsMapping}; -use starknet_api::{calldata, class_hash, contract_address, felt, patricia_key}; +use starknet_api::transaction::{Calldata, ContractAddressSalt, ValidResourceBounds}; +use starknet_api::{ + calldata, + class_hash, + contract_address, + deploy_account_tx_args, + felt, + patricia_key, +}; use crate::abi::abi_utils::{get_fee_token_var_address, get_storage_var_address}; use crate::concurrency::test_utils::{ @@ -44,7 +51,7 @@ use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::objects::{HasRelatedFeeType, TransactionInfoCreator}; use crate::transaction::test_utils::{l1_resource_bounds, max_resource_bounds}; use crate::transaction::transactions::ExecutableTransaction; -use crate::{compiled_class_hash, deploy_account_tx_args, nonce, storage_key}; +use crate::{compiled_class_hash, nonce, storage_key}; #[fixture] pub fn safe_versioned_state( @@ -201,7 +208,7 @@ fn test_versioned_state_proxy() { #[rstest] // Test parallel execution of two transactions that use the same versioned state. -fn test_run_parallel_txs(max_resource_bounds: DeprecatedResourceBoundsMapping) { +fn test_run_parallel_txs(max_resource_bounds: ValidResourceBounds) { let block_context = BlockContext::create_for_account_testing(); let chain_info = &block_context.chain_info; let zero_bounds = true; @@ -233,7 +240,7 @@ fn test_run_parallel_txs(max_resource_bounds: DeprecatedResourceBoundsMapping) { &mut NonceManager::default(), ); let account_tx_1 = AccountTransaction::DeployAccount(deploy_account_tx_1); - let enforce_fee = account_tx_1.create_tx_info().enforce_fee().unwrap(); + let enforce_fee = account_tx_1.create_tx_info().enforce_fee(); let class_hash = grindy_account.get_class_hash(); let ctor_storage_arg = felt!(1_u8); diff --git a/crates/blockifier/src/concurrency/worker_logic.rs b/crates/blockifier/src/concurrency/worker_logic.rs index 3029236f6f..e84960f350 100644 --- a/crates/blockifier/src/concurrency/worker_logic.rs +++ b/crates/blockifier/src/concurrency/worker_logic.rs @@ -134,32 +134,37 @@ impl<'a, S: StateReader> WorkerExecutor<'a, S> { let execution_result = tx.execute_raw(&mut transactional_state, self.block_context, execution_flags); - if execution_result.is_ok() { - // TODO(Noa, 15/05/2024): use `tx_versioned_state` when we add support to transactional - // versioned state. - self.state.pin_version(tx_index).apply_writes( - &transactional_state.cache.borrow().writes, - &transactional_state.class_hash_to_class.borrow(), - &HashMap::default(), - ); - } - - // Write the transaction execution outputs. - let tx_reads_writes = transactional_state.cache.take(); - let class_hash_to_class = transactional_state.class_hash_to_class.take(); - // In case of a failed transaction, we don't record its writes and visited pcs. - let (writes, contract_classes, visited_pcs) = match execution_result { - Ok(_) => (tx_reads_writes.writes, class_hash_to_class, transactional_state.visited_pcs), - Err(_) => (StateMaps::default(), HashMap::default(), HashMap::default()), + // Update the versioned state and store the transaction execution output. + let execution_output_inner = match execution_result { + Ok(_) => { + let tx_reads_writes = transactional_state.cache.take(); + let class_hash_to_class = transactional_state.class_hash_to_class.take(); + let visited_pcs = transactional_state.visited_pcs; + tx_versioned_state.apply_writes( + &tx_reads_writes.writes, + &class_hash_to_class, + // The versioned state does not carry the visited PCs. + &HashMap::default(), + ); + ExecutionTaskOutput { + reads: tx_reads_writes.initial_reads, + writes: tx_reads_writes.writes, + contract_classes: class_hash_to_class, + visited_pcs, + result: execution_result, + } + } + Err(_) => ExecutionTaskOutput { + reads: transactional_state.cache.take().initial_reads, + // Failed transaction - ignore the writes and visited PCs. + writes: StateMaps::default(), + contract_classes: HashMap::default(), + visited_pcs: HashMap::default(), + result: execution_result, + }, }; let mut execution_output = lock_mutex_in_array(&self.execution_outputs, tx_index); - *execution_output = Some(ExecutionTaskOutput { - reads: tx_reads_writes.initial_reads, - writes, - contract_classes, - visited_pcs, - result: execution_result, - }); + *execution_output = Some(execution_output_inner); } fn validate(&self, tx_index: TxIndex) -> Task { diff --git a/crates/blockifier/src/concurrency/worker_logic_test.rs b/crates/blockifier/src/concurrency/worker_logic_test.rs index 0833734a66..a3d48aeaf9 100644 --- a/crates/blockifier/src/concurrency/worker_logic_test.rs +++ b/crates/blockifier/src/concurrency/worker_logic_test.rs @@ -5,11 +5,11 @@ use rstest::rstest; use starknet_api::core::{ContractAddress, Nonce, PatriciaKey}; use starknet_api::transaction::{ ContractAddressSalt, - DeprecatedResourceBoundsMapping, Fee, TransactionVersion, + ValidResourceBounds, }; -use starknet_api::{contract_address, felt, patricia_key}; +use starknet_api::{contract_address, declare_tx_args, felt, invoke_tx_args, patricia_key}; use starknet_types_core::felt::Felt; use super::WorkerExecutor; @@ -47,7 +47,7 @@ use crate::transaction::test_utils::{ max_resource_bounds, }; use crate::transaction::transaction_execution::Transaction; -use crate::{declare_tx_args, invoke_tx_args, nonce, storage_key}; +use crate::{nonce, storage_key}; fn trivial_calldata_invoke_tx( account_address: ContractAddress, @@ -256,7 +256,7 @@ fn test_commit_tx_when_sender_is_sequencer() { } #[rstest] -fn test_worker_execute(max_resource_bounds: DeprecatedResourceBoundsMapping) { +fn test_worker_execute(max_resource_bounds: ValidResourceBounds) { // Settings. let block_context = BlockContext::create_for_account_testing(); let account_contract = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1); @@ -430,7 +430,7 @@ fn test_worker_execute(max_resource_bounds: DeprecatedResourceBoundsMapping) { } #[rstest] -fn test_worker_validate(max_resource_bounds: DeprecatedResourceBoundsMapping) { +fn test_worker_validate(max_resource_bounds: ValidResourceBounds) { // Settings. let block_context = BlockContext::create_for_account_testing(); let account_contract = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1); @@ -537,7 +537,7 @@ fn test_worker_validate(max_resource_bounds: DeprecatedResourceBoundsMapping) { #[case::declare_cairo1(CairoVersion::Cairo1, TransactionVersion::THREE)] fn test_deploy_before_declare( max_fee: Fee, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[case] cairo_version: CairoVersion, #[case] version: TransactionVersion, ) { @@ -629,7 +629,7 @@ fn test_deploy_before_declare( } #[rstest] -fn test_worker_commit_phase(max_resource_bounds: DeprecatedResourceBoundsMapping) { +fn test_worker_commit_phase(max_resource_bounds: ValidResourceBounds) { // Settings. let block_context = BlockContext::create_for_account_testing(); let account_contract = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1); diff --git a/crates/blockifier/src/context.rs b/crates/blockifier/src/context.rs index 13b356ea6d..9e67662b36 100644 --- a/crates/blockifier/src/context.rs +++ b/crates/blockifier/src/context.rs @@ -4,11 +4,13 @@ use papyrus_config::dumping::{append_sub_config_name, ser_param, SerializeConfig use papyrus_config::{ParamPath, ParamPrivacyInput, SerializedParam}; use serde::{Deserialize, Serialize}; use starknet_api::core::{ChainId, ContractAddress}; +use starknet_api::transaction::ValidResourceBounds; use crate::blockifier::block::BlockInfo; use crate::bouncer::BouncerConfig; use crate::transaction::objects::{ FeeType, + GasVectorComputationMode, HasRelatedFeeType, TransactionInfo, TransactionInfoCreator, @@ -29,6 +31,15 @@ impl TransactionContext { pub fn is_sequencer_the_sender(&self) -> bool { self.tx_info.sender_address() == self.block_context.block_info.sequencer_address } + pub fn get_gas_vector_computation_mode(&self) -> GasVectorComputationMode { + match &self.tx_info { + TransactionInfo::Current(info) => match info.resource_bounds { + ValidResourceBounds::AllResources(_) => GasVectorComputationMode::All, + ValidResourceBounds::L1Gas(_) => GasVectorComputationMode::NoL2Gas, + }, + TransactionInfo::Deprecated(_) => GasVectorComputationMode::NoL2Gas, + } + } } #[derive(Clone, Debug)] diff --git a/crates/blockifier/src/execution/call_info.rs b/crates/blockifier/src/execution/call_info.rs index 51f21a8c02..61c577a33a 100644 --- a/crates/blockifier/src/execution/call_info.rs +++ b/crates/blockifier/src/execution/call_info.rs @@ -14,6 +14,7 @@ use crate::execution::entry_point::CallEntryPoint; use crate::fee::gas_usage::get_message_segment_length; use crate::state::cached_state::StorageEntry; +#[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)] pub struct Retdata(pub Vec); @@ -24,12 +25,15 @@ macro_rules! retdata { }; } -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)] +#[cfg_attr(any(test, feature = "testing"), derive(Clone))] +#[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] +#[derive(Debug, Default, Eq, PartialEq, Serialize)] pub struct OrderedEvent { pub order: usize, pub event: EventContent, } +#[cfg_attr(feature = "transaction_serde", derive(Serialize, serde::Deserialize))] #[derive(Debug, Default, Eq, PartialEq, Clone)] pub struct MessageL1CostInfo { pub l2_to_l1_payload_lengths: Vec, @@ -53,12 +57,14 @@ impl MessageL1CostInfo { } } +#[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] #[derive(Debug, Default, Eq, PartialEq, Serialize, Clone)] pub struct MessageToL1 { pub to_address: EthAddress, pub payload: L2ToL1Payload, } +#[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] #[derive(Debug, Default, Eq, PartialEq, Serialize, Clone)] pub struct OrderedL2ToL1Message { pub order: usize, @@ -70,6 +76,7 @@ pub fn get_payload_lengths(l2_to_l1_messages: &[OrderedL2ToL1Message]) -> Vec>, pub hints: HashMap, + pub compiler_version: String, bytecode_segment_lengths: NestedIntList, } @@ -457,6 +459,7 @@ impl TryFrom for ContractClassV1 { program, entry_points_by_type, hints: string_to_hint, + compiler_version: class.compiler_version, bytecode_segment_lengths, }))) } diff --git a/crates/blockifier/src/execution/contract_class_test.rs b/crates/blockifier/src/execution/contract_class_test.rs index 2bc8ab09a5..6dcfd7411e 100644 --- a/crates/blockifier/src/execution/contract_class_test.rs +++ b/crates/blockifier/src/execution/contract_class_test.rs @@ -14,6 +14,7 @@ fn test_get_visited_segments() { program: Default::default(), entry_points_by_type: Default::default(), hints: Default::default(), + compiler_version: Default::default(), bytecode_segment_lengths: NestedIntList::Node(vec![ NestedIntList::Leaf(151), NestedIntList::Leaf(104), diff --git a/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs b/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs index 53722c921f..9aafe0b99c 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs @@ -37,7 +37,6 @@ use crate::test_utils::{ get_syscall_resources, trivial_external_entry_point_new, CairoVersion, - CHAIN_ID_NAME, CURRENT_BLOCK_NUMBER, CURRENT_BLOCK_NUMBER_FOR_VALIDATE, CURRENT_BLOCK_TIMESTAMP, @@ -151,7 +150,7 @@ fn test_nested_library_call() { ..nested_storage_entry_point }; let storage_entry_point_resources = ExecutionResources { - n_steps: 218, + n_steps: 224, n_memory_holes: 0, builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 2)]), }; @@ -243,7 +242,7 @@ fn test_call_contract() { }, execution: expected_execution.clone(), resources: ExecutionResources { - n_steps: 218, + n_steps: 224, n_memory_holes: 0, builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 2)]), }, @@ -262,7 +261,7 @@ fn test_call_contract() { execution: expected_execution, resources: &get_syscall_resources(DeprecatedSyscallSelector::CallContract) + &ExecutionResources { - n_steps: 257, + n_steps: 263, n_memory_holes: 0, builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 3)]), }, @@ -465,12 +464,12 @@ fn test_tx_info(#[values(false, true)] only_query: bool) { let nonce = nonce!(3_u16); let sender_address = test_contract.get_instance_address(0); let expected_tx_info = calldata![ - version, // Transaction version. - *sender_address.0.key(), // Account address. - felt!(max_fee.0), // Max fee. - tx_hash.0, // Transaction hash. - felt!(&*ChainId::Other(CHAIN_ID_NAME.to_string()).as_hex()), // Chain ID. - nonce.0 // Nonce. + version, // Transaction version. + *sender_address.0.key(), // Account address. + felt!(max_fee.0), // Max fee. + tx_hash.0, // Transaction hash. + felt!(&*ChainId::create_for_testing().as_hex()), // Chain ID. + nonce.0 // Nonce. ]; let entry_point_selector = selector_from_name("test_get_tx_info"); let entry_point_call = CallEntryPoint { diff --git a/crates/blockifier/src/execution/entry_point.rs b/crates/blockifier/src/execution/entry_point.rs index a2b1482f53..0f43522e2f 100644 --- a/crates/blockifier/src/execution/entry_point.rs +++ b/crates/blockifier/src/execution/entry_point.rs @@ -22,7 +22,7 @@ use crate::execution::errors::{ }; use crate::execution::execution_utils::execute_entry_point_call; use crate::state::state_api::State; -use crate::transaction::objects::{HasRelatedFeeType, TransactionExecutionResult, TransactionInfo}; +use crate::transaction::objects::{HasRelatedFeeType, TransactionInfo}; use crate::transaction::transaction_types::TransactionType; use crate::utils::{u128_from_usize, usize_from_u128}; use crate::versioned_constants::{GasCosts, VersionedConstants}; @@ -38,6 +38,7 @@ pub type EntryPointExecutionResult = Result; pub type ConstructorEntryPointExecutionResult = Result; /// Represents a the type of the call (used for debugging). +#[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq, Serialize)] pub enum CallType { #[default] @@ -45,6 +46,7 @@ pub enum CallType { Delegate = 1, } /// Represents a call to an entry point of a Starknet contract. +#[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)] pub struct CallEntryPoint { // The class hash is not given if it can be deduced from the storage address. @@ -135,29 +137,26 @@ impl EntryPointExecutionContext { tx_context: Arc, mode: ExecutionMode, limit_steps_by_resources: bool, - ) -> TransactionExecutionResult { - let max_steps = Self::max_steps(&tx_context, &mode, limit_steps_by_resources)?; - Ok(Self { + ) -> Self { + let max_steps = Self::max_steps(&tx_context, &mode, limit_steps_by_resources); + Self { vm_run_resources: RunResources::new(max_steps), n_emitted_events: 0, n_sent_messages_to_l1: 0, tx_context: tx_context.clone(), current_recursion_depth: Default::default(), execution_mode: mode, - }) + } } pub fn new_validate( tx_context: Arc, limit_steps_by_resources: bool, - ) -> TransactionExecutionResult { + ) -> Self { Self::new(tx_context, ExecutionMode::Validate, limit_steps_by_resources) } - pub fn new_invoke( - tx_context: Arc, - limit_steps_by_resources: bool, - ) -> TransactionExecutionResult { + pub fn new_invoke(tx_context: Arc, limit_steps_by_resources: bool) -> Self { Self::new(tx_context, ExecutionMode::Execute, limit_steps_by_resources) } @@ -168,7 +167,7 @@ impl EntryPointExecutionContext { tx_context: &TransactionContext, mode: &ExecutionMode, limit_steps_by_resources: bool, - ) -> TransactionExecutionResult { + ) -> usize { let TransactionContext { block_context, tx_info } = tx_context; let BlockContext { block_info, versioned_constants, .. } = block_context; let block_upper_bound = match mode { @@ -184,8 +183,8 @@ impl EntryPointExecutionContext { .expect("Failed to convert invoke_tx_max_n_steps (u32) to usize."), }; - if !limit_steps_by_resources || !tx_info.enforce_fee()? { - return Ok(block_upper_bound); + if !limit_steps_by_resources || !tx_info.enforce_fee() { + return block_upper_bound; } let gas_per_step = versioned_constants @@ -214,7 +213,7 @@ impl EntryPointExecutionContext { // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the // convertion works. context - .l1_resource_bounds()? + .l1_resource_bounds() .max_amount .try_into() .expect("Failed to convert u64 to usize.") @@ -236,7 +235,7 @@ impl EntryPointExecutionContext { ); usize::MAX }); - Ok(min(tx_upper_bound, block_upper_bound)) + min(tx_upper_bound, block_upper_bound) } /// Returns the available steps in run resources. diff --git a/crates/blockifier/src/execution/entry_point_execution.rs b/crates/blockifier/src/execution/entry_point_execution.rs index 63ddfdd52b..d8346de9f9 100644 --- a/crates/blockifier/src/execution/entry_point_execution.rs +++ b/crates/blockifier/src/execution/entry_point_execution.rs @@ -32,6 +32,7 @@ use crate::execution::execution_utils::{ }; use crate::execution::syscalls::hint_processor::SyscallHintProcessor; use crate::state::state_api::State; +use crate::versioned_constants::GasCosts; // TODO(spapini): Try to refactor this file into a StarknetRunner struct. @@ -175,8 +176,12 @@ pub fn initialize_execution_context<'a>( runner.initialize_function_runner_cairo_1(&entry_point.builtins)?; let mut read_only_segments = ReadOnlySegments::default(); - let program_extra_data_length = - prepare_program_extra_data(&mut runner, contract_class, &mut read_only_segments)?; + let program_extra_data_length = prepare_program_extra_data( + &mut runner, + contract_class, + &mut read_only_segments, + &context.versioned_constants().os_constants.gas_costs, + )?; // Instantiate syscall handler. let initial_syscall_ptr = runner.vm.add_memory_segment(); @@ -203,14 +208,23 @@ fn prepare_program_extra_data( runner: &mut CairoRunner, contract_class: &ContractClassV1, read_only_segments: &mut ReadOnlySegments, + gas_costs: &GasCosts, ) -> Result { - // Create the builtin cost segment, with dummy values. - let mut data = vec![]; - - // TODO(spapini): Put real costs here. - for _i in 0..20 { - data.push(MaybeRelocatable::from(0)); - } + // Create the builtin cost segment, the builtin order should be the same as the price builtin + // array in the os in compiled_class.cairo in load_compiled_class_facts. + let builtin_price_array = [ + gas_costs.pedersen_gas_cost, + gas_costs.bitwise_builtin_gas_cost, + gas_costs.ecop_gas_cost, + gas_costs.poseidon_gas_cost, + gas_costs.add_mod_gas_cost, + gas_costs.mul_mod_gas_cost, + ]; + + let data = builtin_price_array + .iter() + .map(|&x| MaybeRelocatable::from(Felt::from(x))) + .collect::>(); let builtin_cost_segment_start = read_only_segments.allocate(&mut runner.vm, &data)?; // Put a pointer to the builtin cost segment at the end of the program (after the diff --git a/crates/blockifier/src/execution/native.rs b/crates/blockifier/src/execution/native.rs index 5843e98914..a1ba9e858e 100644 --- a/crates/blockifier/src/execution/native.rs +++ b/crates/blockifier/src/execution/native.rs @@ -1,3 +1,5 @@ pub mod entry_point_execution; pub mod syscall_handler; +#[cfg(any(test, feature = "testing"))] +pub mod test_utils; pub mod utils; diff --git a/crates/blockifier/src/execution/native/syscall_handler.rs b/crates/blockifier/src/execution/native/syscall_handler.rs index 39dd12015a..726819be59 100644 --- a/crates/blockifier/src/execution/native/syscall_handler.rs +++ b/crates/blockifier/src/execution/native/syscall_handler.rs @@ -48,7 +48,13 @@ use super::utils::{ u256_to_biguint, }; use crate::abi::constants; -use crate::execution::call_info::{CallInfo, MessageToL1, OrderedEvent, OrderedL2ToL1Message}; +use crate::execution::call_info::{ + CallInfo, + MessageToL1, + OrderedEvent, + OrderedL2ToL1Message, + Retdata, +}; use crate::execution::common_hints::ExecutionMode; use crate::execution::contract_class::ContractClass; use crate::execution::entry_point::{ @@ -120,7 +126,7 @@ impl<'state> NativeSyscallHandler<'state> { &mut self, entry_point: CallEntryPoint, remaining_gas: &mut u128, - ) -> SyscallResult { + ) -> SyscallResult { let call_info = entry_point .execute(self.state, self.execution_resources, self.execution_context) .map_err(|e| encode_str_as_felts(&e.to_string()))?; @@ -133,9 +139,11 @@ impl<'state> NativeSyscallHandler<'state> { self.update_remaining_gas(remaining_gas, &call_info); - self.inner_calls.push(call_info.clone()); + let retdata = call_info.execution.retdata.clone(); + + self.inner_calls.push(call_info); - Ok(call_info) + Ok(retdata) } pub fn update_remaining_gas(&mut self, remaining_gas: &mut u128, call_info: &CallInfo) { @@ -513,11 +521,7 @@ impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> { initial_gas: u64::try_from(*remaining_gas).unwrap(), }; - let retdata = self - .execute_inner_call(entry_point, remaining_gas) - .map(|call_info| call_info.execution.retdata.0.clone())?; - - Ok(retdata) + Ok(self.execute_inner_call(entry_point, remaining_gas)?.0) } fn call_contract( @@ -561,11 +565,7 @@ impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> { initial_gas: u64::try_from(*remaining_gas).unwrap(), }; - let retdata = self - .execute_inner_call(entry_point, remaining_gas) - .map(|call_info| call_info.execution.retdata.0.clone())?; - - Ok(retdata) + Ok(self.execute_inner_call(entry_point, remaining_gas)?.0) } fn storage_read( @@ -1299,10 +1299,9 @@ pub mod sierra_emu_impl { }; let retdata = self - .execute_inner_call(entry_point, remaining_gas) - .map(|call_info| call_info.execution.retdata.0.clone())?; + .execute_inner_call(entry_point, remaining_gas)?; - Ok(retdata) + Ok(retdata.0) } fn call_contract( @@ -1347,10 +1346,9 @@ pub mod sierra_emu_impl { }; let retdata = self - .execute_inner_call(entry_point, remaining_gas) - .map(|call_info| call_info.execution.retdata.0.clone())?; + .execute_inner_call(entry_point, remaining_gas)?; - Ok(retdata) + Ok(retdata.0) } fn storage_read( diff --git a/crates/blockifier/src/execution/native/test_utils.rs b/crates/blockifier/src/execution/native/test_utils.rs new file mode 100644 index 0000000000..d3f66d29e0 --- /dev/null +++ b/crates/blockifier/src/execution/native/test_utils.rs @@ -0,0 +1,227 @@ +use std::collections::HashMap; +use std::sync::Arc; + +use cairo_native::starknet::SyscallResult; +use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress, PatriciaKey}; +use starknet_api::transaction::{Calldata, ContractAddressSalt}; +use starknet_api::{class_hash, contract_address, felt, patricia_key}; +use starknet_types_core::felt::Felt; + +use crate::abi::abi_utils::selector_from_name; +use crate::context::{BlockContext, TransactionContext}; +use crate::execution::call_info::{CallInfo, OrderedEvent}; +use crate::execution::common_hints::ExecutionMode; +use crate::execution::entry_point::{ + CallEntryPoint, + ConstructorContext, + EntryPointExecutionContext, +}; +use crate::execution::execution_utils::execute_deployment; +use crate::execution::native::utils::{ + contract_address_to_native_felt, + decode_felts_as_str, + encode_str_as_felts, +}; +use crate::execution::syscalls::hint_processor::FAILED_TO_CALCULATE_CONTRACT_ADDRESS; +use crate::state::cached_state::CachedState; +use crate::state::state_api::State; +use crate::test_utils::cached_state::get_erc20_class_hash_mapping; +use crate::test_utils::dict_state_reader::DictStateReader; +use crate::test_utils::{ + erc20_external_entry_point, + TEST_ERC20_FULL_CONTRACT_ADDRESS, + TEST_ERC20_FULL_CONTRACT_CLASS_HASH, +}; +use crate::transaction::objects::TransactionInfo; + +pub fn create_erc20_deploy_test_state() -> CachedState { + let address_to_class_hash: HashMap = HashMap::from([( + contract_address!(TEST_ERC20_FULL_CONTRACT_ADDRESS), + class_hash!(TEST_ERC20_FULL_CONTRACT_CLASS_HASH), + )]); + + CachedState::from(DictStateReader { + address_to_class_hash, + class_hash_to_class: get_erc20_class_hash_mapping(), + ..Default::default() + }) +} + +pub fn deploy_contract( + state: &mut dyn State, + class_hash: Felt, + contract_address_salt: Felt, + calldata: &[Felt], +) -> SyscallResult<(Felt, Vec)> { + let deployer_address = ContractAddress::default(); + + let class_hash = ClassHash(class_hash); + + let wrapper_calldata = Calldata(Arc::new(calldata.to_vec())); + + let calculated_contract_address = calculate_contract_address( + ContractAddressSalt(contract_address_salt), + class_hash, + &wrapper_calldata, + deployer_address, + ) + .map_err(|_| vec![Felt::from_hex(FAILED_TO_CALCULATE_CONTRACT_ADDRESS).unwrap()])?; + + let ctor_context = ConstructorContext { + class_hash, + code_address: Some(calculated_contract_address), + storage_address: calculated_contract_address, + caller_address: deployer_address, + }; + + let call_info = execute_deployment( + state, + &mut Default::default(), + &mut EntryPointExecutionContext::new( + Arc::new(TransactionContext { + block_context: BlockContext::create_for_testing(), + tx_info: TransactionInfo::Current(Default::default()), + }), + ExecutionMode::Execute, + false, + ), + ctor_context, + wrapper_calldata, + u64::MAX, + ) + .map_err(|err| encode_str_as_felts(&err.to_string()))?; + + let return_data = call_info.execution.retdata.0; + let contract_address_felt = *calculated_contract_address.0.key(); + + Ok((contract_address_felt, return_data)) +} + +pub fn prepare_erc20_deploy_test_state() -> (ContractAddress, CachedState) { + let mut state = create_erc20_deploy_test_state(); + + let class_hash = Felt::from_hex(TEST_ERC20_FULL_CONTRACT_CLASS_HASH).unwrap(); + + let (contract_address, _) = deploy_contract( + &mut state, + class_hash, + Felt::from(0), + &[ + contract_address_to_native_felt(Signers::Alice.into()), // Recipient + contract_address_to_native_felt(Signers::Alice.into()), // Owner + ], + ) + .unwrap_or_else(|e| panic!("Failed to deploy contract: {:?}", decode_felts_as_str(&e))); + + let contract_address = ContractAddress(PatriciaKey::try_from(contract_address).unwrap()); + + (contract_address, state) +} + +#[derive(Debug, Clone, Copy)] +pub enum Signers { + Alice, + Bob, + Charlie, +} + +impl Signers { + pub fn get_address(&self) -> ContractAddress { + match self { + Signers::Alice => ContractAddress(patricia_key!(0x001u128)), + Signers::Bob => ContractAddress(patricia_key!(0x002u128)), + Signers::Charlie => ContractAddress(patricia_key!(0x003u128)), + } + } +} + +impl From for ContractAddress { + fn from(val: Signers) -> ContractAddress { + val.get_address() + } +} + +impl From for Felt { + fn from(val: Signers) -> Felt { + contract_address_to_native_felt(val.get_address()) + } +} + +#[derive(Debug, Clone)] +pub struct TestEvent { + pub data: Vec, + pub keys: Vec, +} + +impl From for TestEvent { + fn from(value: OrderedEvent) -> Self { + let event_data = value.event.data.0; + let event_keys = value.event.keys.iter().map(|e| e.0).collect(); + Self { data: event_data, keys: event_keys } + } +} + +pub struct TestContext { + pub contract_address: ContractAddress, + pub state: CachedState, + pub caller_address: ContractAddress, + pub events: Vec, +} + +impl Default for TestContext { + fn default() -> Self { + let (contract_address, state) = prepare_erc20_deploy_test_state(); + Self { contract_address, state, caller_address: contract_address, events: vec![] } + } +} + +impl TestContext { + pub fn new() -> Self { + Self::default() + } + + pub fn with_caller(mut self, caller_address: ContractAddress) -> Self { + self.caller_address = caller_address; + self + } + + pub fn call_entry_point(&mut self, entry_point_name: &str, calldata: Vec) -> Vec { + let result = self.call_entry_point_raw(entry_point_name, calldata).unwrap(); + result.execution.retdata.0.to_vec() + } + + pub fn call_entry_point_raw( + &mut self, + entry_point_name: &str, + calldata: Vec, + ) -> Result { + let entry_point_selector = selector_from_name(entry_point_name); + let calldata = Calldata(Arc::new(calldata)); + + let entry_point_call = CallEntryPoint { + calldata, + entry_point_selector, + code_address: Some(self.contract_address), + storage_address: self.contract_address, + caller_address: self.caller_address, + ..erc20_external_entry_point() + }; + + let result = + entry_point_call.execute_directly(&mut self.state).map_err(|e| e.to_string())?; + + let events = result.execution.events.clone(); + + self.events.extend(events.iter().map(|e| e.clone().into())); + + Ok(result) + } + + pub fn get_event(&self, index: usize) -> Option { + self.events.get(index).cloned() + } + + pub fn get_caller(&self) -> ContractAddress { + self.caller_address + } +} diff --git a/crates/blockifier/src/execution/native/utils.rs b/crates/blockifier/src/execution/native/utils.rs index 6795b79308..e6867b8b49 100644 --- a/crates/blockifier/src/execution/native/utils.rs +++ b/crates/blockifier/src/execution/native/utils.rs @@ -15,7 +15,7 @@ use num_traits::ToBytes; use sierra_emu::{ProgramTrace, StateDump}; use starknet_api::core::{ContractAddress, EntryPointSelector}; use starknet_api::state::StorageKey; -use starknet_api::transaction::Resource; +use starknet_api::transaction::{AllResourceBounds, ValidResourceBounds}; use starknet_types_core::felt::Felt; use crate::execution::call_info::{ @@ -129,7 +129,9 @@ fn create_callinfo( syscall_handler: NativeSyscallHandler<'_>, ) -> Result { let gas_consumed = { - let low: u64 = run_result.remaining_gas.try_into().unwrap(); + // We can use `.unwrap()` directly in both cases because the most significant bit is could + // be only 63 here (128 = 64 + 64). + let low: u64 = (run_result.remaining_gas & ((1u128 << 64) - 1)).try_into().unwrap(); let high: u64 = (run_result.remaining_gas >> 64).try_into().unwrap(); if high != 0 { return Err(EntryPointExecutionError::NativeExecutionError { @@ -169,7 +171,9 @@ pub fn create_callinfo_emu( accessed_storage_keys: HashSet, ) -> Result { let gas_consumed = { - let low: u64 = run_result.remaining_gas.try_into().unwrap(); + // We can use `.unwrap()` directly in both cases because the most significant bit is could + // be only 63 here (128 = 64 + 64). + let low: u64 = (run_result.remaining_gas & ((1u128 << 64) - 1)).try_into().unwrap(); let high: u64 = (run_result.remaining_gas >> 64).try_into().unwrap(); if high != 0 { return Err(EntryPointExecutionError::NativeExecutionError { @@ -286,28 +290,34 @@ pub fn default_tx_v2_info_sierra_emu() -> sierra_emu::starknet::TxV2Info { pub fn calculate_resource_bounds( tx_info: &CurrentTransactionInfo, ) -> SyscallResult> { - let l1_gas = Felt::from_hex(L1_GAS).map_err(|e| encode_str_as_felts(&e.to_string()))?; - let l2_gas = Felt::from_hex(L2_GAS).map_err(|e| encode_str_as_felts(&e.to_string()))?; + let l1_gas_felt = Felt::from_hex(L1_GAS).map_err(|e| encode_str_as_felts(&e.to_string()))?; + let l2_gas_felt = Felt::from_hex(L2_GAS).map_err(|e| encode_str_as_felts(&e.to_string()))?; // TODO: Recheck correctness of L1_DATA_GAS - let l1_data_gas = + let l1_data_gas_felt = Felt::from_hex(L1_DATA_GAS).map_err(|e| encode_str_as_felts(&e.to_string()))?; - Ok(tx_info - .resource_bounds - .0 - .iter() - .map(|(resource, resource_bound)| { - let resource = match resource { - Resource::L1Gas => l1_gas, - Resource::L2Gas => l2_gas, - Resource::L1DataGas => l1_data_gas, - }; - - ResourceBounds { - resource, - max_amount: resource_bound.max_amount, - max_price_per_unit: resource_bound.max_price_per_unit, - } - }) - .collect()) + let mut resource_bounds = vec![ + ResourceBounds{ + resource: l1_gas_felt, + max_amount: tx_info.resource_bounds.get_l1_bounds().max_amount, + max_price_per_unit: tx_info.resource_bounds.get_l1_bounds().max_price_per_unit, + }, + ResourceBounds{ + resource: l2_gas_felt, + max_amount: tx_info.resource_bounds.get_l2_bounds().max_amount, + max_price_per_unit: tx_info.resource_bounds.get_l2_bounds().max_price_per_unit, + }, + ]; + + if let ValidResourceBounds::AllResources(AllResourceBounds { l1_data_gas, .. }) = + tx_info.resource_bounds + { + resource_bounds.push(ResourceBounds{ + resource: l1_data_gas_felt, + max_amount: l1_data_gas.max_amount, + max_price_per_unit: l1_data_gas.max_price_per_unit, + }); + } + + Ok(resource_bounds) } diff --git a/crates/blockifier/src/execution/stack_trace.rs b/crates/blockifier/src/execution/stack_trace.rs index c6a15e6a68..af8f9ad1a5 100644 --- a/crates/blockifier/src/execution/stack_trace.rs +++ b/crates/blockifier/src/execution/stack_trace.rs @@ -66,18 +66,23 @@ impl From<&EntryPointErrorFrame> for String { pub struct VmExceptionFrame { pc: Relocatable, + error_attr_value: Option, traceback: Option, } impl From<&VmExceptionFrame> for String { fn from(value: &VmExceptionFrame) -> Self { + let error_msg = match &value.error_attr_value { + Some(error_msg) => error_msg.clone(), + None => String::new(), + }; let vm_exception_preamble = format!("Error at pc={}:", value.pc); let vm_exception_traceback = if let Some(traceback) = &value.traceback { format!("\n{}", traceback) } else { "".to_string() }; - format!("{vm_exception_preamble}{vm_exception_traceback}") + format!("{error_msg}{vm_exception_preamble}{vm_exception_traceback}") } } @@ -217,8 +222,12 @@ fn extract_cairo_run_error_into_stack_trace( ) { if let CairoRunError::VmException(vm_exception) = error { error_stack.push( - VmExceptionFrame { pc: vm_exception.pc, traceback: vm_exception.traceback.clone() } - .into(), + VmExceptionFrame { + pc: vm_exception.pc, + error_attr_value: vm_exception.error_attr_value.clone(), + traceback: vm_exception.traceback.clone(), + } + .into(), ); extract_virtual_machine_error_into_stack_trace(error_stack, depth, &vm_exception.inner_exc); } else { diff --git a/crates/blockifier/src/execution/stack_trace_test.rs b/crates/blockifier/src/execution/stack_trace_test.rs index 6651a5d9cc..4e61dd1837 100644 --- a/crates/blockifier/src/execution/stack_trace_test.rs +++ b/crates/blockifier/src/execution/stack_trace_test.rs @@ -5,17 +5,16 @@ use starknet_api::core::{calculate_contract_address, Nonce}; use starknet_api::transaction::{ Calldata, ContractAddressSalt, - DeprecatedResourceBoundsMapping, Fee, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; -use starknet_api::{calldata, felt}; +use starknet_api::{calldata, felt, invoke_tx_args}; use crate::abi::abi_utils::selector_from_name; use crate::abi::constants::CONSTRUCTOR_ENTRY_POINT_NAME; use crate::context::{BlockContext, ChainInfo}; -use crate::invoke_tx_args; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::{fund_account, test_state}; use crate::test_utils::{create_calldata, CairoVersion, BALANCE}; @@ -42,6 +41,92 @@ use crate::transaction::transactions::ExecutableTransaction; const INNER_CALL_CONTRACT_IN_CALL_CHAIN_OFFSET: usize = 117; +#[rstest] +fn test_stack_trace_with_inner_error_msg(block_context: BlockContext) { + let cairo_version = CairoVersion::Cairo0; + let chain_info = ChainInfo::create_for_testing(); + let account = FeatureContract::AccountWithoutValidations(cairo_version); + let test_contract = FeatureContract::TestContract(cairo_version); + let mut state = test_state(&chain_info, BALANCE, &[(account, 1), (test_contract, 2)]); + let account_address = account.get_instance_address(0); + let test_contract_address = test_contract.get_instance_address(0); + let test_contract_address_2 = test_contract.get_instance_address(1); + let account_address_felt = *account_address.0.key(); + let test_contract_address_felt = *test_contract_address.0.key(); + let test_contract_address_2_felt = *test_contract_address_2.0.key(); + let test_contract_hash = test_contract.get_class_hash().0; + let account_contract_hash = account.get_class_hash().0; + + // Nest calls: __execute__ -> test_call_contract_fail_with_attr_error_msg -> assert_0_is_1. + let call_contract_function_name = "test_call_contract_fail_with_attr_error_msg"; + let inner_entry_point_selector_felt = selector_from_name("fail").0; + let calldata = create_calldata( + test_contract_address, // contract_address + call_contract_function_name, + &[ + test_contract_address_2_felt, // Contract address. + inner_entry_point_selector_felt, // Function selector. + ], + ); + + let tx_execution_error = run_invoke_tx( + &mut state, + &block_context, + invoke_tx_args! { + sender_address: account_address, + calldata, + version: TransactionVersion::ZERO, + }, + ) + .unwrap_err(); + + // Fetch PC locations from the compiled contract to compute the expected PC locations in the + // traceback. Computation is not robust, but as long as the cairo function itself is not edited, + // this computation should be stable. + let account_entry_point_offset = + account.get_entry_point_offset(selector_from_name(EXECUTE_ENTRY_POINT_NAME)); + let execute_selector_felt = selector_from_name(EXECUTE_ENTRY_POINT_NAME).0; + let external_entry_point_selector_felt = selector_from_name(call_contract_function_name).0; + let entry_point_offset = + test_contract.get_entry_point_offset(selector_from_name(call_contract_function_name)); + // Relative offsets of the test_call_contract entry point and the inner call. + let call_location = entry_point_offset.0 + 6; + let entry_point_location = entry_point_offset.0 - 4; + // Relative offsets of the account contract. + let account_call_location = account_entry_point_offset.0 + 18; + let account_entry_point_location = account_entry_point_offset.0 - 8; + + let expected_trace = format!( + "Transaction execution has failed: +0: Error in the called contract (contract address: {account_address_felt:#064x}, class hash: \ + {account_contract_hash:#064x}, selector: {execute_selector_felt:#064x}): +Error at pc=0:7: +Cairo traceback (most recent call last): +Unknown location (pc=0:{account_call_location}) +Unknown location (pc=0:{account_entry_point_location}) + +1: Error in the called contract (contract address: {test_contract_address_felt:#064x}, class hash: \ + {test_contract_hash:#064x}, selector: {external_entry_point_selector_felt:#064x}): +Error at pc=0:37: +Cairo traceback (most recent call last): +Unknown location (pc=0:{call_location}) +Error message: Be aware of failure ahead... +Unknown location (pc=0:{entry_point_location}) + +2: Error in the called contract (contract address: {test_contract_address_2_felt:#064x}, class \ + hash: {test_contract_hash:#064x}, selector: {inner_entry_point_selector_felt:#064x}): +Error message: You shall not pass! +Error at pc=0:1215: +Cairo traceback (most recent call last): +Unknown location (pc=0:1219) + +An ASSERT_EQ instruction failed: 1 != 0. +" + ); + + assert_eq!(tx_execution_error.to_string(), expected_trace); +} + #[rstest] fn test_stack_trace( block_context: BlockContext, @@ -118,9 +203,10 @@ Unknown location (pc=0:{entry_point_location}) 2: Error in the called contract (contract address: {test_contract_address_2_felt:#064x}, class \ hash: {test_contract_hash:#064x}, selector: {inner_entry_point_selector_felt:#064x}): -Error at pc=0:1184: +Error message: You shall not pass! +Error at pc=0:1215: Cairo traceback (most recent call last): -Unknown location (pc=0:1188) +Unknown location (pc=0:1219) An ASSERT_EQ instruction failed: 1 != 0. " @@ -150,9 +236,9 @@ Execution failed. Failure reason: 0x6661696c ('fail'). } #[rstest] -#[case(CairoVersion::Cairo0, "invoke_call_chain", "Couldn't compute operand op0. Unknown value for memory cell 1:37", (1081_u16, 1127_u16) +#[case(CairoVersion::Cairo0, "invoke_call_chain", "Couldn't compute operand op0. Unknown value for memory cell 1:37", (1112_u16, 1158_u16) )] -#[case(CairoVersion::Cairo0, "fail", "An ASSERT_EQ instruction failed: 1 != 0.", (1184_u16, 1135_u16) +#[case(CairoVersion::Cairo0, "fail", "An ASSERT_EQ instruction failed: 1 != 0.", (1215_u16, 1166_u16) )] #[case(CairoVersion::Cairo1, "invoke_call_chain", "0x4469766973696f6e2062792030 ('Division by 0')", (0_u16, 0_u16) )] @@ -164,6 +250,10 @@ fn test_trace_callchain_ends_with_regular_call( #[case] expected_error: &str, #[case] expected_pc_locations: (u16, u16), ) { + let expected_with_attr_error_msg = match (cairo_version, last_func_name) { + (CairoVersion::Cairo0, "fail") => "Error message: You shall not pass!\n".to_string(), + _ => String::new(), + }; let chain_info = ChainInfo::create_for_testing(); let account_contract = FeatureContract::AccountWithoutValidations(cairo_version); let test_contract = FeatureContract::TestContract(cairo_version); @@ -238,7 +328,7 @@ Unknown location (pc=0:{entry_point_location}) 2: Error in the called contract (contract address: {contract_address_felt:#064x}, class hash: \ {test_contract_hash:#064x}, selector: {invoke_call_chain_selector_felt:#064x}): -Error at pc=0:{expected_pc0}: +{expected_with_attr_error_msg}Error at pc=0:{expected_pc0}: Cairo traceback (most recent call last): Unknown location (pc=0:{call_location}) Unknown location (pc=0:{expected_pc1}) @@ -275,13 +365,13 @@ Execution failed. Failure reason: {expected_error}. } #[rstest] -#[case(CairoVersion::Cairo0, "invoke_call_chain", "Couldn't compute operand op0. Unknown value for memory cell 1:23", 1_u8, 0_u8, (37_u16, 1093_u16, 1081_u16, 1166_u16) +#[case(CairoVersion::Cairo0, "invoke_call_chain", "Couldn't compute operand op0. Unknown value for memory cell 1:23", 1_u8, 0_u8, (37_u16, 1124_u16, 1112_u16, 1197_u16) )] -#[case(CairoVersion::Cairo0, "invoke_call_chain", "Couldn't compute operand op0. Unknown value for memory cell 1:23", 1_u8, 1_u8, (49_u16, 1111_u16, 1081_u16, 1166_u16) +#[case(CairoVersion::Cairo0, "invoke_call_chain", "Couldn't compute operand op0. Unknown value for memory cell 1:23", 1_u8, 1_u8, (49_u16, 1142_u16, 1112_u16, 1197_u16) )] -#[case(CairoVersion::Cairo0, "fail", "An ASSERT_EQ instruction failed: 1 != 0.", 0_u8, 0_u8, (37_u16, 1093_u16, 1184_u16, 1188_u16) +#[case(CairoVersion::Cairo0, "fail", "An ASSERT_EQ instruction failed: 1 != 0.", 0_u8, 0_u8, (37_u16, 1124_u16, 1215_u16, 1219_u16) )] -#[case(CairoVersion::Cairo0, "fail", "An ASSERT_EQ instruction failed: 1 != 0.", 0_u8, 1_u8, (49_u16, 1111_u16, 1184_u16, 1188_u16) +#[case(CairoVersion::Cairo0, "fail", "An ASSERT_EQ instruction failed: 1 != 0.", 0_u8, 1_u8, (49_u16, 1142_u16, 1215_u16, 1219_u16) )] #[case(CairoVersion::Cairo1, "invoke_call_chain", "0x4469766973696f6e2062792030 ('Division by 0')", 1_u8, 0_u8, (9631_u16, 9631_u16, 0_u16, 0_u16) )] @@ -300,6 +390,10 @@ fn test_trace_call_chain_with_syscalls( #[case] call_type: u8, #[case] expected_pcs: (u16, u16, u16, u16), ) { + let expected_with_attr_error_msg = match (cairo_version, last_func_name) { + (CairoVersion::Cairo0, "fail") => "Error message: You shall not pass!\n".to_string(), + _ => String::new(), + }; let chain_info = ChainInfo::create_for_testing(); let account_contract = FeatureContract::AccountWithoutValidations(cairo_version); let test_contract = FeatureContract::TestContract(cairo_version); @@ -402,7 +496,7 @@ Unknown location (pc=0:{call_location}) Unknown location (pc=0:{expected_pc1}) 3: {last_call_preamble}: -Error at pc=0:{expected_pc2}: +{expected_with_attr_error_msg}Error at pc=0:{expected_pc2}: Cairo traceback (most recent call last): Unknown location (pc=0:{expected_pc3}) @@ -619,7 +713,7 @@ An ASSERT_EQ instruction failed: 1 != 0. /// point selector). fn test_contract_ctor_frame_stack_trace( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, ) { let chain_info = &block_context.chain_info; diff --git a/crates/blockifier/src/execution/syscalls/hint_processor.rs b/crates/blockifier/src/execution/syscalls/hint_processor.rs index d99bb7938a..850f6a2d0f 100644 --- a/crates/blockifier/src/execution/syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/syscalls/hint_processor.rs @@ -17,7 +17,7 @@ use cairo_vm::vm::vm_core::VirtualMachine; use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector}; use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::state::StorageKey; -use starknet_api::transaction::{Calldata, Resource}; +use starknet_api::transaction::{AllResourceBounds, Calldata, ValidResourceBounds}; use starknet_api::StarknetApiError; use starknet_types_core::felt::{Felt, FromStrError}; use thiserror::Error; @@ -209,6 +209,8 @@ pub const L1_GAS: &str = "0x0000000000000000000000000000000000000000000000000000 pub const L2_GAS: &str = "0x00000000000000000000000000000000000000000000000000004c325f474153"; // "L1_DATA_GAS"; pub const L1_DATA_GAS: &str = "0x0000000000000000000000000000000000004c315f444154415f474153"; +// "L1_DATA" +pub const L1_DATA: &str = "0x00000000000000000000000000000000000000000000000000004c325f474153"; // Failed to execute call pub const FAILED_TO_EXECUTE_CALL: &str = "0x004661696c656420746f20657865637574652063616c6c"; // Failed to calculate address @@ -471,26 +473,29 @@ impl<'a> SyscallHintProcessor<'a> { vm: &mut VirtualMachine, tx_info: &CurrentTransactionInfo, ) -> SyscallResult<(Relocatable, Relocatable)> { - let l1_gas = Felt::from_hex(L1_GAS).map_err(SyscallExecutionError::from)?; - let l2_gas = Felt::from_hex(L2_GAS).map_err(SyscallExecutionError::from)?; - let flat_resource_bounds: Vec = tx_info - .resource_bounds - .0 - .iter() - .flat_map(|(resource, resource_bounds)| { - let resource = match resource { - Resource::L1Gas => l1_gas, - Resource::L2Gas => l2_gas, - Resource::L1DataGas => todo!(), - }; - - vec![ - resource, - Felt::from(resource_bounds.max_amount), - Felt::from(resource_bounds.max_price_per_unit), - ] - }) - .collect(); + let l1_gas_as_felt = Felt::from_hex(L1_GAS).map_err(SyscallExecutionError::from)?; + let l2_gas_as_felt = Felt::from_hex(L2_GAS).map_err(SyscallExecutionError::from)?; + let l1_data_gas_as_felt = Felt::from_hex(L1_DATA_GAS).map_err(SyscallExecutionError::from)?; + + let l1_gas_bounds = tx_info.resource_bounds.get_l1_bounds(); + let l2_gas_bounds = tx_info.resource_bounds.get_l2_bounds(); + let mut flat_resource_bounds = vec![ + l1_gas_as_felt, + Felt::from(l1_gas_bounds.max_amount), + Felt::from(l1_gas_bounds.max_price_per_unit), + l2_gas_as_felt, + Felt::from(l2_gas_bounds.max_amount), + Felt::from(l2_gas_bounds.max_price_per_unit), + ]; + if let ValidResourceBounds::AllResources(AllResourceBounds { l1_data_gas, .. }) = + tx_info.resource_bounds + { + flat_resource_bounds.extend(vec![ + l1_data_gas_as_felt, + Felt::from(l1_data_gas.max_amount), + Felt::from(l1_data_gas.max_price_per_unit), + ]) + } self.allocate_data_segment(vm, &flat_resource_bounds) } diff --git a/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs b/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs index ace0d33b47..21eb140ffc 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs @@ -1,5 +1,3 @@ -use std::collections::BTreeMap; - use cairo_vm::Felt252; use num_traits::Pow; use starknet_api::core::ChainId; @@ -8,14 +6,13 @@ use starknet_api::felt; use starknet_api::transaction::{ AccountDeploymentData, Calldata, - DeprecatedResourceBoundsMapping, Fee, PaymasterData, - Resource, ResourceBounds, Tip, TransactionHash, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; use test_case::test_case; @@ -24,7 +21,7 @@ use crate::abi::abi_utils::selector_from_name; use crate::context::ChainInfo; use crate::execution::common_hints::ExecutionMode; use crate::execution::entry_point::CallEntryPoint; -use crate::execution::syscalls::hint_processor::{L1_GAS, L2_GAS}; +use crate::execution::syscalls::hint_processor::{L1_DATA, L1_GAS, L2_GAS}; use crate::nonce; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::test_state; @@ -32,7 +29,6 @@ use crate::test_utils::{ trivial_external_entry_point_with_address, CairoVersion, BALANCE, - CHAIN_ID_NAME, CURRENT_BLOCK_NUMBER, CURRENT_BLOCK_NUMBER_FOR_VALIDATE, CURRENT_BLOCK_TIMESTAMP, @@ -220,13 +216,13 @@ fn test_get_execution_info( let tx_info: TransactionInfo; if version == TransactionVersion::ONE { expected_tx_info = vec![ - version.0, /* Transaction - * version. */ + version.0, /* Transaction + * version. */ *sender_address.0.key(), // Account address. felt!(max_fee.0), // Max fee. Felt::ZERO, // Signature. tx_hash.0, // Transaction hash. - felt!(&*ChainId::Other(CHAIN_ID_NAME.to_string()).as_hex()), // Chain ID. + felt!(&*ChainId::create_for_testing().as_hex()), // Chain ID. nonce.0, // Nonce. ]; @@ -243,13 +239,13 @@ fn test_get_execution_info( }); } else { expected_tx_info = vec![ - version.0, /* Transaction - * version. */ + version.0, /* Transaction + * version. */ *sender_address.0.key(), // Account address. Felt::ZERO, // Max fee. Felt::ZERO, // Signature. tx_hash.0, // Transaction hash. - felt!(&*ChainId::Other(CHAIN_ID_NAME.to_string()).as_hex()), // Chain ID. + felt!(&*ChainId::create_for_testing().as_hex()), // Chain ID. nonce.0, // Nonce. ]; @@ -262,21 +258,10 @@ fn test_get_execution_info( only_query, ..Default::default() }, - resource_bounds: DeprecatedResourceBoundsMapping(BTreeMap::from([ - ( - Resource::L1Gas, - // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why - // the convertion works. - ResourceBounds { - max_amount: max_amount - .0 - .try_into() - .expect("Failed to convert u128 to u64."), - max_price_per_unit: max_price_per_unit.0, - }, - ), - (Resource::L2Gas, ResourceBounds { max_amount: 0, max_price_per_unit: 0 }), - ])), + resource_bounds: ValidResourceBounds::L1Gas(ResourceBounds { + max_amount: max_amount.0.try_into().expect("Failed to convert u128 to u64."), + max_price_per_unit: max_price_per_unit.0, + }), tip: Tip::default(), nonce_data_availability_mode: DataAvailabilityMode::L1, fee_data_availability_mode: DataAvailabilityMode::L1, @@ -325,3 +310,21 @@ fn test_get_execution_info( assert!(!result.unwrap().execution.failed); } + +#[test] +fn test_gas_types_constants() { + assert_eq!(str_to_32_bytes_in_hex("L1_GAS"), L1_GAS); + assert_eq!(str_to_32_bytes_in_hex("L2_GAS"), L2_GAS); + assert_eq!(str_to_32_bytes_in_hex("L1_DATA"), L1_DATA); +} + +fn str_to_32_bytes_in_hex(s: &str) -> String { + if s.len() > 32 { + panic!("Unsupported input of length > 32.") + } + let prefix = "0x"; + let padding_zeros = "0".repeat(64 - s.len() * 2); // Each string char is 2 chars in hex. + let word_in_hex: String = + s.as_bytes().iter().fold(String::new(), |s, byte| s + (&format!("{:02x}", byte))); + [prefix, &padding_zeros, &word_in_hex].into_iter().collect() +} diff --git a/crates/blockifier/src/execution/syscalls/syscall_tests/library_call.rs b/crates/blockifier/src/execution/syscalls/syscall_tests/library_call.rs index 7cbed935a7..19a20453c9 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_tests/library_call.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_tests/library_call.rs @@ -163,7 +163,7 @@ fn test_nested_library_call(test_contract: FeatureContract, expected_gas: u64) { }; let storage_entry_point_resources = default_resources_if_native(ExecutionResources { - n_steps: 243, + n_steps: 249, n_memory_holes: 0, builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 7)]), }); @@ -183,7 +183,7 @@ fn test_nested_library_call(test_contract: FeatureContract, expected_gas: u64) { let library_call_resources = default_resources_if_native( &get_syscall_resources(SyscallSelector::LibraryCall) + &ExecutionResources { - n_steps: 388, + n_steps: 394, n_memory_holes: 0, builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 15)]), }, @@ -216,7 +216,7 @@ fn test_nested_library_call(test_contract: FeatureContract, expected_gas: u64) { let main_call_resources = default_resources_if_native( &(&get_syscall_resources(SyscallSelector::LibraryCall) * 3) + &ExecutionResources { - n_steps: 749, + n_steps: 761, n_memory_holes: 2, builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 27)]), }, diff --git a/crates/blockifier/src/execution/syscalls/syscall_tests/secp.rs b/crates/blockifier/src/execution/syscalls/syscall_tests/secp.rs index 383fb7e49b..c276c1ecf2 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_tests/secp.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_tests/secp.rs @@ -9,7 +9,7 @@ use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::{trivial_external_entry_point_new, CairoVersion, BALANCE}; -#[test_case(FeatureContract::TestContract(CairoVersion::Native), 17051278; "Native")] +#[test_case(FeatureContract::TestContract(CairoVersion::Native), 17046546; "Native")] #[test_case(FeatureContract::TestContract(CairoVersion::Cairo1), 17022270; "VM")] fn test_secp256k1(test_contract: FeatureContract, expected_gas: u64) { let chain_info = &ChainInfo::create_for_testing(); @@ -28,8 +28,8 @@ fn test_secp256k1(test_contract: FeatureContract, expected_gas: u64) { ); } -#[test_case(FeatureContract::TestContract(CairoVersion::Native), 27580060; "Native")] -#[test_case(FeatureContract::TestContract(CairoVersion::Cairo1), 27570060; "VM")] +#[test_case(FeatureContract::TestContract(CairoVersion::Native), 27575680; "Native")] +#[test_case(FeatureContract::TestContract(CairoVersion::Cairo1), 27565680; "VM")] fn test_secp256r1(test_contract: FeatureContract, expected_gas: u64) { let chain_info = &ChainInfo::create_for_testing(); let mut state = test_state(chain_info, BALANCE, &[(test_contract, 1)]); diff --git a/crates/blockifier/src/fee/actual_cost.rs b/crates/blockifier/src/fee/actual_cost.rs index 36967058b8..c91f3dac4c 100644 --- a/crates/blockifier/src/fee/actual_cost.rs +++ b/crates/blockifier/src/fee/actual_cost.rs @@ -1,19 +1,25 @@ +use std::collections::HashMap; + use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::core::ContractAddress; use starknet_api::transaction::Fee; +use crate::abi::constants as abi_constants; use crate::context::TransactionContext; use crate::execution::call_info::CallInfo; use crate::state::cached_state::StateChanges; use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::objects::{ + ExecutionResourcesTraits, GasVector, HasRelatedFeeType, + ResourcesMapping, StarknetResources, TransactionExecutionResult, TransactionResources, }; use crate::transaction::transaction_types::TransactionType; +use crate::utils::usize_from_u128; #[cfg(test)] #[path = "actual_cost_test.rs"] @@ -36,6 +42,7 @@ struct TransactionReceiptParameters<'a, T: Iterator + Clone // TODO(Gilad): Use everywhere instead of passing the `actual_{fee,resources}` tuple, which often // get passed around together. +#[cfg_attr(feature = "transaction_serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, PartialEq)] pub struct TransactionReceipt { pub fee: Fee, @@ -88,10 +95,11 @@ impl TransactionReceipt { let gas = tx_resources.to_gas_vector( &tx_context.block_context.versioned_constants, tx_context.block_context.block_info.use_kzg_da, + &tx_context.get_gas_vector_computation_mode(), )?; // L1 handler transactions are not charged an L2 fee but it is compared to the L1 fee. - let fee = if tx_context.tx_info.enforce_fee()? || tx_type == TransactionType::L1Handler { + let fee = if tx_context.tx_info.enforce_fee() || tx_type == TransactionType::L1Handler { tx_context.tx_info.get_fee_by_gas_vector(&tx_context.block_context.block_info, gas) } else { Fee(0) @@ -103,6 +111,33 @@ impl TransactionReceipt { Ok(Self { resources: tx_resources, gas, da_gas, fee }) } + pub fn to_resources_mapping(&self, with_reverted_steps: bool) -> ResourcesMapping { + let GasVector { l1_gas, l1_data_gas, l2_gas } = self.gas; + let mut resources = self.resources.vm_resources.to_resources_mapping(); + resources.0.extend(HashMap::from([ + ( + abi_constants::L1_GAS_USAGE.to_string(), + usize_from_u128(l1_gas) + .expect("This conversion should not fail as the value is a converted usize."), + ), + ( + abi_constants::BLOB_GAS_USAGE.to_string(), + usize_from_u128(l1_data_gas) + .expect("This conversion should not fail as the value is a converted usize."), + ), + ( + abi_constants::L2_GAS_USAGE.to_string(), + usize_from_u128(l2_gas) + .expect("This conversion should not fail as the value is a converted usize."), + ), + ])); + let reverted_steps_to_add = + if with_reverted_steps { self.resources.n_reverted_steps } else { 0 }; + *resources.0.get_mut(abi_constants::N_STEPS_RESOURCE).unwrap_or(&mut 0) += + reverted_steps_to_add; + resources + } + /// Computes actual cost of an L1 handler transaction. pub fn from_l1_handler<'a>( tx_context: &'a TransactionContext, diff --git a/crates/blockifier/src/fee/actual_cost_test.rs b/crates/blockifier/src/fee/actual_cost_test.rs index dcb43cab28..13069e01fa 100644 --- a/crates/blockifier/src/fee/actual_cost_test.rs +++ b/crates/blockifier/src/fee/actual_cost_test.rs @@ -1,5 +1,6 @@ use rstest::{fixture, rstest}; -use starknet_api::transaction::{DeprecatedResourceBoundsMapping, L2ToL1Payload}; +use starknet_api::invoke_tx_args; +use starknet_api::transaction::{L2ToL1Payload, ValidResourceBounds}; use starknet_types_core::felt::Felt; use crate::context::BlockContext; @@ -10,12 +11,18 @@ use crate::fee::gas_usage::{ get_log_message_to_l1_emissions_cost, get_message_segment_length, }; +use crate::nonce; use crate::state::cached_state::StateChangesCount; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::{create_calldata, create_trivial_calldata, CairoVersion, BALANCE}; use crate::transaction::constants; -use crate::transaction::objects::{GasVector, HasRelatedFeeType, StarknetResources}; +use crate::transaction::objects::{ + GasVector, + GasVectorComputationMode, + HasRelatedFeeType, + StarknetResources, +}; use crate::transaction::test_utils::{ account_invoke_tx, calculate_class_info_for_testing, @@ -24,7 +31,7 @@ use crate::transaction::test_utils::{ use crate::transaction::transactions::ExecutableTransaction; use crate::utils::{u128_from_usize, usize_from_u128}; use crate::versioned_constants::VersionedConstants; -use crate::{invoke_tx_args, nonce}; + #[fixture] fn versioned_constants() -> &'static VersionedConstants { VersionedConstants::latest_constants() @@ -45,10 +52,13 @@ fn versioned_constants() -> &'static VersionedConstants { #[rstest] fn test_calculate_tx_gas_usage_basic<'a>(#[values(false, true)] use_kzg_da: bool) { // An empty transaction (a theoretical case for sanity check). - let versioned_constants = VersionedConstants::default(); + let versioned_constants = VersionedConstants::create_for_account_testing(); let empty_tx_starknet_resources = StarknetResources::default(); - let empty_tx_gas_usage_vector = - empty_tx_starknet_resources.to_gas_vector(&versioned_constants, use_kzg_da); + let empty_tx_gas_usage_vector = empty_tx_starknet_resources.to_gas_vector( + &versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ); assert_eq!(empty_tx_gas_usage_vector, GasVector::default()); // Declare. @@ -63,7 +73,8 @@ fn test_calculate_tx_gas_usage_basic<'a>(#[values(false, true)] use_kzg_da: bool None, std::iter::empty(), ); - let code_gas_cost = versioned_constants.l2_resource_gas_costs.gas_per_code_byte + let code_gas_cost = versioned_constants.archival_data_gas_costs.gas_per_code_byte + * versioned_constants.l1_to_l2_gas_price_ratio() * u128_from_usize( (class_info.bytecode_length() + class_info.sierra_program_length()) * eth_gas_constants::WORD_WIDTH @@ -71,8 +82,11 @@ fn test_calculate_tx_gas_usage_basic<'a>(#[values(false, true)] use_kzg_da: bool ); let manual_gas_vector = GasVector { l1_gas: code_gas_cost.to_integer(), ..Default::default() }; - let declare_gas_usage_vector = - declare_tx_starknet_resources.to_gas_vector(&versioned_constants, use_kzg_da); + let declare_gas_usage_vector = declare_tx_starknet_resources.to_gas_vector( + &versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ); assert_eq!(manual_gas_vector, declare_gas_usage_vector); } @@ -97,14 +111,18 @@ fn test_calculate_tx_gas_usage_basic<'a>(#[values(false, true)] use_kzg_da: bool std::iter::empty(), ); let calldata_and_signature_gas_cost = - versioned_constants.l2_resource_gas_costs.gas_per_data_felt + versioned_constants.archival_data_gas_costs.gas_per_data_felt + * versioned_constants.l1_to_l2_gas_price_ratio() * u128_from_usize(calldata_length + signature_length); let manual_starknet_gas_usage = calldata_and_signature_gas_cost.to_integer(); let manual_gas_vector = GasVector { l1_gas: manual_starknet_gas_usage, ..Default::default() } + deploy_account_tx_starknet_resources.get_state_changes_cost(use_kzg_da); - let deploy_account_gas_usage_vector = - deploy_account_tx_starknet_resources.to_gas_vector(&versioned_constants, use_kzg_da); + let deploy_account_gas_usage_vector = deploy_account_tx_starknet_resources.to_gas_vector( + &versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ); assert_eq!(manual_gas_vector, deploy_account_gas_usage_vector); // L1 handler. @@ -118,13 +136,17 @@ fn test_calculate_tx_gas_usage_basic<'a>(#[values(false, true)] use_kzg_da: bool Some(l1_handler_payload_size), std::iter::empty(), ); - let l1_handler_gas_usage_vector = - l1_handler_tx_starknet_resources.to_gas_vector(&versioned_constants, use_kzg_da); + let l1_handler_gas_usage_vector = l1_handler_tx_starknet_resources.to_gas_vector( + &versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ); // Manual calculation. let message_segment_length = get_message_segment_length(&[], Some(l1_handler_payload_size)); let calldata_and_signature_gas_cost = - versioned_constants.l2_resource_gas_costs.gas_per_data_felt + versioned_constants.archival_data_gas_costs.gas_per_data_felt + * versioned_constants.l1_to_l2_gas_price_ratio() * u128_from_usize(l1_handler_payload_size + signature_length); let manual_starknet_gas_usage = message_segment_length * eth_gas_constants::GAS_PER_MEMORY_WORD + eth_gas_constants::GAS_PER_COUNTER_DECREASE @@ -182,8 +204,11 @@ fn test_calculate_tx_gas_usage_basic<'a>(#[values(false, true)] use_kzg_da: bool call_infos_iter.clone(), ); - let l2_to_l1_messages_gas_usage_vector = - l2_to_l1_starknet_resources.to_gas_vector(&versioned_constants, use_kzg_da); + let l2_to_l1_messages_gas_usage_vector = l2_to_l1_starknet_resources.to_gas_vector( + &versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ); // Manual calculation. let message_segment_length = get_message_segment_length(&l2_to_l1_payload_lengths, None); @@ -225,8 +250,11 @@ fn test_calculate_tx_gas_usage_basic<'a>(#[values(false, true)] use_kzg_da: bool std::iter::empty(), ); - let storage_writings_gas_usage_vector = - storage_writes_starknet_resources.to_gas_vector(&versioned_constants, use_kzg_da); + let storage_writings_gas_usage_vector = storage_writes_starknet_resources.to_gas_vector( + &versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ); // Manual calculation. let manual_gas_computation = @@ -251,8 +279,11 @@ fn test_calculate_tx_gas_usage_basic<'a>(#[values(false, true)] use_kzg_da: bool call_infos_iter.clone(), ); - let gas_usage_vector = - combined_cases_starknet_resources.to_gas_vector(&versioned_constants, use_kzg_da); + let gas_usage_vector = combined_cases_starknet_resources.to_gas_vector( + &versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ); // Manual calculation. let fee_balance_discount = match use_kzg_da { @@ -286,7 +317,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(#[values(false, true)] use_kzg_da: bool // resources are taken into account). #[rstest] fn test_calculate_tx_gas_usage( - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(false, true)] use_kzg_da: bool, ) { let account_cairo_version = CairoVersion::Cairo0; @@ -327,12 +358,16 @@ fn test_calculate_tx_gas_usage( ); assert_eq!( - starknet_resources.to_gas_vector(versioned_constants, use_kzg_da), - tx_execution_info - .receipt - .resources - .starknet_resources - .to_gas_vector(versioned_constants, use_kzg_da) + starknet_resources.to_gas_vector( + versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas + ), + tx_execution_info.receipt.resources.starknet_resources.to_gas_vector( + versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas + ) ); // A tx that changes the account and some other balance in execute. @@ -378,11 +413,15 @@ fn test_calculate_tx_gas_usage( ); assert_eq!( - starknet_resources.to_gas_vector(versioned_constants, use_kzg_da), - tx_execution_info - .receipt - .resources - .starknet_resources - .to_gas_vector(versioned_constants, use_kzg_da) + starknet_resources.to_gas_vector( + versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas + ), + tx_execution_info.receipt.resources.starknet_resources.to_gas_vector( + versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas + ) ); } diff --git a/crates/blockifier/src/fee/fee_checks.rs b/crates/blockifier/src/fee/fee_checks.rs index d09c96de80..e6515e1e0c 100644 --- a/crates/blockifier/src/fee/fee_checks.rs +++ b/crates/blockifier/src/fee/fee_checks.rs @@ -5,7 +5,6 @@ use thiserror::Error; use crate::context::TransactionContext; use crate::fee::actual_cost::TransactionReceipt; use crate::fee::fee_utils::{get_balance_and_if_covers_fee, get_fee_by_gas_vector}; -use crate::fee::gas_usage::compute_discounted_gas_from_gas_vector; use crate::state::state_api::StateReader; use crate::transaction::errors::TransactionExecutionError; use crate::transaction::objects::{ @@ -61,7 +60,7 @@ impl FeeCheckReport { actual_fee: Fee, error: FeeCheckError, tx_context: &TransactionContext, - ) -> TransactionExecutionResult { + ) -> Self { let recommended_fee = match error { // If the error is insufficient balance, the recommended fee is the actual fee. // This recommendation assumes (a) the pre-validation checks were applied and pass (i.e. @@ -75,14 +74,14 @@ impl FeeCheckReport { match &tx_context.tx_info { TransactionInfo::Current(info) => get_fee_by_gas_vector( &tx_context.block_context.block_info, - GasVector::from_l1_gas(info.l1_resource_bounds()?.max_amount.into()), + GasVector::from_l1_gas(info.l1_resource_bounds().max_amount.into()), &FeeType::Strk, ), TransactionInfo::Deprecated(context) => context.max_fee, } } }; - Ok(Self { recommended_fee, error: Some(error) }) + Self { recommended_fee, error: Some(error) } } /// If the actual cost exceeds the resource bounds on the transaction, returns a fee check @@ -100,13 +99,12 @@ impl FeeCheckReport { match tx_info { TransactionInfo::Current(context) => { // Check L1 gas limit. - let max_l1_gas = context.l1_resource_bounds()?.max_amount.into(); + let max_l1_gas = context.l1_resource_bounds().max_amount.into(); // TODO(Dori, 1/7/2024): When data gas limit is added (and enforced) in resource // bounds, check it here as well (separately, with a different error variant if // limit exceeded). - let total_discounted_gas_used = - compute_discounted_gas_from_gas_vector(gas, tx_context); + let total_discounted_gas_used = gas.to_discounted_l1_gas(tx_context); if total_discounted_gas_used > max_l1_gas { return Err(FeeCheckError::MaxL1GasAmountExceeded { @@ -172,7 +170,7 @@ impl PostValidationReport { tx_receipt: &TransactionReceipt, ) -> TransactionExecutionResult<()> { // If fee is not enforced, no need to check post-execution. - if !tx_context.tx_info.enforce_fee()? { + if !tx_context.tx_info.enforce_fee() { return Ok(()); } @@ -192,7 +190,7 @@ impl PostExecutionReport { let TransactionReceipt { fee, .. } = tx_receipt; // If fee is not enforced, no need to check post-execution. - if !charge_fee || !tx_context.tx_info.enforce_fee()? { + if !charge_fee || !tx_context.tx_info.enforce_fee() { return Ok(Self(FeeCheckReport::success_report(*fee))); } @@ -216,7 +214,7 @@ impl PostExecutionReport { *fee, fee_check_error, tx_context, - )?)); + ))); } Err(other_error) => return Err(other_error), } diff --git a/crates/blockifier/src/fee/fee_test.rs b/crates/blockifier/src/fee/fee_test.rs index 9c86e5f9d3..822ac36427 100644 --- a/crates/blockifier/src/fee/fee_test.rs +++ b/crates/blockifier/src/fee/fee_test.rs @@ -4,6 +4,7 @@ use assert_matches::assert_matches; use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use rstest::rstest; +use starknet_api::invoke_tx_args; use starknet_api::transaction::Fee; use crate::abi::constants::N_STEPS_RESOURCE; @@ -11,8 +12,7 @@ use crate::blockifier::block::GasPrices; use crate::context::BlockContext; use crate::fee::actual_cost::TransactionReceipt; use crate::fee::fee_checks::{FeeCheckError, FeeCheckReportFields, PostExecutionReport}; -use crate::fee::fee_utils::calculate_l1_gas_by_vm_usage; -use crate::invoke_tx_args; +use crate::fee::fee_utils::get_vm_resources_cost; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::{ @@ -21,7 +21,7 @@ use crate::test_utils::{ DEFAULT_ETH_L1_DATA_GAS_PRICE, DEFAULT_ETH_L1_GAS_PRICE, }; -use crate::transaction::objects::GasVector; +use crate::transaction::objects::{GasVector, GasVectorComputationMode}; use crate::transaction::test_utils::{account_invoke_tx, l1_resource_bounds}; use crate::utils::u128_from_usize; use crate::versioned_constants::VersionedConstants; @@ -41,7 +41,7 @@ fn get_vm_resource_usage() -> ExecutionResources { } #[test] -fn test_simple_calculate_l1_gas_by_vm_usage() { +fn test_simple_get_vm_resource_usage() { let versioned_constants = VersionedConstants::create_for_account_testing(); let mut vm_resource_usage = get_vm_resource_usage(); let n_reverted_steps = 15; @@ -55,8 +55,13 @@ fn test_simple_calculate_l1_gas_by_vm_usage() { .to_integer(); assert_eq!( GasVector::from_l1_gas(l1_gas_by_vm_usage), - calculate_l1_gas_by_vm_usage(&versioned_constants, &vm_resource_usage, n_reverted_steps) - .unwrap() + get_vm_resources_cost( + &versioned_constants, + &vm_resource_usage, + n_reverted_steps, + &GasVectorComputationMode::NoL2Gas + ) + .unwrap() ); // Another positive flow, this time the heaviest resource is range_check_builtin. @@ -67,14 +72,19 @@ fn test_simple_calculate_l1_gas_by_vm_usage() { vm_resource_usage.builtin_instance_counter.get(&BuiltinName::range_check).unwrap(); assert_eq!( GasVector::from_l1_gas(u128_from_usize(*l1_gas_by_vm_usage)), - calculate_l1_gas_by_vm_usage(&versioned_constants, &vm_resource_usage, n_reverted_steps) - .unwrap() + get_vm_resources_cost( + &versioned_constants, + &vm_resource_usage, + n_reverted_steps, + &GasVectorComputationMode::NoL2Gas + ) + .unwrap() ); } #[test] -fn test_float_calculate_l1_gas_by_vm_usage() { - let versioned_constants = VersionedConstants::create_float_for_testing(); +fn test_float_get_vm_resource_usage() { + let versioned_constants = VersionedConstants::create_for_testing(); let mut vm_resource_usage = get_vm_resource_usage(); // Positive flow. @@ -87,8 +97,13 @@ fn test_float_calculate_l1_gas_by_vm_usage() { .to_integer(); assert_eq!( GasVector::from_l1_gas(l1_gas_by_vm_usage), - calculate_l1_gas_by_vm_usage(&versioned_constants, &vm_resource_usage, n_reverted_steps) - .unwrap() + get_vm_resources_cost( + &versioned_constants, + &vm_resource_usage, + n_reverted_steps, + &GasVectorComputationMode::NoL2Gas + ) + .unwrap() ); // Another positive flow, this time the heaviest resource is ecdsa_builtin. @@ -105,8 +120,13 @@ fn test_float_calculate_l1_gas_by_vm_usage() { assert_eq!( GasVector::from_l1_gas(l1_gas_by_vm_usage), - calculate_l1_gas_by_vm_usage(&versioned_constants, &vm_resource_usage, n_reverted_steps) - .unwrap() + get_vm_resources_cost( + &versioned_constants, + &vm_resource_usage, + n_reverted_steps, + &GasVectorComputationMode::NoL2Gas + ) + .unwrap() ); } @@ -134,13 +154,10 @@ fn test_discounted_gas_overdraft( DEFAULT_ETH_L1_DATA_GAS_PRICE.try_into().unwrap(), data_gas_price.try_into().unwrap(), VersionedConstants::latest_constants() - .l1_to_l2_gas_price_conversion(DEFAULT_ETH_L1_GAS_PRICE) - .try_into() - .unwrap(), - VersionedConstants::latest_constants() - .l1_to_l2_gas_price_conversion(gas_price) + .convert_l1_to_l2_gas(DEFAULT_ETH_L1_GAS_PRICE) .try_into() .unwrap(), + VersionedConstants::latest_constants().convert_l1_to_l2_gas(gas_price).try_into().unwrap(), ); let account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo0); diff --git a/crates/blockifier/src/fee/fee_utils.rs b/crates/blockifier/src/fee/fee_utils.rs index cce1b85227..8a97267815 100644 --- a/crates/blockifier/src/fee/fee_utils.rs +++ b/crates/blockifier/src/fee/fee_utils.rs @@ -4,7 +4,7 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use num_bigint::BigUint; use starknet_api::core::ContractAddress; use starknet_api::state::StorageKey; -use starknet_api::transaction::Fee; +use starknet_api::transaction::{Fee, Resource}; use starknet_types_core::felt::Felt; use crate::abi::abi_utils::get_fee_token_var_address; @@ -18,6 +18,7 @@ use crate::transaction::objects::{ ExecutionResourcesTraits, FeeType, GasVector, + GasVectorComputationMode, TransactionFeeResult, TransactionInfo, }; @@ -28,13 +29,15 @@ use crate::versioned_constants::VersionedConstants; #[path = "fee_test.rs"] pub mod test; -/// Calculates the L1 gas consumed when submitting the underlying Cairo program to SHARP. -/// I.e., returns the heaviest Cairo resource weight (in terms of L1 gas), as the size of +/// Calculates the gas consumed when submitting the underlying Cairo program to SHARP. +/// I.e., returns the heaviest Cairo resource weight (in terms of gas), as the size of /// a proof is determined similarly - by the (normalized) largest segment. -pub fn calculate_l1_gas_by_vm_usage( +/// The result can be in either L1 or L2 gas, according to the gas vector computation mode. +pub fn get_vm_resources_cost( versioned_constants: &VersionedConstants, vm_resource_usage: &ExecutionResources, n_reverted_steps: usize, + computation_mode: &GasVectorComputationMode, ) -> TransactionFeeResult { // TODO(Yoni, 1/7/2024): rename vm -> cairo. let vm_resource_fee_costs = versioned_constants.vm_resource_fee_cost(); @@ -65,7 +68,12 @@ pub fn calculate_l1_gas_by_vm_usage( }) .fold(0, u128::max); - Ok(GasVector::from_l1_gas(vm_l1_gas_usage)) + match computation_mode { + GasVectorComputationMode::NoL2Gas => Ok(GasVector::from_l1_gas(vm_l1_gas_usage)), + GasVectorComputationMode::All => { + Ok(GasVector::from_l2_gas(versioned_constants.convert_l1_to_l2_gas(vm_l1_gas_usage))) + } + } } /// Converts the gas vector to a fee. @@ -107,7 +115,7 @@ pub fn verify_can_pay_committed_bounds( let tx_info = &tx_context.tx_info; let committed_fee = match tx_info { TransactionInfo::Current(context) => { - let l1_bounds = context.l1_resource_bounds()?; + let l1_bounds = context.l1_resource_bounds(); let max_amount: u128 = l1_bounds.max_amount.into(); // Sender will not be charged by `max_price_per_unit`, but this check should not depend // on the current gas price. @@ -122,8 +130,9 @@ pub fn verify_can_pay_committed_bounds( } else { Err(match tx_info { TransactionInfo::Current(context) => { - let l1_bounds = context.l1_resource_bounds()?; - TransactionFeeError::L1GasBoundsExceedBalance { + let l1_bounds = context.l1_resource_bounds(); + TransactionFeeError::GasBoundsExceedBalance { + resource: Resource::L1Gas, max_amount: l1_bounds.max_amount, max_price: l1_bounds.max_price_per_unit, balance: balance_to_big_uint(&balance_low, &balance_high), diff --git a/crates/blockifier/src/fee/gas_usage.rs b/crates/blockifier/src/fee/gas_usage.rs index ecbf658ba0..a805b83502 100644 --- a/crates/blockifier/src/fee/gas_usage.rs +++ b/crates/blockifier/src/fee/gas_usage.rs @@ -1,13 +1,17 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources; -use super::fee_utils::calculate_l1_gas_by_vm_usage; +use super::fee_utils::get_vm_resources_cost; use crate::abi::constants; -use crate::context::{BlockContext, TransactionContext}; +use crate::context::BlockContext; use crate::fee::eth_gas_constants; use crate::state::cached_state::StateChangesCount; use crate::transaction::account_transaction::AccountTransaction; -use crate::transaction::objects::{GasVector, HasRelatedFeeType, TransactionPreValidationResult}; -use crate::utils::{u128_div_ceil, u128_from_usize}; +use crate::transaction::objects::{ + GasVector, + GasVectorComputationMode, + TransactionPreValidationResult, +}; +use crate::utils::u128_from_usize; #[cfg(test)] #[path = "gas_usage_test.rs"] @@ -144,6 +148,7 @@ fn get_event_emission_cost(n_topics: usize, data_length: usize) -> GasVector { pub fn estimate_minimal_gas_vector( block_context: &BlockContext, tx: &AccountTransaction, + gas_usage_vector_computation_mode: &GasVectorComputationMode, ) -> TransactionPreValidationResult { // TODO(Dori, 1/8/2023): Give names to the constant VM step estimates and regression-test them. let BlockContext { block_info, versioned_constants, .. } = block_context; @@ -180,24 +185,10 @@ pub fn estimate_minimal_gas_vector( let resources = ExecutionResources { n_steps: os_steps_for_type, ..Default::default() }; Ok(get_da_gas_cost(&state_changes_by_account_transaction, block_info.use_kzg_da) - + calculate_l1_gas_by_vm_usage(versioned_constants, &resources, 0)?) -} - -/// Compute l1_gas estimation from gas_vector using the following formula: -/// One byte of data costs either 1 data gas (in blob mode) or 16 gas (in calldata -/// mode). For gas price GP and data gas price DGP, the discount for using blobs -/// would be DGP / (16 * GP). -/// X non-data-related gas consumption and Y bytes of data, in non-blob mode, would -/// cost (X + 16*Y) units of gas. Applying the discount ratio to the data-related -/// summand, we get total_gas = (X + Y * DGP / GP). -pub fn compute_discounted_gas_from_gas_vector( - gas_usage_vector: &GasVector, - tx_context: &TransactionContext, -) -> u128 { - let gas_prices = &tx_context.block_context.block_info.gas_prices; - let GasVector { l1_gas: gas_usage, l1_data_gas: blob_gas_usage, .. } = gas_usage_vector; - let fee_type = tx_context.tx_info.fee_type(); - let gas_price = gas_prices.get_l1_gas_price_by_fee_type(&fee_type); - let data_gas_price = gas_prices.get_l1_data_gas_price_by_fee_type(&fee_type); - gas_usage + u128_div_ceil(blob_gas_usage * u128::from(data_gas_price), gas_price) + + get_vm_resources_cost( + versioned_constants, + &resources, + 0, + gas_usage_vector_computation_mode, + )?) } diff --git a/crates/blockifier/src/fee/gas_usage_test.rs b/crates/blockifier/src/fee/gas_usage_test.rs index 1d89c913db..728e9daa7a 100644 --- a/crates/blockifier/src/fee/gas_usage_test.rs +++ b/crates/blockifier/src/fee/gas_usage_test.rs @@ -2,6 +2,7 @@ use std::num::NonZeroU128; use pretty_assertions::assert_eq; use rstest::{fixture, rstest}; +use starknet_api::invoke_tx_args; use starknet_api::transaction::{EventContent, EventData, EventKey, Fee}; use starknet_types_core::felt::Felt; @@ -10,15 +11,15 @@ use crate::context::BlockContext; use crate::execution::call_info::{CallExecution, CallInfo, OrderedEvent}; use crate::fee::eth_gas_constants; use crate::fee::fee_utils::get_fee_by_gas_vector; -use crate::fee::gas_usage::{ - compute_discounted_gas_from_gas_vector, - get_da_gas_cost, - get_message_segment_length, -}; -use crate::invoke_tx_args; +use crate::fee::gas_usage::{get_da_gas_cost, get_message_segment_length}; use crate::state::cached_state::StateChangesCount; use crate::test_utils::{DEFAULT_ETH_L1_DATA_GAS_PRICE, DEFAULT_ETH_L1_GAS_PRICE}; -use crate::transaction::objects::{FeeType, GasVector, StarknetResources}; +use crate::transaction::objects::{ + FeeType, + GasVector, + GasVectorComputationMode, + StarknetResources, +}; use crate::transaction::test_utils::account_invoke_tx; use crate::utils::{u128_div_ceil, u128_from_usize}; use crate::versioned_constants::{ResourceCost, VersionedConstants}; @@ -32,16 +33,20 @@ fn test_get_event_gas_cost( versioned_constants: &VersionedConstants, #[values(false, true)] use_kzg_da: bool, ) { - let l2_resource_gas_costs = &versioned_constants.l2_resource_gas_costs; + let archival_data_gas_costs = &versioned_constants.archival_data_gas_costs; let (event_key_factor, data_word_cost) = - (l2_resource_gas_costs.event_key_factor, l2_resource_gas_costs.gas_per_data_felt); + (archival_data_gas_costs.event_key_factor, archival_data_gas_costs.gas_per_data_felt); let call_infos = vec![CallInfo::default(), CallInfo::default(), CallInfo::default()]; let call_infos_iter = call_infos.iter(); let starknet_resources = StarknetResources::new(0, 0, 0, StateChangesCount::default(), None, call_infos_iter); assert_eq!( GasVector::default(), - starknet_resources.to_gas_vector(versioned_constants, use_kzg_da) + starknet_resources.to_gas_vector( + versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas + ) ); let create_event = |keys_size: usize, data_size: usize| OrderedEvent { @@ -77,11 +82,18 @@ fn test_get_event_gas_cost( let call_infos_iter = call_infos.iter(); let expected = GasVector::from_l1_gas( // 8 keys and 11 data words overall. - (data_word_cost * (event_key_factor * 8_u128 + 11_u128)).to_integer(), + (data_word_cost + * versioned_constants.l1_to_l2_gas_price_ratio() + * (event_key_factor * 8_u128 + 11_u128)) + .to_integer(), ); let starknet_resources = StarknetResources::new(0, 0, 0, StateChangesCount::default(), None, call_infos_iter); - let gas_vector = starknet_resources.to_gas_vector(versioned_constants, use_kzg_da); + let gas_vector = starknet_resources.to_gas_vector( + versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ); assert_eq!(expected, gas_vector); assert_ne!(GasVector::default(), gas_vector) } @@ -204,11 +216,11 @@ fn test_get_message_segment_length( } #[rstest] -fn test_compute_discounted_gas_from_gas_vector() { +fn test_discounted_gas_from_gas_vector_computation() { let tx_context = BlockContext::create_for_testing().to_tx_context(&account_invoke_tx(invoke_tx_args! {})); let gas_usage = GasVector { l1_gas: 100, l1_data_gas: 2, ..Default::default() }; - let actual_result = compute_discounted_gas_from_gas_vector(&gas_usage, &tx_context); + let actual_result = gas_usage.to_discounted_l1_gas(&tx_context); let result_div_ceil = gas_usage.l1_gas + u128_div_ceil( diff --git a/crates/blockifier/src/state/cached_state.rs b/crates/blockifier/src/state/cached_state.rs index 93201f3456..deff9cc9c7 100644 --- a/crates/blockifier/src/state/cached_state.rs +++ b/crates/blockifier/src/state/cached_state.rs @@ -721,6 +721,7 @@ impl From for StateChanges { } /// Holds the number of state changes. +#[cfg_attr(feature = "transaction_serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct StateChangesCount { pub n_storage_updates: usize, diff --git a/crates/blockifier/src/test_utils.rs b/crates/blockifier/src/test_utils.rs index e31e948861..c947b654e8 100644 --- a/crates/blockifier/src/test_utils.rs +++ b/crates/blockifier/src/test_utils.rs @@ -12,53 +12,21 @@ pub mod transfers_generator; use std::collections::HashMap; use std::fs; use std::path::PathBuf; -use std::sync::Arc; -use cairo_native::starknet::SyscallResult; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; -use starknet_api::core::{ - calculate_contract_address, - ClassHash, - ContractAddress, - Nonce, - PatriciaKey, -}; +use starknet_api::core::{ClassHash, ContractAddress, Nonce, PatriciaKey}; use starknet_api::state::StorageKey; -use starknet_api::transaction::{ - Calldata, - ContractAddressSalt, - DeprecatedResourceBoundsMapping, - Resource, - ResourceBounds, - TransactionVersion, -}; -use starknet_api::{class_hash, contract_address, felt, patricia_key}; +use starknet_api::transaction::{Calldata, ContractAddressSalt, ResourceBounds, TransactionVersion, ValidResourceBounds}; +use starknet_api::{contract_address, felt, patricia_key}; use starknet_types_core::felt::Felt; -use self::dict_state_reader::DictStateReader; use crate::abi::abi_utils::{get_fee_token_var_address, selector_from_name}; -use crate::context::{BlockContext, TransactionContext}; -use crate::execution::call_info::{CallInfo, OrderedEvent}; -use crate::execution::common_hints::ExecutionMode; use crate::execution::deprecated_syscalls::hint_processor::SyscallCounter; -use crate::execution::entry_point::{ - CallEntryPoint, - ConstructorContext, - EntryPointExecutionContext, -}; -use crate::execution::execution_utils::execute_deployment; -use crate::execution::native::utils::{ - contract_address_to_native_felt, - decode_felts_as_str, - encode_str_as_felts, -}; -use crate::execution::syscalls::hint_processor::FAILED_TO_CALCULATE_CONTRACT_ADDRESS; +use crate::execution::entry_point::CallEntryPoint; use crate::execution::syscalls::SyscallSelector; -use crate::state::cached_state::{CachedState, StateChangesCount}; -use crate::state::state_api::State; -use crate::test_utils::cached_state::get_erc20_class_hash_mapping; +use crate::state::cached_state::StateChangesCount; use crate::test_utils::contracts::FeatureContract; -use crate::transaction::objects::{StarknetResources, TransactionInfo}; +use crate::transaction::objects::StarknetResources; use crate::transaction::transaction_types::TransactionType; use crate::utils::{const_max, u128_from_usize}; use crate::versioned_constants::VersionedConstants; @@ -92,9 +60,20 @@ pub const TEST_CONTRACT_SIERRA_PATH: &str = // error. #[derive(Clone, Hash, PartialEq, Eq, Copy, Debug)] pub enum CairoVersion { - Cairo0, - Cairo1, - Native, + Cairo0 = 0, + Cairo1 = 1, + Native = 2, +} + +impl From for CairoVersion { + fn from(value: isize) -> Self { + match value { + 0 => Self::Cairo0, + 1 => Self::Cairo1, + 2 => Self::Native, + _ => panic!("Invalid value for CairoVersion: {}", value), + } + } } impl Default for CairoVersion { @@ -156,8 +135,6 @@ pub const CURRENT_BLOCK_NUMBER_FOR_VALIDATE: u64 = 2000; pub const CURRENT_BLOCK_TIMESTAMP: u64 = 1072023; pub const CURRENT_BLOCK_TIMESTAMP_FOR_VALIDATE: u64 = 1069200; -pub const CHAIN_ID_NAME: &str = "SN_GOERLI"; - #[derive(Default)] pub struct NonceManager { next_nonce: HashMap, @@ -198,7 +175,7 @@ macro_rules! storage_key { } // TODO(Yoni, 1/1/2025): move to SN API. -/// A utility macro to create a [`CompiledClassHash`] from a hex string / unsigned integer +/// A utility macro to create a `CompiledClassHash` from a hex string / unsigned integer /// representation. #[macro_export] macro_rules! compiled_class_hash { @@ -253,14 +230,9 @@ pub fn erc20_external_entry_point() -> CallEntryPoint { trivial_external_entry_point_with_address(contract_address!(TEST_ERC20_FULL_CONTRACT_ADDRESS)) } -pub fn default_testing_resource_bounds() -> DeprecatedResourceBoundsMapping { - DeprecatedResourceBoundsMapping::try_from(vec![ - (Resource::L1Gas, ResourceBounds { max_amount: 0, max_price_per_unit: 1 }), - // TODO(Dori, 1/2/2024): When fee market is developed, change the default price of - // L2 gas. - (Resource::L2Gas, ResourceBounds { max_amount: 0, max_price_per_unit: 0 }), - ]) - .unwrap() +// TODO: Default testing bounds should probably be AllResourceBounds variant. +pub fn default_testing_resource_bounds() -> ValidResourceBounds { + ValidResourceBounds::L1Gas(ResourceBounds { max_amount: 0, max_price_per_unit: 1 }) } #[macro_export] @@ -484,196 +456,3 @@ pub fn update_json_value(base: &mut serde_json::Value, update: serde_json::Value _ => panic!("Both base and update should be of type serde_json::Value::Object."), } } - -pub fn create_erc20_deploy_test_state() -> CachedState { - let address_to_class_hash: HashMap = HashMap::from([( - contract_address!(TEST_ERC20_FULL_CONTRACT_ADDRESS), - class_hash!(TEST_ERC20_FULL_CONTRACT_CLASS_HASH), - )]); - - CachedState::from(DictStateReader { - address_to_class_hash, - class_hash_to_class: get_erc20_class_hash_mapping(), - ..Default::default() - }) -} - -pub fn deploy_contract( - state: &mut dyn State, - class_hash: Felt, - contract_address_salt: Felt, - calldata: &[Felt], -) -> SyscallResult<(Felt, Vec)> { - let deployer_address = ContractAddress::default(); - - let class_hash = ClassHash(class_hash); - - let wrapper_calldata = Calldata(Arc::new(calldata.to_vec())); - - let calculated_contract_address = calculate_contract_address( - ContractAddressSalt(contract_address_salt), - class_hash, - &wrapper_calldata, - deployer_address, - ) - .map_err(|_| vec![Felt::from_hex(FAILED_TO_CALCULATE_CONTRACT_ADDRESS).unwrap()])?; - - let ctor_context = ConstructorContext { - class_hash, - code_address: Some(calculated_contract_address), - storage_address: calculated_contract_address, - caller_address: deployer_address, - }; - - let call_info = execute_deployment( - state, - &mut Default::default(), - &mut EntryPointExecutionContext::new( - Arc::new(TransactionContext { - block_context: BlockContext::create_for_testing(), - tx_info: TransactionInfo::Current(Default::default()), - }), - ExecutionMode::Execute, - false, - ) - .unwrap(), - ctor_context, - wrapper_calldata, - u64::MAX, - ) - .map_err(|err| encode_str_as_felts(&err.to_string()))?; - - let return_data = call_info.execution.retdata.0; - let contract_address_felt = *calculated_contract_address.0.key(); - - Ok((contract_address_felt, return_data)) -} - -pub fn prepare_erc20_deploy_test_state() -> (ContractAddress, CachedState) { - let mut state = create_erc20_deploy_test_state(); - - let class_hash = Felt::from_hex(TEST_ERC20_FULL_CONTRACT_CLASS_HASH).unwrap(); - - let (contract_address, _) = deploy_contract( - &mut state, - class_hash, - Felt::from(0), - &[ - contract_address_to_native_felt(Signers::Alice.into()), // Recipient - contract_address_to_native_felt(Signers::Alice.into()), // Owner - ], - ) - .unwrap_or_else(|e| panic!("Failed to deploy contract: {:?}", decode_felts_as_str(&e))); - - let contract_address = ContractAddress(PatriciaKey::try_from(contract_address).unwrap()); - - (contract_address, state) -} - -#[derive(Debug, Clone, Copy)] -pub enum Signers { - Alice, - Bob, - Charlie, -} - -impl Signers { - pub fn get_address(&self) -> ContractAddress { - match self { - Signers::Alice => ContractAddress(patricia_key!(0x001u128)), - Signers::Bob => ContractAddress(patricia_key!(0x002u128)), - Signers::Charlie => ContractAddress(patricia_key!(0x003u128)), - } - } -} - -impl From for ContractAddress { - fn from(val: Signers) -> ContractAddress { - val.get_address() - } -} - -impl From for Felt { - fn from(val: Signers) -> Felt { - contract_address_to_native_felt(val.get_address()) - } -} - -#[derive(Debug, Clone)] -pub struct TestEvent { - pub data: Vec, - pub keys: Vec, -} - -impl From for TestEvent { - fn from(value: OrderedEvent) -> Self { - let event_data = value.event.data.0; - let event_keys = value.event.keys.iter().map(|e| e.0).collect(); - Self { data: event_data, keys: event_keys } - } -} - -pub struct TestContext { - pub contract_address: ContractAddress, - pub state: CachedState, - pub caller_address: ContractAddress, - pub events: Vec, -} - -impl Default for TestContext { - fn default() -> Self { - let (contract_address, state) = prepare_erc20_deploy_test_state(); - Self { contract_address, state, caller_address: contract_address, events: vec![] } - } -} - -impl TestContext { - pub fn new() -> Self { - Self::default() - } - - pub fn with_caller(mut self, caller_address: ContractAddress) -> Self { - self.caller_address = caller_address; - self - } - - pub fn call_entry_point(&mut self, entry_point_name: &str, calldata: Vec) -> Vec { - let result = self.call_entry_point_raw(entry_point_name, calldata).unwrap(); - result.execution.retdata.0.to_vec() - } - - pub fn call_entry_point_raw( - &mut self, - entry_point_name: &str, - calldata: Vec, - ) -> Result { - let entry_point_selector = selector_from_name(entry_point_name); - let calldata = Calldata(Arc::new(calldata)); - - let entry_point_call = CallEntryPoint { - calldata, - entry_point_selector, - code_address: Some(self.contract_address), - storage_address: self.contract_address, - caller_address: self.caller_address, - ..erc20_external_entry_point() - }; - - let result = - entry_point_call.execute_directly(&mut self.state).map_err(|e| e.to_string())?; - - let events = result.execution.events.clone(); - - self.events.extend(events.iter().map(|e| e.clone().into())); - - Ok(result) - } - - pub fn get_event(&self, index: usize) -> Option { - self.events.get(index).cloned() - } - - pub fn get_caller(&self) -> ContractAddress { - self.caller_address - } -} diff --git a/crates/blockifier/src/test_utils/cairo_compile.rs b/crates/blockifier/src/test_utils/cairo_compile.rs index 4678f03743..7b6a530136 100644 --- a/crates/blockifier/src/test_utils/cairo_compile.rs +++ b/crates/blockifier/src/test_utils/cairo_compile.rs @@ -4,6 +4,7 @@ use std::process::{Command, Output}; use std::{env, fs}; use cached::proc_macro::cached; +use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; use tempfile::NamedTempFile; @@ -146,6 +147,7 @@ pub fn sierra_compile( cargo_nightly_arg: Option, ) -> Vec { prepare_cairo1_compiler_deps(git_tag_override); + let cairo1_compiler_path = local_cairo1_compiler_repo_path(); // Command args common to both compilation phases. @@ -199,7 +201,24 @@ fn verify_cairo0_compiler_deps() { ); } +// We should do it in that way, to avoid multithreading when running tests, so we don't have +// conflicts with `.git/index.lock`. +// +// Reference of the error: +// fatal: Unable to create '/cairo/.git/index.lock': File exists. +// +// Another git process seems to be running in this repository, e.g. +// an editor opened by 'git commit'. Please make sure all processes +// are terminated then try again. If it still fails, a git process +// may have crashed in this repository earlier: +// remove the file manually to continue. +lazy_static! { + static ref PREPARING_CAIRO1_COMPILER_DEPS: std::sync::Mutex<()> = std::sync::Mutex::default(); +} + fn prepare_cairo1_compiler_deps(git_tag_override: Option) { + let _preparing = PREPARING_CAIRO1_COMPILER_DEPS.lock().unwrap(); + let cairo_repo_path = local_cairo1_compiler_repo_path(); let tag = git_tag_override.unwrap_or(cairo1_compiler_tag()); diff --git a/crates/blockifier/src/test_utils/contracts.rs b/crates/blockifier/src/test_utils/contracts.rs index ebd65561f8..a2a8a650f6 100644 --- a/crates/blockifier/src/test_utils/contracts.rs +++ b/crates/blockifier/src/test_utils/contracts.rs @@ -58,6 +58,8 @@ const SECURITY_TEST_CONTRACT_BASE: u32 = 6 * CLASS_HASH_BASE; const TEST_CONTRACT_BASE: u32 = 7 * CLASS_HASH_BASE; const ERC20_CONTRACT_BASE: u32 = 8 * CLASS_HASH_BASE; const SIERRA_EXECUTION_INFO_V1_CONTRACT_BASE: u32 = 10 * CLASS_HASH_BASE; +const TEST_CONTRACT_ENTRY_POINT_A_BASE: u32 = 11 * CLASS_HASH_BASE; +const TEST_CONTRACT_ENTRY_POINT_B_BASE: u32 = 12 * CLASS_HASH_BASE; // Contract names. const ACCOUNT_LONG_VALIDATE_NAME: &str = "account_with_long_validate"; @@ -68,6 +70,8 @@ const LEGACY_CONTRACT_NAME: &str = "legacy_test_contract"; const SECURITY_TEST_CONTRACT_NAME: &str = "security_tests_contract"; const TEST_CONTRACT_NAME: &str = "test_contract"; const EXECUTION_INFO_V1_CONTRACT_NAME: &str = "test_contract_execution_info_v1"; +const TEST_CONTRACT_ENTRY_POINT_A_NAME: &str = "test_contract_entrypoint_a"; +const TEST_CONTRACT_ENTRY_POINT_B_NAME: &str = "test_contract_entrypoint_b"; // ERC20 contract is in a unique location. const ERC20_CAIRO0_CONTRACT_SOURCE_PATH: &str = @@ -95,6 +99,8 @@ pub enum FeatureContract { SecurityTests, TestContract(CairoVersion), SierraExecutionInfoV1Contract, + TestContractEntryPointA, + TestContractEntryPointB, } impl FeatureContract { @@ -108,22 +114,50 @@ impl FeatureContract { | Self::ERC20(version) => *version, Self::SecurityTests => CairoVersion::Cairo0, Self::LegacyTestContract => CairoVersion::Cairo1, - Self::SierraExecutionInfoV1Contract => CairoVersion::Native, + Self::SierraExecutionInfoV1Contract + | Self::TestContractEntryPointA + | Self::TestContractEntryPointB => CairoVersion::Native, } } - fn has_two_versions(&self) -> bool { - match self { - Self::AccountWithLongValidate(_) - | Self::AccountWithoutValidations(_) - | Self::Empty(_) - | Self::FaultyAccount(_) - | Self::TestContract(_) - | Self::ERC20(_) => true, - Self::SecurityTests - | Self::LegacyTestContract - | Self::SierraExecutionInfoV1Contract => false, - } + /// Returns a bit mask of supported Cairo versions for the feature contract. + /// + /// Each bit identifies a supported Cairo version. The least significant bit is Cairo0, the next + /// bit is Cairo1, and the most significant bit is the native version. + /// + /// This order is defined in [CairoVersion] enum. + fn supported_versions(&self) -> u32 { + let supports_legacy = matches!( + self, + Self::FaultyAccount(_) + | Self::AccountWithoutValidations(_) + | Self::AccountWithLongValidate(_) + | Self::Empty(_) + | Self::TestContract(_) + | Self::SecurityTests + | Self::ERC20(_) + ); + + let supports_cairo1 = matches!( + self, + Self::FaultyAccount(_) + | Self::AccountWithoutValidations(_) + | Self::AccountWithLongValidate(_) + | Self::Empty(_) + | Self::LegacyTestContract + | Self::TestContract(_) + | Self::ERC20(_) + ); + + let supports_native = matches!( + self, + Self::SierraExecutionInfoV1Contract + | Self::TestContract(_) + | Self::TestContractEntryPointA + | Self::TestContractEntryPointB + ); + + (supports_legacy as u32) | (supports_cairo1 as u32) << 1 | (supports_native as u32) << 2 } pub fn set_cairo_version(&mut self, version: CairoVersion) { @@ -136,7 +170,9 @@ impl FeatureContract { | Self::ERC20(v) => *v = version, Self::LegacyTestContract | Self::SecurityTests - | Self::SierraExecutionInfoV1Contract => { + | Self::SierraExecutionInfoV1Contract + | Self::TestContractEntryPointA + | Self::TestContractEntryPointB => { panic!("{self:?} contract has no configurable version.") } } @@ -204,6 +240,8 @@ impl FeatureContract { Self::SecurityTests => SECURITY_TEST_CONTRACT_BASE, Self::TestContract(_) => TEST_CONTRACT_BASE, Self::SierraExecutionInfoV1Contract => SIERRA_EXECUTION_INFO_V1_CONTRACT_BASE, + Self::TestContractEntryPointA => TEST_CONTRACT_ENTRY_POINT_A_BASE, + Self::TestContractEntryPointB => TEST_CONTRACT_ENTRY_POINT_B_BASE, } } @@ -217,6 +255,8 @@ impl FeatureContract { Self::SecurityTests => SECURITY_TEST_CONTRACT_NAME, Self::TestContract(_) => TEST_CONTRACT_NAME, Self::SierraExecutionInfoV1Contract => EXECUTION_INFO_V1_CONTRACT_NAME, + Self::TestContractEntryPointA => TEST_CONTRACT_ENTRY_POINT_A_NAME, + Self::TestContractEntryPointB => TEST_CONTRACT_ENTRY_POINT_B_NAME, Self::ERC20(_) => { unreachable!() } @@ -239,7 +279,8 @@ impl FeatureContract { "feature_contracts/cairo{}/{}.cairo", match self.cairo_version() { CairoVersion::Cairo0 => "0", - CairoVersion::Cairo1 | CairoVersion::Native => "1", + CairoVersion::Cairo1 => "1", + CairoVersion::Native => "_native", }, self.get_non_erc20_base_name() ) @@ -261,7 +302,8 @@ impl FeatureContract { "feature_contracts/cairo{}/compiled/{}{}.json", match self.cairo_version() { CairoVersion::Cairo0 => "0", - CairoVersion::Cairo1 | CairoVersion::Native => "1", + CairoVersion::Cairo1 => "1", + CairoVersion::Native => "_native", }, self.get_non_erc20_base_name(), match self.cairo_version() { @@ -283,15 +325,17 @@ impl FeatureContract { CairoVersion::Cairo0 => { let extra_arg: Option = match self { // Account contracts require the account_contract flag. - FeatureContract::AccountWithLongValidate(_) - | FeatureContract::AccountWithoutValidations(_) - | FeatureContract::FaultyAccount(_) => Some("--account_contract".into()), - FeatureContract::SecurityTests => Some("--disable_hint_validation".into()), - FeatureContract::Empty(_) - | FeatureContract::TestContract(_) - | FeatureContract::LegacyTestContract - | FeatureContract::SierraExecutionInfoV1Contract => None, - FeatureContract::ERC20(_) => unreachable!(), + Self::AccountWithLongValidate(_) + | Self::AccountWithoutValidations(_) + | Self::FaultyAccount(_) => Some("--account_contract".into()), + Self::SecurityTests => Some("--disable_hint_validation".into()), + Self::Empty(_) + | Self::TestContract(_) + | Self::LegacyTestContract + | Self::SierraExecutionInfoV1Contract + | Self::TestContractEntryPointA + | Self::TestContractEntryPointB => None, + Self::ERC20(_) => unreachable!(), }; cairo0_compile(self.get_source_path(), extra_arg, false) } @@ -388,12 +432,24 @@ impl FeatureContract { // EnumIter iterates over all variants with Default::default() as the cairo // version. Self::iter().flat_map(|contract| { - if contract.has_two_versions() { - let mut other_contract = contract; - other_contract.set_cairo_version(contract.cairo_version().other()); - vec![contract, other_contract].into_iter() - } else { + // if we have only one supported version, return the contract as is. + if contract.supported_versions().is_power_of_two() { vec![contract].into_iter() + } else { + let supported_versions = contract.supported_versions(); + + // if we have multiple supported versions, return the contract for each supported + // version. + (0..3isize) + .filter(|i| supported_versions & (1u32 << i) != 0) + .map(move |i| { + let mut contract = contract; + contract.set_cairo_version(CairoVersion::from(i)); + + contract + }) + .collect::>() + .into_iter() } }) } diff --git a/crates/blockifier/src/test_utils/declare.rs b/crates/blockifier/src/test_utils/declare.rs index ab5470c130..d78f3ff06c 100644 --- a/crates/blockifier/src/test_utils/declare.rs +++ b/crates/blockifier/src/test_utils/declare.rs @@ -1,129 +1,12 @@ -use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; -use starknet_api::data_availability::DataAvailabilityMode; -use starknet_api::transaction::{ - AccountDeploymentData, - DeclareTransactionV0V1, - DeclareTransactionV2, - DeclareTransactionV3, - DeprecatedResourceBoundsMapping, - Fee, - PaymasterData, - Tip, - TransactionHash, - TransactionSignature, - TransactionVersion, -}; +use starknet_api::test_utils::declare::DeclareTxArgs; use crate::execution::contract_class::ClassInfo; -use crate::test_utils::default_testing_resource_bounds; use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::transactions::DeclareTransaction; -#[derive(Clone)] -pub struct DeclareTxArgs { - pub max_fee: Fee, - pub signature: TransactionSignature, - pub sender_address: ContractAddress, - pub version: TransactionVersion, - pub resource_bounds: DeprecatedResourceBoundsMapping, - pub tip: Tip, - pub nonce_data_availability_mode: DataAvailabilityMode, - pub fee_data_availability_mode: DataAvailabilityMode, - pub paymaster_data: PaymasterData, - pub account_deployment_data: AccountDeploymentData, - pub nonce: Nonce, - pub class_hash: ClassHash, - pub compiled_class_hash: CompiledClassHash, - pub tx_hash: TransactionHash, -} - -impl Default for DeclareTxArgs { - fn default() -> Self { - Self { - max_fee: Fee::default(), - signature: TransactionSignature::default(), - sender_address: ContractAddress::default(), - version: TransactionVersion::THREE, - resource_bounds: default_testing_resource_bounds(), - tip: Tip::default(), - nonce_data_availability_mode: DataAvailabilityMode::L1, - fee_data_availability_mode: DataAvailabilityMode::L1, - paymaster_data: PaymasterData::default(), - account_deployment_data: AccountDeploymentData::default(), - nonce: Nonce::default(), - class_hash: ClassHash::default(), - compiled_class_hash: CompiledClassHash::default(), - tx_hash: TransactionHash::default(), - } - } -} - -/// Utility macro for creating `DeclareTxArgs` to reduce boilerplate. -#[macro_export] -macro_rules! declare_tx_args { - ($($field:ident $(: $value:expr)?),* $(,)?) => { - $crate::test_utils::declare::DeclareTxArgs { - $($field $(: $value)?,)* - ..Default::default() - } - }; - ($($field:ident $(: $value:expr)?),* , ..$defaults:expr) => { - $crate::test_utils::declare::DeclareTxArgs { - $($field $(: $value)?,)* - ..$defaults - } - }; -} - pub fn declare_tx(declare_tx_args: DeclareTxArgs, class_info: ClassInfo) -> AccountTransaction { - AccountTransaction::Declare( - DeclareTransaction::new( - // TODO: Make TransactionVersion an enum and use match here. - if declare_tx_args.version == TransactionVersion::ZERO { - starknet_api::transaction::DeclareTransaction::V0(DeclareTransactionV0V1 { - max_fee: declare_tx_args.max_fee, - signature: declare_tx_args.signature, - sender_address: declare_tx_args.sender_address, - nonce: declare_tx_args.nonce, - class_hash: declare_tx_args.class_hash, - }) - } else if declare_tx_args.version == TransactionVersion::ONE { - starknet_api::transaction::DeclareTransaction::V1(DeclareTransactionV0V1 { - max_fee: declare_tx_args.max_fee, - signature: declare_tx_args.signature, - sender_address: declare_tx_args.sender_address, - nonce: declare_tx_args.nonce, - class_hash: declare_tx_args.class_hash, - }) - } else if declare_tx_args.version == TransactionVersion::TWO { - starknet_api::transaction::DeclareTransaction::V2(DeclareTransactionV2 { - max_fee: declare_tx_args.max_fee, - signature: declare_tx_args.signature, - sender_address: declare_tx_args.sender_address, - nonce: declare_tx_args.nonce, - class_hash: declare_tx_args.class_hash, - compiled_class_hash: declare_tx_args.compiled_class_hash, - }) - } else if declare_tx_args.version == TransactionVersion::THREE { - starknet_api::transaction::DeclareTransaction::V3(DeclareTransactionV3 { - signature: declare_tx_args.signature, - sender_address: declare_tx_args.sender_address, - resource_bounds: declare_tx_args.resource_bounds, - tip: declare_tx_args.tip, - nonce_data_availability_mode: declare_tx_args.nonce_data_availability_mode, - fee_data_availability_mode: declare_tx_args.fee_data_availability_mode, - paymaster_data: declare_tx_args.paymaster_data, - account_deployment_data: declare_tx_args.account_deployment_data, - nonce: declare_tx_args.nonce, - class_hash: declare_tx_args.class_hash, - compiled_class_hash: declare_tx_args.compiled_class_hash, - }) - } else { - panic!("Unsupported transaction version: {:?}.", declare_tx_args.version) - }, - declare_tx_args.tx_hash, - class_info, - ) - .unwrap(), - ) + let tx_hash = declare_tx_args.tx_hash; + let declare_tx = starknet_api::test_utils::declare::declare_tx(declare_tx_args); + + AccountTransaction::Declare(DeclareTransaction::new(declare_tx, tx_hash, class_info).unwrap()) } diff --git a/crates/blockifier/src/test_utils/deploy_account.rs b/crates/blockifier/src/test_utils/deploy_account.rs index 1ae7a58340..2b9267a267 100644 --- a/crates/blockifier/src/test_utils/deploy_account.rs +++ b/crates/blockifier/src/test_utils/deploy_account.rs @@ -1,80 +1,15 @@ -use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress, Nonce}; -use starknet_api::data_availability::DataAvailabilityMode; -use starknet_api::transaction::{ - Calldata, - ContractAddressSalt, - DeployAccountTransactionV1, - DeployAccountTransactionV3, - DeprecatedResourceBoundsMapping, - Fee, - PaymasterData, - Tip, - TransactionHash, - TransactionSignature, - TransactionVersion, -}; +use starknet_api::core::calculate_contract_address; +use starknet_api::test_utils::deploy_account::DeployAccountTxArgs; +use starknet_api::transaction::TransactionHash; -use crate::test_utils::{default_testing_resource_bounds, NonceManager}; +use crate::test_utils::NonceManager; use crate::transaction::transactions::DeployAccountTransaction; -#[derive(Clone)] -pub struct DeployAccountTxArgs { - pub max_fee: Fee, - pub signature: TransactionSignature, - pub deployer_address: ContractAddress, - pub version: TransactionVersion, - pub resource_bounds: DeprecatedResourceBoundsMapping, - pub tip: Tip, - pub nonce_data_availability_mode: DataAvailabilityMode, - pub fee_data_availability_mode: DataAvailabilityMode, - pub paymaster_data: PaymasterData, - pub nonce: Nonce, - pub class_hash: ClassHash, - pub contract_address_salt: ContractAddressSalt, - pub constructor_calldata: Calldata, -} - -impl Default for DeployAccountTxArgs { - fn default() -> Self { - DeployAccountTxArgs { - max_fee: Fee::default(), - signature: TransactionSignature::default(), - deployer_address: ContractAddress::default(), - version: TransactionVersion::THREE, - resource_bounds: default_testing_resource_bounds(), - tip: Tip::default(), - nonce_data_availability_mode: DataAvailabilityMode::L1, - fee_data_availability_mode: DataAvailabilityMode::L1, - paymaster_data: PaymasterData::default(), - nonce: Nonce::default(), - class_hash: ClassHash::default(), - contract_address_salt: ContractAddressSalt::default(), - constructor_calldata: Calldata::default(), - } - } -} - -/// Utility macro for creating `DeployAccountTxArgs` to reduce boilerplate. -#[macro_export] -macro_rules! deploy_account_tx_args { - ($($field:ident $(: $value:expr)?),* $(,)?) => { - $crate::test_utils::deploy_account::DeployAccountTxArgs { - $($field $(: $value)?,)* - ..Default::default() - } - }; - ($($field:ident $(: $value:expr)?),* , ..$defaults:expr) => { - $crate::test_utils::deploy_account::DeployAccountTxArgs { - $($field $(: $value)?,)* - ..$defaults - } - }; -} - pub fn deploy_account_tx( deploy_tx_args: DeployAccountTxArgs, nonce_manager: &mut NonceManager, ) -> DeployAccountTransaction { + let default_tx_hash = TransactionHash::default(); let contract_address = calculate_contract_address( deploy_tx_args.contract_address_salt, deploy_tx_args.class_hash, @@ -83,32 +18,9 @@ pub fn deploy_account_tx( ) .unwrap(); - // TODO: Make TransactionVersion an enum and use match here. - let tx = if deploy_tx_args.version == TransactionVersion::ONE { - starknet_api::transaction::DeployAccountTransaction::V1(DeployAccountTransactionV1 { - max_fee: deploy_tx_args.max_fee, - signature: deploy_tx_args.signature, - nonce: nonce_manager.next(contract_address), - class_hash: deploy_tx_args.class_hash, - contract_address_salt: deploy_tx_args.contract_address_salt, - constructor_calldata: deploy_tx_args.constructor_calldata, - }) - } else if deploy_tx_args.version == TransactionVersion::THREE { - starknet_api::transaction::DeployAccountTransaction::V3(DeployAccountTransactionV3 { - signature: deploy_tx_args.signature, - resource_bounds: deploy_tx_args.resource_bounds, - tip: deploy_tx_args.tip, - nonce_data_availability_mode: deploy_tx_args.nonce_data_availability_mode, - fee_data_availability_mode: deploy_tx_args.fee_data_availability_mode, - paymaster_data: deploy_tx_args.paymaster_data, - nonce: nonce_manager.next(contract_address), - class_hash: deploy_tx_args.class_hash, - contract_address_salt: deploy_tx_args.contract_address_salt, - constructor_calldata: deploy_tx_args.constructor_calldata, - }) - } else { - panic!("Unsupported transaction version: {:?}.", deploy_tx_args.version) - }; - - DeployAccountTransaction::new(tx, TransactionHash::default(), contract_address) + let deploy_account_tx = starknet_api::test_utils::deploy_account::deploy_account_tx( + deploy_tx_args, + nonce_manager.next(contract_address), + ); + DeployAccountTransaction::new(deploy_account_tx, default_tx_hash, contract_address) } diff --git a/crates/blockifier/src/test_utils/invoke.rs b/crates/blockifier/src/test_utils/invoke.rs index b1e025bc0e..a5898d31fb 100644 --- a/crates/blockifier/src/test_utils/invoke.rs +++ b/crates/blockifier/src/test_utils/invoke.rs @@ -1,81 +1,13 @@ -use starknet_api::calldata; -use starknet_api::core::{ContractAddress, Nonce}; -use starknet_api::data_availability::DataAvailabilityMode; -use starknet_api::transaction::{ - AccountDeploymentData, - Calldata, - DeprecatedResourceBoundsMapping, - Fee, - InvokeTransactionV0, - InvokeTransactionV1, - InvokeTransactionV3, - PaymasterData, - Tip, - TransactionHash, - TransactionSignature, - TransactionVersion, -}; +use starknet_api::test_utils::invoke::InvokeTxArgs; +use starknet_api::transaction::{InvokeTransactionV0, TransactionHash, TransactionVersion}; use crate::abi::abi_utils::selector_from_name; -use crate::test_utils::default_testing_resource_bounds; use crate::transaction::constants::EXECUTE_ENTRY_POINT_NAME; use crate::transaction::transactions::InvokeTransaction; -#[derive(Clone)] -pub struct InvokeTxArgs { - pub max_fee: Fee, - pub signature: TransactionSignature, - pub sender_address: ContractAddress, - pub calldata: Calldata, - pub version: TransactionVersion, - pub resource_bounds: DeprecatedResourceBoundsMapping, - pub tip: Tip, - pub nonce_data_availability_mode: DataAvailabilityMode, - pub fee_data_availability_mode: DataAvailabilityMode, - pub paymaster_data: PaymasterData, - pub account_deployment_data: AccountDeploymentData, - pub nonce: Nonce, - pub only_query: bool, -} - -impl Default for InvokeTxArgs { - fn default() -> Self { - InvokeTxArgs { - max_fee: Fee::default(), - signature: TransactionSignature::default(), - sender_address: ContractAddress::default(), - calldata: calldata![], - version: TransactionVersion::THREE, - resource_bounds: default_testing_resource_bounds(), - tip: Tip::default(), - nonce_data_availability_mode: DataAvailabilityMode::L1, - fee_data_availability_mode: DataAvailabilityMode::L1, - paymaster_data: PaymasterData::default(), - account_deployment_data: AccountDeploymentData::default(), - nonce: Nonce::default(), - only_query: false, - } - } -} - -/// Utility macro for creating `InvokeTxArgs` to reduce boilerplate. -#[macro_export] -macro_rules! invoke_tx_args { - ($($field:ident $(: $value:expr)?),* $(,)?) => { - $crate::test_utils::invoke::InvokeTxArgs { - $($field $(: $value)?,)* - ..Default::default() - } - }; - ($($field:ident $(: $value:expr)?),* , ..$defaults:expr) => { - $crate::test_utils::invoke::InvokeTxArgs { - $($field $(: $value)?,)* - ..$defaults - } - }; -} - pub fn invoke_tx(invoke_args: InvokeTxArgs) -> InvokeTransaction { + let default_tx_hash = TransactionHash::default(); + let only_query = invoke_args.only_query; // TODO: Make TransactionVersion an enum and use match here. let invoke_tx = if invoke_args.version == TransactionVersion::ZERO { starknet_api::transaction::InvokeTransaction::V0(InvokeTransactionV0 { @@ -86,33 +18,11 @@ pub fn invoke_tx(invoke_args: InvokeTxArgs) -> InvokeTransaction { // V0 transactions should always select the `__execute__` entry point. entry_point_selector: selector_from_name(EXECUTE_ENTRY_POINT_NAME), }) - } else if invoke_args.version == TransactionVersion::ONE { - starknet_api::transaction::InvokeTransaction::V1(InvokeTransactionV1 { - max_fee: invoke_args.max_fee, - sender_address: invoke_args.sender_address, - nonce: invoke_args.nonce, - calldata: invoke_args.calldata, - signature: invoke_args.signature, - }) - } else if invoke_args.version == TransactionVersion::THREE { - starknet_api::transaction::InvokeTransaction::V3(InvokeTransactionV3 { - resource_bounds: invoke_args.resource_bounds, - calldata: invoke_args.calldata, - sender_address: invoke_args.sender_address, - nonce: invoke_args.nonce, - signature: invoke_args.signature, - tip: invoke_args.tip, - nonce_data_availability_mode: invoke_args.nonce_data_availability_mode, - fee_data_availability_mode: invoke_args.fee_data_availability_mode, - paymaster_data: invoke_args.paymaster_data, - account_deployment_data: invoke_args.account_deployment_data, - }) } else { - panic!("Unsupported transaction version: {:?}.", invoke_args.version) + starknet_api::test_utils::invoke::invoke_tx(invoke_args) }; - let default_tx_hash = TransactionHash::default(); - match invoke_args.only_query { + match only_query { true => InvokeTransaction::new_for_query(invoke_tx, default_tx_hash), false => InvokeTransaction::new(invoke_tx, default_tx_hash), } diff --git a/crates/blockifier/src/test_utils/prices.rs b/crates/blockifier/src/test_utils/prices.rs index bc2592aade..343ebe7ad5 100644 --- a/crates/blockifier/src/test_utils/prices.rs +++ b/crates/blockifier/src/test_utils/prices.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use cached::proc_macro::cached; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::core::ContractAddress; +use starknet_api::test_utils::invoke::InvokeTxArgs; use starknet_api::transaction::Calldata; use starknet_api::{calldata, felt}; @@ -12,7 +13,6 @@ use crate::execution::common_hints::ExecutionMode; use crate::execution::entry_point::{CallEntryPoint, EntryPointExecutionContext}; use crate::state::state_api::State; use crate::test_utils::initial_test_state::test_state; -use crate::test_utils::invoke::InvokeTxArgs; use crate::test_utils::BALANCE; use crate::transaction::constants; use crate::transaction::objects::FeeType; @@ -75,8 +75,7 @@ fn fee_transfer_resources( Arc::new(block_context.to_tx_context(&account_invoke_tx(InvokeTxArgs::default()))), ExecutionMode::Execute, false, - ) - .unwrap(), + ), ) .unwrap() .resources diff --git a/crates/blockifier/src/test_utils/struct_impls.rs b/crates/blockifier/src/test_utils/struct_impls.rs index 19a820059b..64f053192f 100644 --- a/crates/blockifier/src/test_utils/struct_impls.rs +++ b/crates/blockifier/src/test_utils/struct_impls.rs @@ -23,7 +23,6 @@ use crate::fee::fee_utils::get_fee_by_gas_vector; use crate::state::state_api::State; use crate::test_utils::{ get_raw_contract_class, - CHAIN_ID_NAME, CURRENT_BLOCK_NUMBER, CURRENT_BLOCK_TIMESTAMP, DEFAULT_ETH_L1_DATA_GAS_PRICE, @@ -37,6 +36,7 @@ use crate::test_utils::{ use crate::transaction::objects::{ DeprecatedTransactionInfo, FeeType, + GasVectorComputationMode, TransactionFeeResult, TransactionInfo, TransactionResources, @@ -68,8 +68,7 @@ impl CallEntryPoint { let tx_context = TransactionContext { block_context: BlockContext::create_for_testing(), tx_info }; let mut context = - EntryPointExecutionContext::new_invoke(Arc::new(tx_context), limit_steps_by_resources) - .unwrap(); + EntryPointExecutionContext::new_invoke(Arc::new(tx_context), limit_steps_by_resources); self.execute(state, &mut ExecutionResources::default(), &mut context) } @@ -97,8 +96,7 @@ impl CallEntryPoint { let mut context = EntryPointExecutionContext::new_validate( Arc::new(tx_context), limit_steps_by_resources, - ) - .unwrap(); + ); self.execute(state, &mut ExecutionResources::default(), &mut context) } } @@ -118,6 +116,7 @@ impl TransactionResources { let gas_vector = self.to_gas_vector( &block_context.versioned_constants, block_context.block_info.use_kzg_da, + &GasVectorComputationMode::NoL2Gas, )?; Ok(get_fee_by_gas_vector(&block_context.block_info, gas_vector, fee_type)) } @@ -141,7 +140,7 @@ impl GasCosts { impl ChainInfo { pub fn create_for_testing() -> Self { Self { - chain_id: ChainId::Other(CHAIN_ID_NAME.to_string()), + chain_id: ChainId::create_for_testing(), fee_token_addresses: FeeTokenAddresses { eth_fee_token_address: contract_address!(TEST_ERC20_CONTRACT_ADDRESS), strk_fee_token_address: contract_address!(TEST_ERC20_CONTRACT_ADDRESS2), @@ -162,11 +161,11 @@ impl BlockInfo { DEFAULT_ETH_L1_DATA_GAS_PRICE.try_into().unwrap(), DEFAULT_STRK_L1_DATA_GAS_PRICE.try_into().unwrap(), VersionedConstants::latest_constants() - .l1_to_l2_gas_price_conversion(DEFAULT_ETH_L1_GAS_PRICE) + .convert_l1_to_l2_gas(DEFAULT_ETH_L1_GAS_PRICE) .try_into() .unwrap(), VersionedConstants::latest_constants() - .l1_to_l2_gas_price_conversion(DEFAULT_STRK_L1_GAS_PRICE) + .convert_l1_to_l2_gas(DEFAULT_STRK_L1_GAS_PRICE) .try_into() .unwrap(), ), diff --git a/crates/blockifier/src/test_utils/transfers_generator.rs b/crates/blockifier/src/test_utils/transfers_generator.rs index 3d3a6a911d..ffe0c818af 100644 --- a/crates/blockifier/src/test_utils/transfers_generator.rs +++ b/crates/blockifier/src/test_utils/transfers_generator.rs @@ -2,14 +2,13 @@ use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use starknet_api::core::ContractAddress; use starknet_api::transaction::{Calldata, Fee, TransactionVersion}; -use starknet_api::{calldata, felt}; +use starknet_api::{calldata, felt, invoke_tx_args}; use starknet_types_core::felt::Felt; use crate::abi::abi_utils::selector_from_name; use crate::blockifier::config::{ConcurrencyConfig, TransactionExecutorConfig}; use crate::blockifier::transaction_executor::TransactionExecutor; use crate::context::{BlockContext, ChainInfo}; -use crate::invoke_tx_args; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::dict_state_reader::DictStateReader; use crate::test_utils::initial_test_state::test_state; diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index fec8820e94..224593b7a9 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -7,6 +7,7 @@ use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::transaction::{ Calldata, Fee, + Resource, ResourceBounds, TransactionHash, TransactionVersion, @@ -25,7 +26,7 @@ use crate::fee::fee_utils::{ get_sequencer_balance_keys, verify_can_pay_committed_bounds, }; -use crate::fee::gas_usage::{compute_discounted_gas_from_gas_vector, estimate_minimal_gas_vector}; +use crate::fee::gas_usage::estimate_minimal_gas_vector; use crate::retdata; use crate::state::cached_state::{StateChanges, TransactionalState}; use crate::state::state_api::{State, StateReader, UpdatableState}; @@ -215,7 +216,7 @@ impl AccountTransaction { let tx_info = &tx_context.tx_info; Self::handle_nonce(state, tx_info, strict_nonce_check)?; - if charge_fee && tx_info.enforce_fee()? { + if charge_fee && tx_info.enforce_fee() { self.check_fee_bounds(tx_context)?; verify_can_pay_committed_bounds(state, tx_context)?; @@ -228,11 +229,13 @@ impl AccountTransaction { &self, tx_context: &TransactionContext, ) -> TransactionPreValidationResult<()> { - let minimal_l1_gas_amount_vector = - estimate_minimal_gas_vector(&tx_context.block_context, self)?; + let minimal_l1_gas_amount_vector = estimate_minimal_gas_vector( + &tx_context.block_context, + self, + &tx_context.get_gas_vector_computation_mode(), + )?; // TODO(Aner, 30/01/24): modify once data gas limit is enforced. - let minimal_l1_gas_amount = - compute_discounted_gas_from_gas_vector(&minimal_l1_gas_amount_vector, tx_context); + let minimal_l1_gas_amount = minimal_l1_gas_amount_vector.to_discounted_l1_gas(tx_context); let TransactionContext { block_context, tx_info } = tx_context; let block_info = &block_context.block_info; @@ -242,15 +245,16 @@ impl AccountTransaction { let ResourceBounds { max_amount: max_l1_gas_amount, max_price_per_unit: max_l1_gas_price, - } = context.l1_resource_bounds()?; + } = context.l1_resource_bounds(); let max_l1_gas_amount_as_u128: u128 = max_l1_gas_amount.into(); if max_l1_gas_amount_as_u128 < minimal_l1_gas_amount { - return Err(TransactionFeeError::MaxL1GasAmountTooLow { - max_l1_gas_amount, + return Err(TransactionFeeError::MaxGasAmountTooLow { + resource: Resource::L1Gas, + max_gas_amount: max_l1_gas_amount, // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why // the convertion works. - minimal_l1_gas_amount: (minimal_l1_gas_amount + minimal_gas_amount: (minimal_l1_gas_amount .try_into() .expect("Failed to convert u128 to u64.")), })?; @@ -259,9 +263,10 @@ impl AccountTransaction { let actual_l1_gas_price = block_info.gas_prices.get_l1_gas_price_by_fee_type(fee_type); if max_l1_gas_price < actual_l1_gas_price.into() { - return Err(TransactionFeeError::MaxL1GasPriceTooLow { - max_l1_gas_price, - actual_l1_gas_price: actual_l1_gas_price.into(), + return Err(TransactionFeeError::MaxGasPriceTooLow { + resource: Resource::L1Gas, + max_gas_price: max_l1_gas_price, + actual_gas_price: actual_l1_gas_price.into(), })?; } } @@ -320,16 +325,13 @@ impl AccountTransaction { } } - fn assert_actual_fee_in_bounds( - tx_context: &Arc, - actual_fee: Fee, - ) -> TransactionExecutionResult<()> { + fn assert_actual_fee_in_bounds(tx_context: &Arc, actual_fee: Fee) { match &tx_context.tx_info { TransactionInfo::Current(context) => { let ResourceBounds { max_amount: max_l1_gas_amount, max_price_per_unit: max_l1_gas_price, - } = context.l1_resource_bounds()?; + } = context.l1_resource_bounds(); if actual_fee > Fee(u128::from(max_l1_gas_amount) * max_l1_gas_price) { panic!( "Actual fee {:#?} exceeded bounds; max amount is {:#?}, max price is @@ -347,7 +349,6 @@ impl AccountTransaction { } } } - Ok(()) } fn handle_fee( @@ -364,7 +365,7 @@ impl AccountTransaction { } // TODO(Amos, 8/04/2024): Add test for this assert. - Self::assert_actual_fee_in_bounds(&tx_context, actual_fee)?; + Self::assert_actual_fee_in_bounds(&tx_context, actual_fee); let fee_transfer_call_info = if concurrency_mode && !tx_context.is_sequencer_the_sender() { Self::concurrency_execute_fee_transfer(state, tx_context, actual_fee)? @@ -404,7 +405,7 @@ impl AccountTransaction { initial_gas: block_context.versioned_constants.os_constants.gas_costs.initial_gas_cost, }; - let mut context = EntryPointExecutionContext::new_invoke(tx_context, true)?; + let mut context = EntryPointExecutionContext::new_invoke(tx_context, true); Ok(fee_transfer_call .execute(state, &mut ExecutionResources::default(), &mut context) @@ -473,7 +474,7 @@ impl AccountTransaction { // Also, the execution context required form the `DeployAccount` execute phase is // validation context. let mut execution_context = - EntryPointExecutionContext::new_validate(tx_context.clone(), charge_fee)?; + EntryPointExecutionContext::new_validate(tx_context.clone(), charge_fee); execute_call_info = self.run_execute(state, &mut resources, &mut execution_context, remaining_gas)?; validate_call_info = self.handle_validate_tx( @@ -486,7 +487,7 @@ impl AccountTransaction { )?; } else { let mut execution_context = - EntryPointExecutionContext::new_invoke(tx_context.clone(), charge_fee)?; + EntryPointExecutionContext::new_invoke(tx_context.clone(), charge_fee); validate_call_info = self.handle_validate_tx( state, &mut resources, @@ -530,7 +531,7 @@ impl AccountTransaction { ) -> TransactionExecutionResult { let mut resources = ExecutionResources::default(); let mut execution_context = - EntryPointExecutionContext::new_invoke(tx_context.clone(), charge_fee)?; + EntryPointExecutionContext::new_invoke(tx_context.clone(), charge_fee); // Run the validation, and if execution later fails, only keep the validation diff. let validate_call_info = self.handle_validate_tx( state, @@ -791,7 +792,7 @@ impl ValidatableTransaction for AccountTransaction { limit_steps_by_resources: bool, ) -> TransactionExecutionResult> { let mut context = - EntryPointExecutionContext::new_validate(tx_context, limit_steps_by_resources)?; + EntryPointExecutionContext::new_validate(tx_context, limit_steps_by_resources); let tx_info = &context.tx_context.tx_info; if tx_info.is_v0() { return Ok(None); diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index 35f899ca2e..663f06a1b9 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -8,16 +8,26 @@ use rstest::rstest; use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress, PatriciaKey}; use starknet_api::hash::StarkHash; use starknet_api::state::StorageKey; +use starknet_api::test_utils::invoke::InvokeTxArgs; use starknet_api::transaction::{ Calldata, ContractAddressSalt, DeclareTransactionV2, - DeprecatedResourceBoundsMapping, Fee, TransactionHash, TransactionVersion, + ValidResourceBounds, +}; +use starknet_api::{ + calldata, + class_hash, + contract_address, + declare_tx_args, + deploy_account_tx_args, + felt, + invoke_tx_args, + patricia_key, }; -use starknet_api::{calldata, class_hash, contract_address, felt, patricia_key}; use starknet_types_core::felt::Felt; use crate::abi::abi_utils::{ @@ -37,7 +47,6 @@ use crate::test_utils::contracts::FeatureContract; use crate::test_utils::declare::declare_tx; use crate::test_utils::deploy_account::deploy_account_tx; use crate::test_utils::initial_test_state::{fund_account, test_state}; -use crate::test_utils::invoke::InvokeTxArgs; use crate::test_utils::{ create_calldata, create_trivial_calldata, @@ -52,7 +61,13 @@ use crate::test_utils::{ }; use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::constants::TRANSFER_ENTRY_POINT_NAME; -use crate::transaction::objects::{FeeType, GasVector, HasRelatedFeeType, TransactionInfoCreator}; +use crate::transaction::objects::{ + FeeType, + GasVector, + GasVectorComputationMode, + HasRelatedFeeType, + TransactionInfoCreator, +}; use crate::transaction::test_utils::{ account_invoke_tx, block_context, @@ -70,17 +85,10 @@ use crate::transaction::test_utils::{ }; use crate::transaction::transaction_types::TransactionType; use crate::transaction::transactions::{DeclareTransaction, ExecutableTransaction, ExecutionFlags}; -use crate::{ - check_transaction_execution_error_for_invalid_scenario, - declare_tx_args, - deploy_account_tx_args, - invoke_tx_args, - nonce, - storage_key, -}; +use crate::{check_transaction_execution_error_for_invalid_scenario, nonce, storage_key}; #[rstest] -fn test_circuit(block_context: BlockContext, max_resource_bounds: DeprecatedResourceBoundsMapping) { +fn test_circuit(block_context: BlockContext, max_resource_bounds: ValidResourceBounds) { let test_contract = FeatureContract::TestContract(CairoVersion::Cairo1); let account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1); let chain_info = &block_context.chain_info; @@ -110,14 +118,11 @@ fn test_circuit(block_context: BlockContext, max_resource_bounds: DeprecatedReso .unwrap(); assert!(tx_execution_info.revert_error.is_none()); - assert_eq!(tx_execution_info.receipt.gas, GasVector::from_l1_gas(6682)); + assert_eq!(tx_execution_info.receipt.gas, GasVector::from_l1_gas(6806)); } #[rstest] -fn test_rc96_holes( - block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, -) { +fn test_rc96_holes(block_context: BlockContext, max_resource_bounds: ValidResourceBounds) { let test_contract = FeatureContract::TestContract(CairoVersion::Cairo1); let account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1); let chain_info = &block_context.chain_info; @@ -152,7 +157,7 @@ fn test_rc96_holes( [&BuiltinName::range_check96], 24 ); - assert_eq!(tx_execution_info.receipt.gas, GasVector::from_l1_gas(6598)); + assert_eq!(tx_execution_info.receipt.gas, GasVector::from_l1_gas(6722)); } #[rstest] @@ -174,7 +179,7 @@ fn test_fee_enforcement( ); let account_tx = AccountTransaction::DeployAccount(deploy_account_tx); - let enforce_fee = account_tx.create_tx_info().enforce_fee().unwrap(); + let enforce_fee = account_tx.create_tx_info().enforce_fee(); let result = account_tx.execute(state, &block_context, true, true); assert_eq!(result.is_err(), enforce_fee); } @@ -208,7 +213,7 @@ fn test_enforce_fee_false_works(block_context: BlockContext, #[case] version: Tr fn test_account_flow_test( block_context: BlockContext, max_fee: Fee, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(TransactionVersion::ZERO, TransactionVersion::ONE, TransactionVersion::THREE)] tx_version: TransactionVersion, #[values(true, false)] only_query: bool, @@ -240,7 +245,7 @@ fn test_account_flow_test( fn test_invoke_tx_from_non_deployed_account( block_context: BlockContext, max_fee: Fee, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[case] tx_version: TransactionVersion, ) { let TestInitData { mut state, account_address, contract_address: _, mut nonce_manager } = @@ -289,10 +294,10 @@ fn test_infinite_recursion( #[values(true, false)] success: bool, #[values(true, false)] normal_recurse: bool, mut block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, ) { // Limit the number of execution steps (so we quickly hit the limit). - block_context.versioned_constants.invoke_tx_max_n_steps = 4100; + block_context.versioned_constants.invoke_tx_max_n_steps = 4200; let TestInitData { mut state, account_address, contract_address, mut nonce_manager } = create_test_init_data(&block_context.chain_info, CairoVersion::Cairo0); @@ -344,7 +349,7 @@ fn test_infinite_recursion( fn test_max_fee_limit_validate( block_context: BlockContext, #[case] version: TransactionVersion, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, ) { let chain_info = &block_context.chain_info; let TestInitData { mut state, account_address, contract_address, mut nonce_manager } = @@ -415,8 +420,12 @@ fn test_max_fee_limit_validate( resource_bounds: max_resource_bounds, ..tx_args.clone() }); - let estimated_min_gas_usage_vector = - estimate_minimal_gas_vector(&block_context, &account_tx).unwrap(); + let estimated_min_gas_usage_vector = estimate_minimal_gas_vector( + &block_context, + &account_tx, + &GasVectorComputationMode::NoL2Gas, + ) + .unwrap(); let estimated_min_l1_gas = estimated_min_gas_usage_vector.l1_gas; let estimated_min_fee = get_fee_by_gas_vector(block_info, estimated_min_gas_usage_vector, &account_tx.fee_type()); @@ -449,7 +458,7 @@ fn test_recursion_depth_exceeded( #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, block_context: BlockContext, max_fee: Fee, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, ) { let TestInitData { mut state, account_address, contract_address, mut nonce_manager } = create_test_init_data(&block_context.chain_info, cairo_version); @@ -502,11 +511,8 @@ fn test_recursion_depth_exceeded( felt!(exceeding_recursion_depth), ], ); - let invoke_args = crate::test_utils::invoke::InvokeTxArgs { - calldata, - nonce: nonce_manager.next(account_address), - ..invoke_args - }; + let invoke_args = + InvokeTxArgs { calldata, nonce: nonce_manager.next(account_address), ..invoke_args }; let tx_execution_info = run_invoke_tx(&mut state, &block_context, invoke_args); assert!(tx_execution_info.unwrap().revert_error.unwrap().contains("recursion depth exceeded")); @@ -693,7 +699,7 @@ fn recursive_function_calldata( #[case(TransactionVersion::THREE)] fn test_reverted_reach_steps_limit( max_fee: Fee, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, mut block_context: BlockContext, #[case] version: TransactionVersion, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, @@ -702,7 +708,7 @@ fn test_reverted_reach_steps_limit( create_test_init_data(&block_context.chain_info, cairo_version); // Limit the number of execution steps (so we quickly hit the limit). - block_context.versioned_constants.invoke_tx_max_n_steps = 5000; + block_context.versioned_constants.invoke_tx_max_n_steps = 6000; let recursion_base_args = invoke_tx_args! { max_fee, resource_bounds: max_resource_bounds, @@ -771,6 +777,8 @@ fn test_reverted_reach_steps_limit( // Make sure that the failed transaction gets charged for the extra steps taken, compared with // the smaller valid transaction. + + // If this fail, try to increase the `invoke_tx_max_n_steps` above. assert!(n_steps_fail > n_steps_1); assert!(actual_fee_fail > actual_fee_1); @@ -801,7 +809,7 @@ fn test_reverted_reach_steps_limit( /// asserts false. We test deltas between consecutive depths, and further depths. fn test_n_reverted_steps( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, ) { let TestInitData { mut state, account_address, contract_address, mut nonce_manager } = @@ -933,14 +941,18 @@ fn test_max_fee_to_max_steps_conversion( nonce: nonce_manager.next(account_address), }); let tx_context1 = Arc::new(block_context.to_tx_context(&account_tx1)); - let execution_context1 = EntryPointExecutionContext::new_invoke(tx_context1, true).unwrap(); + let execution_context1 = EntryPointExecutionContext::new_invoke(tx_context1, true); let max_steps_limit1 = execution_context1.vm_run_resources.get_n_steps(); let tx_execution_info1 = account_tx1.execute(&mut state, &block_context, true, true).unwrap(); let n_steps1 = tx_execution_info1.receipt.resources.vm_resources.n_steps; let gas_used_vector1 = tx_execution_info1 .receipt .resources - .to_gas_vector(&block_context.versioned_constants, block_context.block_info.use_kzg_da) + .to_gas_vector( + &block_context.versioned_constants, + block_context.block_info.use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ) .unwrap(); // Second invocation of `with_arg` gets twice the pre-calculated actual fee as max_fee. @@ -953,14 +965,18 @@ fn test_max_fee_to_max_steps_conversion( nonce: nonce_manager.next(account_address), }); let tx_context2 = Arc::new(block_context.to_tx_context(&account_tx2)); - let execution_context2 = EntryPointExecutionContext::new_invoke(tx_context2, true).unwrap(); + let execution_context2 = EntryPointExecutionContext::new_invoke(tx_context2, true); let max_steps_limit2 = execution_context2.vm_run_resources.get_n_steps(); let tx_execution_info2 = account_tx2.execute(&mut state, &block_context, true, true).unwrap(); let n_steps2 = tx_execution_info2.receipt.resources.vm_resources.n_steps; let gas_used_vector2 = tx_execution_info2 .receipt .resources - .to_gas_vector(&block_context.versioned_constants, block_context.block_info.use_kzg_da) + .to_gas_vector( + &block_context.versioned_constants, + block_context.block_info.use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ) .unwrap(); // Test that steps limit doubles as max_fee doubles, but actual consumed steps and fee remains. @@ -982,7 +998,7 @@ fn test_max_fee_to_max_steps_conversion( /// recorded and max_fee is charged. fn test_insufficient_max_fee_reverts( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, ) { let TestInitData { mut state, account_address, contract_address, mut nonce_manager } = @@ -1051,7 +1067,7 @@ fn test_insufficient_max_fee_reverts( #[rstest] fn test_deploy_account_constructor_storage_write( - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, block_context: BlockContext, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, ) { @@ -1095,7 +1111,7 @@ fn test_deploy_account_constructor_storage_write( fn test_count_actual_storage_changes( max_fee: Fee, block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[case] version: TransactionVersion, #[case] fee_type: FeeType, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, @@ -1276,7 +1292,7 @@ fn test_count_actual_storage_changes( #[case::tx_version_3(TransactionVersion::THREE)] fn test_concurrency_execute_fee_transfer( max_fee: Fee, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[case] version: TransactionVersion, ) { // TODO(Meshi, 01/06/2024): make the test so it will include changes in @@ -1376,7 +1392,7 @@ fn test_concurrency_execute_fee_transfer( #[case::tx_version_3(TransactionVersion::THREE)] fn test_concurrent_fee_transfer_when_sender_is_sequencer( max_fee: Fee, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[case] version: TransactionVersion, ) { let mut block_context = BlockContext::create_for_account_testing(); diff --git a/crates/blockifier/src/transaction/errors.rs b/crates/blockifier/src/transaction/errors.rs index 7707c4c93d..e410d4d338 100644 --- a/crates/blockifier/src/transaction/errors.rs +++ b/crates/blockifier/src/transaction/errors.rs @@ -1,7 +1,7 @@ use cairo_vm::types::errors::program_errors::ProgramError; use num_bigint::BigUint; use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, Nonce}; -use starknet_api::transaction::{Fee, TransactionVersion}; +use starknet_api::transaction::{Fee, Resource, TransactionVersion}; use starknet_api::StarknetApiError; use starknet_types_core::felt::FromStrError; use thiserror::Error; @@ -22,26 +22,31 @@ pub enum TransactionFeeError { #[error("Actual fee ({}) exceeded max fee ({}).", actual_fee.0, max_fee.0)] FeeTransferError { max_fee: Fee, actual_fee: Fee }, #[error("Actual fee ({}) exceeded paid fee on L1 ({}).", actual_fee.0, paid_fee.0)] - InsufficientL1Fee { paid_fee: Fee, actual_fee: Fee }, + InsufficientFee { paid_fee: Fee, actual_fee: Fee }, #[error( - "L1 gas bounds (max amount: {max_amount}, max price: {max_price}) exceed balance \ - ({balance})." + "Resource {resource} Gas bounds (max amount: {max_amount}, max price: {max_price}) exceed \ + balance ({balance})." )] - L1GasBoundsExceedBalance { max_amount: u64, max_price: u128, balance: BigUint }, + GasBoundsExceedBalance { + resource: Resource, + max_amount: u64, + max_price: u128, + balance: BigUint, + }, #[error("Max fee ({}) exceeds balance ({balance}).", max_fee.0,)] MaxFeeExceedsBalance { max_fee: Fee, balance: BigUint }, #[error("Max fee ({}) is too low. Minimum fee: {}.", max_fee.0, min_fee.0)] MaxFeeTooLow { min_fee: Fee, max_fee: Fee }, #[error( - "Max L1 gas price ({max_l1_gas_price}) is lower than the actual gas price: \ - {actual_l1_gas_price}." + "Resource {resource} max gas price ({max_gas_price}) is lower than the actual gas price: \ + {actual_gas_price}." )] - MaxL1GasPriceTooLow { max_l1_gas_price: u128, actual_l1_gas_price: u128 }, + MaxGasPriceTooLow { resource: Resource, max_gas_price: u128, actual_gas_price: u128 }, #[error( - "Max L1 gas amount ({max_l1_gas_amount}) is lower than the minimal gas amount: \ - {minimal_l1_gas_amount}." + "Max {resource} gas amount ({max_gas_amount}) is lower than the minimal gas amount: \ + {minimal_gas_amount}." )] - MaxL1GasAmountTooLow { max_l1_gas_amount: u64, minimal_l1_gas_amount: u64 }, + MaxGasAmountTooLow { resource: Resource, max_gas_amount: u64, minimal_gas_amount: u64 }, #[error("Missing L1 gas bounds in resource bounds.")] MissingL1GasBounds, #[error(transparent)] diff --git a/crates/blockifier/src/transaction/execution_flavors_test.rs b/crates/blockifier/src/transaction/execution_flavors_test.rs index 608feac892..db41415abe 100644 --- a/crates/blockifier/src/transaction/execution_flavors_test.rs +++ b/crates/blockifier/src/transaction/execution_flavors_test.rs @@ -2,19 +2,21 @@ use assert_matches::assert_matches; use pretty_assertions::assert_eq; use rstest::rstest; use starknet_api::core::ContractAddress; -use starknet_api::felt; use starknet_api::transaction::{ Calldata, - DeprecatedResourceBoundsMapping, Fee, + Resource, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; +use starknet_api::{felt, invoke_tx_args}; use starknet_types_core::felt::Felt; use crate::context::{BlockContext, ChainInfo}; use crate::execution::syscalls::SyscallSelector; use crate::fee::fee_utils::get_fee_by_gas_vector; +use crate::nonce; use crate::state::cached_state::CachedState; use crate::state::state_api::StateReader; use crate::test_utils::contracts::FeatureContract; @@ -38,7 +40,12 @@ use crate::transaction::errors::{ TransactionFeeError, TransactionPreValidationError, }; -use crate::transaction::objects::{FeeType, GasVector, TransactionExecutionInfo}; +use crate::transaction::objects::{ + FeeType, + GasVector, + GasVectorComputationMode, + TransactionExecutionInfo, +}; use crate::transaction::test_utils::{ account_invoke_tx, l1_resource_bounds, @@ -47,7 +54,6 @@ use crate::transaction::test_utils::{ }; use crate::transaction::transaction_types::TransactionType; use crate::transaction::transactions::ExecutableTransaction; -use crate::{invoke_tx_args, nonce}; const VALIDATE_GAS_OVERHEAD: u64 = 21; struct FlavorTestInitialState { @@ -129,7 +135,11 @@ fn check_gas_and_fee( tx_execution_info .receipt .resources - .to_gas_vector(&block_context.versioned_constants, block_context.block_info.use_kzg_da) + .to_gas_vector( + &block_context.versioned_constants, + block_context.block_info.use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ) .unwrap() .l1_gas, expected_actual_gas.into() @@ -255,9 +265,9 @@ fn test_simulate_validate_charge_fee_pre_validate( result.unwrap_err(), TransactionExecutionError::TransactionPreValidationError( TransactionPreValidationError::TransactionFeeError( - TransactionFeeError::MaxL1GasAmountTooLow { .. } + TransactionFeeError::MaxGasAmountTooLow { resource , .. } ) - ) + ) if resource == Resource::L1Gas ); } } @@ -299,9 +309,10 @@ fn test_simulate_validate_charge_fee_pre_validate( result.unwrap_err(), TransactionExecutionError::TransactionPreValidationError( TransactionPreValidationError::TransactionFeeError( - TransactionFeeError::L1GasBoundsExceedBalance { .. } + TransactionFeeError::GasBoundsExceedBalance {resource, .. } ) ) + if resource == Resource::L1Gas ); } } @@ -329,9 +340,10 @@ fn test_simulate_validate_charge_fee_pre_validate( result.unwrap_err(), TransactionExecutionError::TransactionPreValidationError( TransactionPreValidationError::TransactionFeeError( - TransactionFeeError::MaxL1GasPriceTooLow { .. } + TransactionFeeError::MaxGasPriceTooLow { resource, .. } ) ) + if resource == Resource::L1Gas ); } } @@ -349,7 +361,7 @@ fn test_simulate_validate_charge_fee_fail_validate( #[values(CairoVersion::Cairo0)] cairo_version: CairoVersion, #[case] version: TransactionVersion, #[case] fee_type: FeeType, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, ) { let block_context = BlockContext::create_for_account_testing(); let max_fee = Fee(MAX_FEE); @@ -411,7 +423,7 @@ fn test_simulate_validate_charge_fee_mid_execution( #[values(CairoVersion::Cairo0)] cairo_version: CairoVersion, #[case] version: TransactionVersion, #[case] fee_type: FeeType, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, ) { let block_context = BlockContext::create_for_account_testing(); let chain_info = &block_context.chain_info; @@ -474,10 +486,10 @@ fn test_simulate_validate_charge_fee_mid_execution( // Second scenario: limit resources via sender bounds. Should revert if and only if step limit // is derived from sender bounds (`charge_fee` mode). - let (gas_bound, fee_bound) = gas_and_fee(6001, validate, &fee_type); + let (gas_bound, fee_bound) = gas_and_fee(6047, validate, &fee_type); // If `charge_fee` is true, execution is limited by sender bounds, so less resources will be // used. Otherwise, execution is limited by block bounds, so more resources will be used. - let (limited_gas_used, limited_fee) = gas_and_fee(7653, validate, &fee_type); + let (limited_gas_used, limited_fee) = gas_and_fee(7699, validate, &fee_type); let (unlimited_gas_used, unlimited_fee) = gas_and_fee( u64_from_usize( get_syscall_resources(SyscallSelector::CallContract).n_steps @@ -651,7 +663,7 @@ fn test_simulate_validate_charge_fee_post_execution( u64_from_usize( get_syscall_resources(SyscallSelector::CallContract).n_steps + get_tx_resources(TransactionType::InvokeFunction).n_steps - + 4244, + + 4268, ), validate, &fee_type, @@ -685,6 +697,7 @@ fn test_simulate_validate_charge_fee_post_execution( .execute(&mut state, &block_context, charge_fee, validate) .unwrap(); assert_eq!(tx_execution_info.is_reverted(), charge_fee); + if charge_fee { assert!( tx_execution_info diff --git a/crates/blockifier/src/transaction/objects.rs b/crates/blockifier/src/transaction/objects.rs index 97bdc7083b..c6a4a93a4f 100644 --- a/crates/blockifier/src/transaction/objects.rs +++ b/crates/blockifier/src/transaction/objects.rs @@ -8,25 +8,26 @@ use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::transaction::{ AccountDeploymentData, - DeprecatedResourceBoundsMapping, + AllResourceBounds, Fee, PaymasterData, - Resource, ResourceBounds, Tip, TransactionHash, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; use strum_macros::EnumIter; use crate::abi::constants as abi_constants; use crate::blockifier::block::BlockInfo; +use crate::context::TransactionContext; use crate::execution::call_info::{CallInfo, ExecutionSummary, MessageL1CostInfo, OrderedEvent}; use crate::fee::actual_cost::TransactionReceipt; use crate::fee::eth_gas_constants; -use crate::fee::fee_utils::{calculate_l1_gas_by_vm_usage, get_fee_by_gas_vector}; +use crate::fee::fee_utils::{get_fee_by_gas_vector, get_vm_resources_cost}; use crate::fee::gas_usage::{ get_consumed_message_to_l2_emissions_cost, get_da_gas_cost, @@ -40,7 +41,7 @@ use crate::transaction::errors::{ TransactionFeeError, TransactionPreValidationError, }; -use crate::utils::{u128_from_usize, usize_from_u128}; +use crate::utils::{u128_div_ceil, u128_from_usize, usize_from_u128}; use crate::versioned_constants::VersionedConstants; #[cfg(test)] @@ -100,14 +101,14 @@ impl TransactionInfo { TransactionVersion(query_version) } - pub fn enforce_fee(&self) -> TransactionFeeResult { + pub fn enforce_fee(&self) -> bool { match self { TransactionInfo::Current(context) => { - let l1_bounds = context.l1_resource_bounds()?; + let l1_bounds = context.l1_resource_bounds(); let max_amount: u128 = l1_bounds.max_amount.into(); - Ok(max_amount * l1_bounds.max_price_per_unit > 0) + max_amount * l1_bounds.max_price_per_unit > 0 } - TransactionInfo::Deprecated(context) => Ok(context.max_fee != Fee(0)), + TransactionInfo::Deprecated(context) => context.max_fee != Fee(0), } } @@ -132,7 +133,7 @@ impl HasRelatedFeeType for TransactionInfo { #[derive(Clone, Debug, Eq, PartialEq)] pub struct CurrentTransactionInfo { pub common_fields: CommonAccountFields, - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, @@ -156,10 +157,12 @@ impl Default for CurrentTransactionInfo { impl CurrentTransactionInfo { /// Fetch the L1 resource bounds, if they exist. - pub fn l1_resource_bounds(&self) -> TransactionFeeResult { - match self.resource_bounds.0.get(&Resource::L1Gas).copied() { - Some(bounds) => Ok(bounds), - None => Err(TransactionFeeError::MissingL1GasBounds), + // TODO(Nimrod): Consider removing this function and add equivalent method to + // `ValidResourceBounds`. + pub fn l1_resource_bounds(&self) -> ResourceBounds { + match self.resource_bounds { + ValidResourceBounds::L1Gas(bounds) => bounds, + ValidResourceBounds::AllResources(AllResourceBounds { l1_gas, .. }) => l1_gas, } } } @@ -170,6 +173,7 @@ pub struct DeprecatedTransactionInfo { pub max_fee: Fee, } +#[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] #[derive( derive_more::Add, derive_more::Sum, Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, )] @@ -188,6 +192,10 @@ impl GasVector { Self { l1_data_gas, ..Default::default() } } + pub fn from_l2_gas(l2_gas: u128) -> Self { + Self { l2_gas, ..Default::default() } + } + /// Computes the cost (in fee token units) of the gas vector (saturating on overflow). pub fn saturated_cost(&self, gas_price: u128, blob_gas_price: u128) -> Fee { let l1_gas_cost = self.l1_gas.checked_mul(gas_price).unwrap_or_else(|| { @@ -216,6 +224,21 @@ impl GasVector { }); Fee(total) } + + /// Compute l1_gas estimation from gas_vector using the following formula: + /// One byte of data costs either 1 data gas (in blob mode) or 16 gas (in calldata + /// mode). For gas price GP and data gas price DGP, the discount for using blobs + /// would be DGP / (16 * GP). + /// X non-data-related gas consumption and Y bytes of data, in non-blob mode, would + /// cost (X + 16*Y) units of gas. Applying the discount ratio to the data-related + /// summand, we get total_gas = (X + Y * DGP / GP). + pub fn to_discounted_l1_gas(&self, tx_context: &TransactionContext) -> u128 { + let gas_prices = &tx_context.block_context.block_info.gas_prices; + let fee_type = tx_context.tx_info.fee_type(); + let gas_price = gas_prices.get_l1_gas_price_by_fee_type(&fee_type); + let data_gas_price = gas_prices.get_l1_data_gas_price_by_fee_type(&fee_type); + self.l1_gas + u128_div_ceil(self.l1_data_gas * u128::from(data_gas_price), gas_price) + } } #[derive(Clone, Debug, Default, Eq, PartialEq)] @@ -229,6 +252,7 @@ pub struct CommonAccountFields { } /// Contains the information gathered by the execution of a transaction. +#[cfg_attr(feature = "transaction_serde", derive(Serialize, serde::Deserialize))] #[derive(Debug, Default, PartialEq)] pub struct TransactionExecutionInfo { /// Transaction validation call info; [None] for `L1Handler`. @@ -287,7 +311,8 @@ impl ResourcesMapping { } } -/// Containes all the L2 resources consumed by a transaction +/// Contains all the L2 resources consumed by a transaction +#[cfg_attr(feature = "transaction_serde", derive(Serialize, serde::Deserialize))] #[derive(Clone, Debug, Default, PartialEq)] pub struct StarknetResources { pub calldata_length: usize, @@ -327,31 +352,55 @@ impl StarknetResources { } /// Returns the gas cost of the starknet resources, summing all components. + /// The L2 gas amount may be converted to L1 gas (depending on the gas vector computation mode). pub fn to_gas_vector( &self, versioned_constants: &VersionedConstants, use_kzg_da: bool, + mode: &GasVectorComputationMode, ) -> GasVector { - self.get_calldata_and_signature_cost(versioned_constants) - + self.get_code_cost(versioned_constants) + self.get_l2_archival_data_cost(versioned_constants, mode) + self.get_state_changes_cost(use_kzg_da) + self.get_messages_cost() - + self.get_events_cost(versioned_constants) } - // Returns the gas cost for transaction calldata and transaction signature. Each felt costs a - // fixed and configurable amount of gas. This cost represents the cost of storing the - // calldata and the signature on L2. - pub fn get_calldata_and_signature_cost( + /// Returns the cost of the transaction's archival data, for example, calldata, signature, code, + /// and events. + pub fn get_l2_archival_data_cost( &self, versioned_constants: &VersionedConstants, + mode: &GasVectorComputationMode, ) -> GasVector { + // Cost in L2 gas. + let l2_archival_data_costs = [ + self.get_calldata_and_signature_cost(versioned_constants), + self.get_code_cost(versioned_constants), + self.get_events_cost(versioned_constants), + ]; + match mode { + GasVectorComputationMode::All => { + GasVector::from_l2_gas(l2_archival_data_costs.iter().sum()) + } + GasVectorComputationMode::NoL2Gas => GasVector::from_l1_gas( + l2_archival_data_costs + .map(|cost| versioned_constants.convert_l2_to_l1_gas(cost)) + .iter() + .sum(), + ), + } + } + + /// Returns the cost for transaction calldata and transaction signature. Each felt costs a + /// fixed and configurable amount of gas. This cost represents the cost of storing the + /// calldata and the signature on L2. The result is given in L2 gas units. + pub fn get_calldata_and_signature_cost( + &self, + versioned_constants: &VersionedConstants, + ) -> u128 { // TODO(Avi, 20/2/2024): Calculate the number of bytes instead of the number of felts. let total_data_size = u128_from_usize(self.calldata_length + self.signature_length); - let l1_gas = (versioned_constants.l2_resource_gas_costs.gas_per_data_felt - * total_data_size) - .to_integer(); - GasVector::from_l1_gas(l1_gas) + (versioned_constants.archival_data_gas_costs.gas_per_data_felt * total_data_size) + .to_integer() } /// Returns an estimation of the gas usage for processing L1<>L2 messages on L1. Accounts for @@ -399,13 +448,11 @@ impl StarknetResources { (message_segment_length, gas_weight) } - /// Returns the gas cost of declared class codes. - pub fn get_code_cost(&self, versioned_constants: &VersionedConstants) -> GasVector { - GasVector::from_l1_gas( - (versioned_constants.l2_resource_gas_costs.gas_per_code_byte - * u128_from_usize(self.code_size)) - .to_integer(), - ) + /// Returns the cost of declared class codes in L2 gas units. + pub fn get_code_cost(&self, versioned_constants: &VersionedConstants) -> u128 { + (versioned_constants.archival_data_gas_costs.gas_per_code_byte + * u128_from_usize(self.code_size)) + .to_integer() } /// Returns the gas cost of the transaction's state changes. @@ -414,16 +461,13 @@ impl StarknetResources { get_da_gas_cost(&self.state_changes_for_fee, use_kzg_da) } - /// Returns the gas cost of the transaction's emmited events. - pub fn get_events_cost(&self, versioned_constants: &VersionedConstants) -> GasVector { - let l2_resource_gas_costs = &versioned_constants.l2_resource_gas_costs; + /// Returns the cost of the transaction's emmited events in L2 gas units. + pub fn get_events_cost(&self, versioned_constants: &VersionedConstants) -> u128 { + let archival_data_gas_costs = &versioned_constants.archival_data_gas_costs; let (event_key_factor, data_word_cost) = - (l2_resource_gas_costs.event_key_factor, l2_resource_gas_costs.gas_per_data_felt); - let l1_gas: u128 = (data_word_cost - * (event_key_factor * self.total_event_keys + self.total_event_data_size)) - .to_integer(); - - GasVector::from_l1_gas(l1_gas) + (archival_data_gas_costs.event_key_factor, archival_data_gas_costs.gas_per_data_felt); + (data_word_cost * (event_key_factor * self.total_event_keys + self.total_event_data_size)) + .to_integer() } pub fn get_onchain_data_segment_length(&self) -> usize { @@ -454,6 +498,7 @@ impl StarknetResources { } } +#[cfg_attr(feature = "transaction_serde", derive(Serialize, serde::Deserialize))] #[derive(Default, Clone, Debug, PartialEq)] pub struct TransactionResources { pub starknet_resources: StarknetResources, @@ -461,50 +506,30 @@ pub struct TransactionResources { pub n_reverted_steps: usize, } +#[derive(Debug, PartialEq)] +pub enum GasVectorComputationMode { + All, + NoL2Gas, +} + impl TransactionResources { - /// Computes and returns the total L1 gas consumption. - /// We add the l1_gas_usage (which may include, for example, the direct cost of L2-to-L1 - /// messages) to the gas consumed by Cairo VM resource. + /// Computes and returns the total gas consumption. The L2 gas amount may be converted + /// to L1 gas (depending on the gas vector computation mode). pub fn to_gas_vector( &self, versioned_constants: &VersionedConstants, use_kzg_da: bool, + computation_mode: &GasVectorComputationMode, ) -> TransactionFeeResult { - Ok(self.starknet_resources.to_gas_vector(versioned_constants, use_kzg_da) - + calculate_l1_gas_by_vm_usage( + Ok(self.starknet_resources.to_gas_vector(versioned_constants, use_kzg_da, computation_mode) + + get_vm_resources_cost( versioned_constants, &self.vm_resources, self.n_reverted_steps, + computation_mode, )?) } - pub fn to_resources_mapping( - &self, - versioned_constants: &VersionedConstants, - use_kzg_da: bool, - with_reverted_steps: bool, - ) -> ResourcesMapping { - let GasVector { l1_gas, l1_data_gas, .. } = - self.starknet_resources.to_gas_vector(versioned_constants, use_kzg_da); - let mut resources = self.vm_resources.to_resources_mapping(); - resources.0.extend(HashMap::from([ - ( - abi_constants::L1_GAS_USAGE.to_string(), - usize_from_u128(l1_gas) - .expect("This conversion should not fail as the value is a converted usize."), - ), - ( - abi_constants::BLOB_GAS_USAGE.to_string(), - usize_from_u128(l1_data_gas) - .expect("This conversion should not fail as the value is a converted usize."), - ), - ])); - let reverted_steps_to_add = if with_reverted_steps { self.n_reverted_steps } else { 0 }; - *resources.0.get_mut(abi_constants::N_STEPS_RESOURCE).unwrap_or(&mut 0) += - reverted_steps_to_add; - resources - } - pub fn total_charged_steps(&self) -> usize { self.n_reverted_steps + self.vm_resources.n_steps } diff --git a/crates/blockifier/src/transaction/post_execution_test.rs b/crates/blockifier/src/transaction/post_execution_test.rs index bb6dd8f43c..838c44d0d6 100644 --- a/crates/blockifier/src/transaction/post_execution_test.rs +++ b/crates/blockifier/src/transaction/post_execution_test.rs @@ -2,25 +2,24 @@ use assert_matches::assert_matches; use rstest::rstest; use starknet_api::core::{ContractAddress, PatriciaKey}; use starknet_api::state::StorageKey; -use starknet_api::transaction::{ - Calldata, - DeprecatedResourceBoundsMapping, - Fee, - TransactionVersion, -}; -use starknet_api::{felt, patricia_key}; +use starknet_api::transaction::{Calldata, Fee, TransactionVersion, ValidResourceBounds}; +use starknet_api::{felt, invoke_tx_args, patricia_key}; use starknet_types_core::felt::Felt; use crate::context::{BlockContext, ChainInfo}; use crate::fee::fee_checks::FeeCheckError; -use crate::invoke_tx_args; use crate::state::state_api::StateReader; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::{create_calldata, CairoVersion, BALANCE, MAX_L1_GAS_PRICE}; use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::errors::TransactionExecutionError; -use crate::transaction::objects::{FeeType, HasRelatedFeeType, TransactionInfoCreator}; +use crate::transaction::objects::{ + FeeType, + GasVectorComputationMode, + HasRelatedFeeType, + TransactionInfoCreator, +}; use crate::transaction::test_utils::{ account_invoke_tx, block_context, @@ -72,7 +71,7 @@ fn calldata_for_write_and_transfer( #[case(TransactionVersion::THREE, FeeType::Strk)] fn test_revert_on_overdraft( max_fee: Fee, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, block_context: BlockContext, #[case] version: TransactionVersion, #[case] fee_type: FeeType, @@ -217,7 +216,7 @@ fn test_revert_on_overdraft( #[case(TransactionVersion::THREE, "Insufficient max L1 gas", true)] fn test_revert_on_resource_overuse( max_fee: Fee, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, block_context: BlockContext, #[case] version: TransactionVersion, #[case] expected_error_prefix: &str, @@ -261,7 +260,11 @@ fn test_revert_on_resource_overuse( let actual_gas_usage: u64 = execution_info_measure .receipt .resources - .to_gas_vector(&block_context.versioned_constants, block_context.block_info.use_kzg_da) + .to_gas_vector( + &block_context.versioned_constants, + block_context.block_info.use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ) .unwrap() .l1_gas .try_into() diff --git a/crates/blockifier/src/transaction/test_utils.rs b/crates/blockifier/src/transaction/test_utils.rs index ed9c1dd1e8..4cdbd799db 100644 --- a/crates/blockifier/src/transaction/test_utils.rs +++ b/crates/blockifier/src/transaction/test_utils.rs @@ -1,20 +1,21 @@ use rstest::fixture; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; +use starknet_api::test_utils::deploy_account::DeployAccountTxArgs; +use starknet_api::test_utils::invoke::InvokeTxArgs; use starknet_api::transaction::{ Calldata, ContractAddressSalt, - DeprecatedResourceBoundsMapping, Fee, InvokeTransactionV0, InvokeTransactionV1, InvokeTransactionV3, - Resource, ResourceBounds, TransactionHash, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; -use starknet_api::{calldata, felt}; +use starknet_api::{calldata, declare_tx_args, deploy_account_tx_args, felt, invoke_tx_args}; use starknet_types_core::felt::Felt; use strum::IntoEnumIterator; @@ -25,13 +26,12 @@ use crate::state::cached_state::CachedState; use crate::state::state_api::State; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::declare::declare_tx; -use crate::test_utils::deploy_account::{deploy_account_tx, DeployAccountTxArgs}; +use crate::test_utils::deploy_account::deploy_account_tx; use crate::test_utils::dict_state_reader::DictStateReader; use crate::test_utils::initial_test_state::test_state; -use crate::test_utils::invoke::{invoke_tx, InvokeTxArgs}; +use crate::test_utils::invoke::invoke_tx; use crate::test_utils::{ create_calldata, - default_testing_resource_bounds, CairoVersion, NonceManager, BALANCE, @@ -44,7 +44,6 @@ use crate::transaction::constants; use crate::transaction::objects::{FeeType, TransactionExecutionInfo, TransactionExecutionResult}; use crate::transaction::transaction_types::TransactionType; use crate::transaction::transactions::{ExecutableTransaction, InvokeTransaction}; -use crate::{declare_tx_args, deploy_account_tx_args, invoke_tx_args}; // Corresponding constants to the ones in faulty_account. pub const VALID: u64 = 0; @@ -83,7 +82,7 @@ pub fn max_fee() -> Fee { } #[fixture] -pub fn max_resource_bounds() -> DeprecatedResourceBoundsMapping { +pub fn max_resource_bounds() -> ValidResourceBounds { l1_resource_bounds(MAX_L1_GAS_AMOUNT, MAX_L1_GAS_PRICE) } @@ -146,7 +145,7 @@ pub struct FaultyAccountTxCreatorArgs { pub tx_version: TransactionVersion, pub scenario: u64, pub max_fee: Fee, - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, // Should be None unless scenario is CALL_CONTRACT. pub additional_data: Option>, // Should be use with tx_type Declare or InvokeFunction. @@ -173,7 +172,7 @@ impl Default for FaultyAccountTxCreatorArgs { contract_address_salt: ContractAddressSalt::default(), validate_constructor: false, max_fee: Fee::default(), - resource_bounds: default_testing_resource_bounds(), + resource_bounds: ValidResourceBounds::create_for_testing(), declared_contract: None, } } @@ -298,12 +297,8 @@ pub fn run_invoke_tx( /// Creates a `ResourceBoundsMapping` with the given `max_amount` and `max_price` for L1 gas limits. /// No guarantees on the values of the other resources bounds. -pub fn l1_resource_bounds(max_amount: u64, max_price: u128) -> DeprecatedResourceBoundsMapping { - DeprecatedResourceBoundsMapping::try_from(vec![ - (Resource::L1Gas, ResourceBounds { max_amount, max_price_per_unit: max_price }), - (Resource::L2Gas, ResourceBounds { max_amount: 0, max_price_per_unit: 0 }), - ]) - .unwrap() +pub fn l1_resource_bounds(max_amount: u64, max_price: u128) -> ValidResourceBounds { + ValidResourceBounds::L1Gas(ResourceBounds { max_amount, max_price_per_unit: max_price }) } pub fn calculate_class_info_for_testing(contract_class: ContractClass) -> ClassInfo { diff --git a/crates/blockifier/src/transaction/transaction_execution.rs b/crates/blockifier/src/transaction/transaction_execution.rs index f2fb174a84..1c62f51752 100644 --- a/crates/blockifier/src/transaction/transaction_execution.rs +++ b/crates/blockifier/src/transaction/transaction_execution.rs @@ -118,7 +118,7 @@ impl ExecutableTransaction for L1HandlerTransaction { let tx_context = Arc::new(block_context.to_tx_context(self)); let mut execution_resources = ExecutionResources::default(); - let mut context = EntryPointExecutionContext::new_invoke(tx_context.clone(), true)?; + let mut context = EntryPointExecutionContext::new_invoke(tx_context.clone(), true); let mut remaining_gas = block_context.versioned_constants.tx_initial_gas(); let execute_call_info = self.run_execute(state, &mut execution_resources, &mut context, &mut remaining_gas)?; @@ -141,7 +141,7 @@ impl ExecutableTransaction for L1HandlerTransaction { // For now, assert only that any amount of fee was paid. // The error message still indicates the required fee. if paid_fee == Fee(0) { - return Err(TransactionFeeError::InsufficientL1Fee { paid_fee, actual_fee })?; + return Err(TransactionFeeError::InsufficientFee { paid_fee, actual_fee })?; } Ok(TransactionExecutionInfo { diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index 1115b280ca..094f79d140 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -13,16 +13,26 @@ use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::state::StorageKey; use starknet_api::transaction::{ Calldata, - DeprecatedResourceBoundsMapping, EventContent, EventData, EventKey, Fee, L2ToL1Payload, + Resource, TransactionSignature, TransactionVersion, + ValidResourceBounds, +}; +use starknet_api::{ + calldata, + class_hash, + contract_address, + declare_tx_args, + deploy_account_tx_args, + felt, + invoke_tx_args, + patricia_key, }; -use starknet_api::{calldata, class_hash, contract_address, felt, patricia_key}; use starknet_types_core::felt::Felt; use strum::IntoEnumIterator; @@ -66,7 +76,6 @@ use crate::test_utils::prices::Prices; use crate::test_utils::{ create_calldata, create_trivial_calldata, - default_testing_resource_bounds, get_syscall_resources, get_tx_resources, test_erc20_sequencer_balance_key, @@ -74,7 +83,6 @@ use crate::test_utils::{ NonceManager, SaltManager, BALANCE, - CHAIN_ID_NAME, CURRENT_BLOCK_NUMBER, CURRENT_BLOCK_NUMBER_FOR_VALIDATE, CURRENT_BLOCK_TIMESTAMP, @@ -94,6 +102,7 @@ use crate::transaction::errors::{ use crate::transaction::objects::{ FeeType, GasVector, + GasVectorComputationMode, HasRelatedFeeType, StarknetResources, TransactionExecutionInfo, @@ -124,9 +133,6 @@ use crate::versioned_constants::VersionedConstants; use crate::{ check_transaction_execution_error_for_custom_hint, check_transaction_execution_error_for_invalid_scenario, - declare_tx_args, - deploy_account_tx_args, - invoke_tx_args, nonce, retdata, }; @@ -383,7 +389,7 @@ fn add_kzg_da_resources_to_resources_mapping( }, CairoVersion::Cairo1)] fn test_invoke_tx( - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[case] expected_arguments: ExpectedResultTestInvokeTx, #[case] account_cairo_version: CairoVersion, #[values(false, true)] use_kzg_da: bool, @@ -507,7 +513,11 @@ fn test_invoke_tx( ); let total_gas = expected_actual_resources - .to_gas_vector(&block_context.versioned_constants, block_context.block_info.use_kzg_da) + .to_gas_vector( + &block_context.versioned_constants, + block_context.block_info.use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ) .unwrap(); let expected_execution_info = TransactionExecutionInfo { @@ -576,7 +586,7 @@ fn verify_storage_after_invoke_advanced_operations( #[rstest] fn test_invoke_tx_advanced_operations( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, ) { let block_context = &block_context; @@ -803,22 +813,55 @@ fn assert_failure_if_resource_bounds_exceed_balance( ); } TransactionInfo::Current(context) => { - let l1_bounds = context.l1_resource_bounds().unwrap(); + let l1_bounds = context.l1_resource_bounds(); assert_matches!( invalid_tx.execute(state, block_context, true, true).unwrap_err(), TransactionExecutionError::TransactionPreValidationError( TransactionPreValidationError::TransactionFeeError( - TransactionFeeError::L1GasBoundsExceedBalance{ max_amount, max_price, .. })) - if max_amount == l1_bounds.max_amount && max_price == l1_bounds.max_price_per_unit + TransactionFeeError::GasBoundsExceedBalance{resource, max_amount, max_price, .. })) + if max_amount == l1_bounds.max_amount && max_price == l1_bounds.max_price_per_unit && resource == Resource::L1Gas ); } }; } +#[rstest] +fn test_estimate_minimal_gas_vector( + mut block_context: BlockContext, + #[values(true, false)] use_kzg_da: bool, + #[values(GasVectorComputationMode::NoL2Gas, GasVectorComputationMode::All)] + gas_vector_computation_mode: GasVectorComputationMode, + #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] account_cairo_version: CairoVersion, +) { + block_context.block_info.use_kzg_da = use_kzg_da; + let block_context = &block_context; + let account_contract = FeatureContract::AccountWithoutValidations(account_cairo_version); + let test_contract = FeatureContract::TestContract(CairoVersion::Cairo0); + + let valid_invoke_tx_args = invoke_tx_args! { + sender_address: account_contract.get_instance_address(0), + calldata: create_trivial_calldata(test_contract.get_instance_address(0)), + max_fee: Fee(MAX_FEE) + }; + + // The minimal gas estimate does not depend on tx version. + let tx = &account_invoke_tx(valid_invoke_tx_args); + let minimal_gas_vector = + estimate_minimal_gas_vector(block_context, tx, &gas_vector_computation_mode).unwrap(); + let minimal_l1_gas = minimal_gas_vector.l1_gas; + let minimal_l2_gas = minimal_gas_vector.l2_gas; + let minimal_l1_data_gas = minimal_gas_vector.l1_data_gas; + if gas_vector_computation_mode == GasVectorComputationMode::NoL2Gas || !use_kzg_da { + assert!(minimal_l1_gas > 0); + } + assert_eq!(minimal_l2_gas > 0, gas_vector_computation_mode == GasVectorComputationMode::All); + assert_eq!(minimal_l1_data_gas > 0, use_kzg_da); +} + #[rstest] fn test_max_fee_exceeds_balance( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] account_cairo_version: CairoVersion, ) { let block_context = &block_context; @@ -903,7 +946,10 @@ fn test_insufficient_resource_bounds( // The minimal gas estimate does not depend on tx version. let tx = &account_invoke_tx(valid_invoke_tx_args.clone()); - let minimal_l1_gas = estimate_minimal_gas_vector(block_context, tx).unwrap().l1_gas; + let minimal_l1_gas = + estimate_minimal_gas_vector(block_context, tx, &GasVectorComputationMode::NoL2Gas) + .unwrap() + .l1_gas; // Test V1 transaction. @@ -923,7 +969,7 @@ fn test_insufficient_resource_bounds( execution_error, TransactionExecutionError::TransactionPreValidationError( TransactionPreValidationError::TransactionFeeError( - TransactionFeeError::MaxFeeTooLow { min_fee, max_fee })) + TransactionFeeError::MaxFeeTooLow { min_fee, max_fee })) if max_fee == invalid_max_fee && min_fee == minimal_fee ); @@ -946,10 +992,12 @@ fn test_insufficient_resource_bounds( execution_error, TransactionExecutionError::TransactionPreValidationError( TransactionPreValidationError::TransactionFeeError( - TransactionFeeError::MaxL1GasAmountTooLow{ - max_l1_gas_amount, minimal_l1_gas_amount })) - if max_l1_gas_amount == insufficient_max_l1_gas_amount && - minimal_l1_gas_amount == minimal_l1_gas_as_u64 + TransactionFeeError::MaxGasAmountTooLow{ + resource, + max_gas_amount, + minimal_gas_amount})) + if max_gas_amount == insufficient_max_l1_gas_amount && + minimal_gas_amount == minimal_l1_gas_as_u64 && resource == Resource::L1Gas ); // Max L1 gas price too low. @@ -965,9 +1013,13 @@ fn test_insufficient_resource_bounds( execution_error, TransactionExecutionError::TransactionPreValidationError( TransactionPreValidationError::TransactionFeeError( - TransactionFeeError::MaxL1GasPriceTooLow{ max_l1_gas_price, actual_l1_gas_price })) - if max_l1_gas_price == insufficient_max_l1_gas_price && - actual_l1_gas_price == actual_strk_l1_gas_price.into() + TransactionFeeError::MaxGasPriceTooLow{ + resource, + max_gas_price, + actual_gas_price})) + if max_gas_price == insufficient_max_l1_gas_price && + actual_gas_price == actual_strk_l1_gas_price.into() && + resource == Resource::L1Gas ); } @@ -975,7 +1027,7 @@ fn test_insufficient_resource_bounds( #[rstest] fn test_actual_fee_gt_resource_bounds( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] account_cairo_version: CairoVersion, ) { let block_context = &block_context; @@ -992,7 +1044,10 @@ fn test_actual_fee_gt_resource_bounds( resource_bounds: max_resource_bounds }; let tx = &account_invoke_tx(invoke_tx_args.clone()); - let minimal_l1_gas = estimate_minimal_gas_vector(block_context, tx).unwrap().l1_gas; + let minimal_l1_gas = + estimate_minimal_gas_vector(block_context, tx, &GasVectorComputationMode::NoL2Gas) + .unwrap() + .l1_gas; let minimal_resource_bounds = l1_resource_bounds( u64::try_from(minimal_l1_gas).unwrap(), u128::from( @@ -1019,7 +1074,7 @@ fn test_actual_fee_gt_resource_bounds( #[rstest] fn test_invalid_nonce( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] account_cairo_version: CairoVersion, ) { let account_contract = FeatureContract::AccountWithoutValidations(account_cairo_version); @@ -1139,7 +1194,7 @@ fn declare_expected_state_changes_count(version: TransactionVersion) -> StateCha #[case(TransactionVersion::TWO, CairoVersion::Cairo1)] #[case(TransactionVersion::THREE, CairoVersion::Cairo1)] fn test_declare_tx( - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] account_cairo_version: CairoVersion, #[case] tx_version: TransactionVersion, #[case] empty_contract_version: CairoVersion, @@ -1228,8 +1283,9 @@ fn test_declare_tx( use_kzg_da, ); - let expected_total_gas = - expected_actual_resources.to_gas_vector(versioned_constants, use_kzg_da).unwrap(); + let expected_total_gas = expected_actual_resources + .to_gas_vector(versioned_constants, use_kzg_da, &GasVectorComputationMode::NoL2Gas) + .unwrap(); let expected_execution_info = TransactionExecutionInfo { validate_call_info: expected_validate_call_info, @@ -1292,7 +1348,7 @@ fn test_declare_tx( fn test_deploy_account_tx( #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, #[values(false, true)] use_kzg_da: bool, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, ) { let block_context = &BlockContext::create_for_account_testing_with_kzg(use_kzg_da); let versioned_constants = &block_context.versioned_constants; @@ -1397,7 +1453,11 @@ fn test_deploy_account_tx( ); let expected_total_gas = actual_resources - .to_gas_vector(&block_context.versioned_constants, block_context.block_info.use_kzg_da) + .to_gas_vector( + &block_context.versioned_constants, + block_context.block_info.use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ) .unwrap(); let expected_execution_info = TransactionExecutionInfo { @@ -1459,7 +1519,7 @@ fn test_deploy_account_tx( #[rstest] fn test_fail_deploy_account_undeclared_class_hash( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, ) { let block_context = &block_context; let chain_info = &block_context.chain_info; @@ -1557,7 +1617,7 @@ fn test_validate_accounts_tx( * the address of * faulty_account. */ contract_address_salt: salt_manager.next_salt(), - resource_bounds: default_testing_resource_bounds(), + resource_bounds: ValidResourceBounds::create_for_testing(), ..default_args }); let error = account_tx.execute(state, block_context, true, true).unwrap_err(); @@ -1573,7 +1633,7 @@ fn test_validate_accounts_tx( scenario: GET_BLOCK_HASH, contract_address_salt: salt_manager.next_salt(), additional_data: None, - resource_bounds: default_testing_resource_bounds(), + resource_bounds: ValidResourceBounds::create_for_testing(), ..default_args }); let error = account_tx.execute(state, block_context, true, true).unwrap_err(); @@ -1588,7 +1648,7 @@ fn test_validate_accounts_tx( let account_tx = create_account_tx_for_validate_test_nonce_0(FaultyAccountTxCreatorArgs { scenario: GET_SEQUENCER_ADDRESS, contract_address_salt: salt_manager.next_salt(), - resource_bounds: default_testing_resource_bounds(), + resource_bounds: ValidResourceBounds::create_for_testing(), ..default_args }); let error = account_tx.execute(state, block_context, true, true).unwrap_err(); @@ -1611,7 +1671,7 @@ fn test_validate_accounts_tx( contract_address_salt: salt_manager.next_salt(), additional_data: None, declared_contract: Some(FeatureContract::TestContract(declared_contract_cairo_version)), - resource_bounds: default_testing_resource_bounds(), + resource_bounds: ValidResourceBounds::create_for_testing(), ..default_args }, ); @@ -1628,7 +1688,7 @@ fn test_validate_accounts_tx( declared_contract: Some(FeatureContract::AccountWithLongValidate( declared_contract_cairo_version, )), - resource_bounds: default_testing_resource_bounds(), + resource_bounds: ValidResourceBounds::create_for_testing(), ..default_args }, ); @@ -1648,7 +1708,7 @@ fn test_validate_accounts_tx( declared_contract: Some(FeatureContract::AccountWithoutValidations( declared_contract_cairo_version, )), - resource_bounds: default_testing_resource_bounds(), + resource_bounds: ValidResourceBounds::create_for_testing(), ..default_args }, ); @@ -1664,7 +1724,7 @@ fn test_validate_accounts_tx( contract_address_salt: salt_manager.next_salt(), additional_data: Some(vec![Felt::from(CURRENT_BLOCK_TIMESTAMP_FOR_VALIDATE)]), declared_contract: Some(FeatureContract::Empty(declared_contract_cairo_version)), - resource_bounds: default_testing_resource_bounds(), + resource_bounds: ValidResourceBounds::create_for_testing(), ..default_args }, ); @@ -1686,7 +1746,7 @@ fn test_validate_accounts_tx( Felt::from(0_u64), // Sequencer address for validate. ]), declared_contract: Some(FeatureContract::Empty(declared_contract_cairo_version)), - resource_bounds: default_testing_resource_bounds(), + resource_bounds: ValidResourceBounds::create_for_testing(), ..default_args }, ); @@ -1698,7 +1758,7 @@ fn test_validate_accounts_tx( #[rstest] fn test_valid_flag( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] account_cairo_version: CairoVersion, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] test_contract_cairo_version: CairoVersion, ) { @@ -1726,7 +1786,7 @@ fn test_valid_flag( #[rstest] fn test_only_query_flag( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[values(true, false)] only_query: bool, ) { let account_balance = BALANCE; @@ -1746,13 +1806,13 @@ fn test_only_query_flag( let sender_address = account.get_instance_address(0); let test_contract_address = test_contract.get_instance_address(0); let expected_tx_info = vec![ - version, // Transaction version. - *sender_address.0.key(), // Account address. - Felt::ZERO, // Max fee. - Felt::ZERO, // Signature. - Felt::ZERO, // Transaction hash. - felt!(&*ChainId::Other(CHAIN_ID_NAME.to_string()).as_hex()), // Chain ID. - Felt::ZERO, // Nonce. + version, // Transaction version. + *sender_address.0.key(), // Account address. + Felt::ZERO, // Max fee. + Felt::ZERO, // Signature. + Felt::ZERO, // Transaction hash. + felt!(&*ChainId::create_for_testing().as_hex()), // Chain ID. + Felt::ZERO, // Nonce. ]; let expected_resource_bounds = vec![ @@ -1857,7 +1917,7 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) { ..Default::default() }, resources: ExecutionResources { - n_steps: 154, + n_steps: 158, n_memory_holes: 0, builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 6)]), }, @@ -1893,7 +1953,7 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) { + 6, ), ]), - n_steps: get_tx_resources(TransactionType::L1Handler).n_steps + 167, + n_steps: get_tx_resources(TransactionType::L1Handler).n_steps + 171, n_memory_holes: 0, }; @@ -1912,15 +1972,19 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) { }; assert_eq!( expected_gas, - actual_execution_info - .receipt - .resources - .starknet_resources - .to_gas_vector(versioned_constants, use_kzg_da) + actual_execution_info.receipt.resources.starknet_resources.to_gas_vector( + versioned_constants, + use_kzg_da, + &GasVectorComputationMode::NoL2Gas + ) ); let total_gas = expected_tx_resources - .to_gas_vector(versioned_constants, block_context.block_info.use_kzg_da) + .to_gas_vector( + versioned_constants, + block_context.block_info.use_kzg_da, + &GasVectorComputationMode::NoL2Gas, + ) .unwrap(); // Build the expected execution info. @@ -1960,7 +2024,7 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) { assert_matches!( error, TransactionExecutionError::TransactionFeeError( - TransactionFeeError::InsufficientL1Fee { paid_fee, actual_fee, }) + TransactionFeeError::InsufficientFee {paid_fee, actual_fee, }) if paid_fee == Fee(0) && actual_fee == expected_actual_fee ); } @@ -1968,7 +2032,7 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) { #[rstest] fn test_execute_tx_with_invalid_transaction_version( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, ) { let cairo_version = CairoVersion::Cairo0; let account = FeatureContract::AccountWithoutValidations(cairo_version); @@ -2041,7 +2105,7 @@ fn max_event_data() -> usize { }))] fn test_emit_event_exceeds_limit( block_context: BlockContext, - max_resource_bounds: DeprecatedResourceBoundsMapping, + max_resource_bounds: ValidResourceBounds, #[case] event_keys: Vec, #[case] event_data: Vec, #[case] n_emitted_events: usize, diff --git a/crates/blockifier/src/versioned_constants.rs b/crates/blockifier/src/versioned_constants.rs index 12e0a26397..784d7cb690 100644 --- a/crates/blockifier/src/versioned_constants.rs +++ b/crates/blockifier/src/versioned_constants.rs @@ -7,6 +7,7 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use indexmap::{IndexMap, IndexSet}; use num_rational::Ratio; +use num_traits::Inv; use paste::paste; use serde::de::Error as DeserializationError; use serde::{Deserialize, Deserializer}; @@ -69,6 +70,7 @@ define_versioned_constants! { (V0_13_1, "../resources/versioned_constants_13_1.json"), (V0_13_1_1, "../resources/versioned_constants_13_1_1.json"), (V0_13_2, "../resources/versioned_constants_13_2.json"), + (V0_13_2_1, "../resources/versioned_constants_13_2_1.json"), (Latest, "../resources/versioned_constants.json"), } @@ -85,7 +87,7 @@ pub struct VersionedConstants { pub tx_event_limits: EventLimits, pub invoke_tx_max_n_steps: u32, #[serde(default)] - pub l2_resource_gas_costs: L2ResourceGasCosts, + pub archival_data_gas_costs: ArchivalDataGasCosts, pub max_recursion_depth: usize, pub validate_max_n_steps: u32, // BACKWARD COMPATIBILITY: If true, the segment_arena builtin instance counter will be @@ -124,12 +126,22 @@ impl VersionedConstants { Self::get(StarknetVersion::Latest) } - /// Converts from l1 gas cost to l2 gas cost with **upward rounding** - pub fn l1_to_l2_gas_price_conversion(&self, l1_gas_price: u128) -> u128 { - let l1_to_l2_gas_price_ratio: Ratio = - Ratio::new(1, u128::from(self.os_constants.gas_costs.step_gas_cost)) - * self.vm_resource_fee_cost()["n_steps"]; - *(l1_to_l2_gas_price_ratio * l1_gas_price).ceil().numer() + /// Converts from L1 gas to L2 gas with **upward rounding**. + pub fn convert_l1_to_l2_gas(&self, l1_gas: u128) -> u128 { + let l1_to_l2_gas_price_ratio = self.l1_to_l2_gas_price_ratio().inv(); + *(l1_to_l2_gas_price_ratio * l1_gas).ceil().numer() + } + + /// Converts from L2 gas to L1 gas **rounding towards zero**. + pub fn convert_l2_to_l1_gas(&self, l2_gas: u128) -> u128 { + let l2_to_l1_gas_price_ratio = self.l1_to_l2_gas_price_ratio(); + (l2_to_l1_gas_price_ratio * l2_gas).to_integer() + } + + /// Returns the following ratio: L2_gas_price/L1_gas_price. + pub fn l1_to_l2_gas_price_ratio(&self) -> ResourceCost { + Ratio::new(1, u128::from(self.os_constants.gas_costs.step_gas_cost)) + * self.vm_resource_fee_cost()["n_steps"] } /// Returns the initial gas of any transaction to run with. @@ -185,8 +197,9 @@ impl VersionedConstants { #[cfg(any(feature = "testing", test))] pub fn create_for_account_testing() -> Self { + let step_cost = ResourceCost::from_integer(1); let vm_resource_fee_cost = Arc::new(HashMap::from([ - (crate::abi::constants::N_STEPS_RESOURCE.to_string(), ResourceCost::from_integer(1)), + (crate::abi::constants::N_STEPS_RESOURCE.to_string(), step_cost), (BuiltinName::pedersen.to_str_with_suffix().to_string(), ResourceCost::from_integer(1)), ( BuiltinName::range_check.to_str_with_suffix().to_string(), @@ -205,24 +218,13 @@ impl VersionedConstants { (BuiltinName::mul_mod.to_str_with_suffix().to_string(), ResourceCost::from_integer(1)), ])); - Self { vm_resource_fee_cost, ..Self::create_for_testing() } - } - - // A more complicated instance to increase test coverage. - #[cfg(any(feature = "testing", test))] - pub fn create_float_for_testing() -> Self { - let vm_resource_fee_cost = Arc::new(HashMap::from([ - (crate::abi::constants::N_STEPS_RESOURCE.to_string(), ResourceCost::new(25, 10000)), - (BuiltinName::pedersen.to_str_with_suffix().to_string(), ResourceCost::new(8, 100)), - (BuiltinName::range_check.to_str_with_suffix().to_string(), ResourceCost::new(4, 100)), - (BuiltinName::ecdsa.to_str_with_suffix().to_string(), ResourceCost::new(512, 100)), - (BuiltinName::bitwise.to_str_with_suffix().to_string(), ResourceCost::new(16, 100)), - (BuiltinName::poseidon.to_str_with_suffix().to_string(), ResourceCost::new(8, 100)), - (BuiltinName::output.to_str_with_suffix().to_string(), ResourceCost::from_integer(0)), - (BuiltinName::ec_op.to_str_with_suffix().to_string(), ResourceCost::new(256, 100)), - ])); - - Self { vm_resource_fee_cost, ..Self::create_for_testing() } + // Maintain the ratio between L1 gas price and L2 gas price. + let latest = Self::create_for_testing(); + let latest_step_cost = latest.vm_resource_fee_cost["n_steps"]; + let mut archival_data_gas_costs = latest.archival_data_gas_costs; + archival_data_gas_costs.gas_per_code_byte *= latest_step_cost / step_cost; + archival_data_gas_costs.gas_per_data_felt *= latest_step_cost / step_cost; + Self { vm_resource_fee_cost, archival_data_gas_costs, ..latest } } pub fn latest_constants_with_overrides( @@ -259,7 +261,7 @@ impl TryFrom<&Path> for VersionedConstants { } #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] -pub struct L2ResourceGasCosts { +pub struct ArchivalDataGasCosts { // TODO(barak, 18/03/2024): Once we start charging per byte change to milligas_per_data_byte, // divide the value by 32 in the JSON file. pub gas_per_data_felt: ResourceCost, @@ -455,10 +457,17 @@ impl<'de> Deserialize<'de> for OsResources { #[derive(Debug, Default, Deserialize)] pub struct GasCosts { pub step_gas_cost: u64, + pub memory_hole_gas_cost: u64, // Range check has a hard-coded cost higher than its proof percentage to avoid the overhead of // retrieving its price from the table. pub range_check_gas_cost: u64, - pub memory_hole_gas_cost: u64, + // Priced builtins. + pub pedersen_gas_cost: u64, + pub bitwise_builtin_gas_cost: u64, + pub ecop_gas_cost: u64, + pub poseidon_gas_cost: u64, + pub add_mod_gas_cost: u64, + pub mul_mod_gas_cost: u64, // An estimation of the initial gas for a transaction to run with. This solution is // temporary and this value will be deduced from the transaction's fields. pub initial_gas_cost: u64, @@ -512,7 +521,7 @@ impl OsConstants { // not used by the blockifier but included for transparency. These constanst will be ignored // during the creation of the struct containing the gas costs. - const ADDITIONAL_FIELDS: [&'static str; 25] = [ + const ADDITIONAL_FIELDS: [&'static str; 27] = [ "block_hash_contract_address", "constructor_entry_point_selector", "default_entry_point_selector", @@ -529,6 +538,8 @@ impl OsConstants { "l1_handler_version", "l2_gas", "l2_gas_index", + "l1_data_gas", + "l1_data_gas_index", "nop_entry_point_offset", "sierra_array_len_bound", "stored_block_hash_buffer", diff --git a/crates/blockifier/src/versioned_constants_test.rs b/crates/blockifier/src/versioned_constants_test.rs index 7a6f9f545d..290138a025 100644 --- a/crates/blockifier/src/versioned_constants_test.rs +++ b/crates/blockifier/src/versioned_constants_test.rs @@ -124,7 +124,7 @@ fn test_default_values() { assert_eq!(versioned_constants.get_validate_timestamp_rounding(), 1); assert_eq!(versioned_constants.tx_event_limits, EventLimits::max()); - assert_eq!(versioned_constants.l2_resource_gas_costs, L2ResourceGasCosts::default()); + assert_eq!(versioned_constants.archival_data_gas_costs, ArchivalDataGasCosts::default()); // Calldata factor was initialized as 0, and did not affect the expected result, even if // calldata length is nonzero. diff --git a/crates/blockifier/tests/erc20_tests.rs b/crates/blockifier/tests/erc20_tests.rs index 2131a09d51..837e2ca714 100644 --- a/crates/blockifier/tests/erc20_tests.rs +++ b/crates/blockifier/tests/erc20_tests.rs @@ -1,5 +1,6 @@ // run with: // cargo test --test erc20_tests --features testing +use blockifier::execution::native::test_utils::*; use blockifier::execution::native::utils::contract_address_to_native_felt; use blockifier::test_utils::*; use starknet_types_core::felt::Felt; diff --git a/crates/blockifier/tests/feature_contracts_compatibility_test.rs b/crates/blockifier/tests/feature_contracts_compatibility_test.rs index cac102c77d..3273213e7f 100644 --- a/crates/blockifier/tests/feature_contracts_compatibility_test.rs +++ b/crates/blockifier/tests/feature_contracts_compatibility_test.rs @@ -7,6 +7,7 @@ use rstest::rstest; const CAIRO0_FEATURE_CONTRACTS_DIR: &str = "feature_contracts/cairo0"; const CAIRO1_FEATURE_CONTRACTS_DIR: &str = "feature_contracts/cairo1"; +const CAIRO_NATIVE_FEATURE_CONTRACTS_DIR: &str = "feature_contracts/cairo_native"; const COMPILED_CONTRACTS_SUBDIR: &str = "compiled"; const FIX_COMMAND: &str = "FIX_FEATURE_TEST=1 cargo test -p blockifier --test \ feature_contracts_compatibility_test --features testing -- \ @@ -63,7 +64,8 @@ fn verify_and_get_files(cairo_version: CairoVersion) -> Vec<(String, String, Str let mut paths = vec![]; let directory = match cairo_version { CairoVersion::Cairo0 => CAIRO0_FEATURE_CONTRACTS_DIR, - CairoVersion::Cairo1 | CairoVersion::Native => CAIRO1_FEATURE_CONTRACTS_DIR, + CairoVersion::Cairo1 => CAIRO1_FEATURE_CONTRACTS_DIR, + CairoVersion::Native => CAIRO_NATIVE_FEATURE_CONTRACTS_DIR, }; let compiled_extension = match cairo_version { CairoVersion::Cairo0 => "_compiled.json", @@ -108,12 +110,14 @@ fn verify_feature_contracts_match_enum() { let mut compiled_paths_from_enum: Vec = FeatureContract::all_feature_contracts() .map(|contract| contract.get_compiled_path()) .collect(); + let mut compiled_paths_on_filesystem: Vec = verify_and_get_files(CairoVersion::Cairo0) .into_iter() .chain(verify_and_get_files(CairoVersion::Cairo1)) .chain(verify_and_get_files(CairoVersion::Native)) .map(|(_, _, compiled_path)| compiled_path) .collect(); + compiled_paths_from_enum.sort(); compiled_paths_on_filesystem.sort(); assert_eq!(compiled_paths_from_enum, compiled_paths_on_filesystem); @@ -122,7 +126,8 @@ fn verify_feature_contracts_match_enum() { #[rstest] #[ignore] fn verify_feature_contracts( - #[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion, + #[values(CairoVersion::Cairo0, CairoVersion::Cairo1, CairoVersion::Native)] + cairo_version: CairoVersion, ) { let fix_features = std::env::var("FIX_FEATURE_TEST").is_ok(); verify_feature_contracts_compatibility(fix_features, cairo_version) diff --git a/crates/blockifier/tests/test_native_contract.rs b/crates/blockifier/tests/test_native_contract.rs new file mode 100644 index 0000000000..b42839b77c --- /dev/null +++ b/crates/blockifier/tests/test_native_contract.rs @@ -0,0 +1,20 @@ +// Test command: cargo test --test test_native_contract --features testing +use blockifier::execution::contract_class::NativeContractClassV1; +use blockifier::test_utils::contracts::FeatureContract; + +#[test] +fn test_partial_eq() { + let contract_a = NativeContractClassV1::from_file( + &FeatureContract::TestContractEntryPointA.get_compiled_path(), + ); + let contract_b = NativeContractClassV1::from_file( + &FeatureContract::TestContractEntryPointB.get_compiled_path(), + ); + assert_eq!(contract_b, contract_b); + assert_eq!(contract_a, contract_a); + assert_ne!( + contract_a, contract_b, + "Contracts should be considered different because they have different entry points. \ + Specifically, the selectors are different due to having different names." + ); +} diff --git a/crates/committer_cli/Cargo.toml b/crates/committer_cli/Cargo.toml index 19ae805830..e29ad842b2 100644 --- a/crates/committer_cli/Cargo.toml +++ b/crates/committer_cli/Cargo.toml @@ -33,7 +33,7 @@ starknet_patricia = { workspace = true, features = ["testing"] } strum.workspace = true strum_macros.workspace = true thiserror.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } tracing-subscriber.workspace = true tracing.workspace = true diff --git a/crates/gateway/Cargo.toml b/crates/gateway/Cargo.toml index 0d2f4cb710..9fb5f88743 100644 --- a/crates/gateway/Cargo.toml +++ b/crates/gateway/Cargo.toml @@ -38,7 +38,7 @@ validator.workspace = true assert_matches.workspace = true cairo-lang-sierra-to-casm.workspace = true mockall.workspace = true -mockito = "1.4.0" +mockito.workspace = true num-bigint.workspace = true pretty_assertions.workspace = true rstest.workspace = true diff --git a/crates/gateway/build.rs b/crates/gateway/build.rs new file mode 100644 index 0000000000..2c3d009e87 --- /dev/null +++ b/crates/gateway/build.rs @@ -0,0 +1,3 @@ +// Sets up the environment variable OUT_DIR, which holds the cairo compiler binary. +// The binary is dowloaded to OUT_DIR by the starknet_sierra_compile crate. +fn main() {} diff --git a/crates/gateway/src/compilation.rs b/crates/gateway/src/compilation.rs index aab1affc40..a4f3a3d7e6 100644 --- a/crates/gateway/src/compilation.rs +++ b/crates/gateway/src/compilation.rs @@ -3,9 +3,9 @@ use std::sync::Arc; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use cairo_lang_starknet_classes::contract_class::ContractClass as CairoLangContractClass; use starknet_api::contract_class::ClassInfo; -use starknet_api::core::CompiledClassHash; use starknet_api::rpc_transaction::RpcDeclareTransaction; use starknet_sierra_compile::cairo_lang_compiler::CairoLangSierraToCasmCompiler; +use starknet_sierra_compile::command_line_compiler::CommandLineCompiler; use starknet_sierra_compile::config::SierraToCasmCompilationConfig; use starknet_sierra_compile::utils::into_contract_class_for_compilation; use starknet_sierra_compile::SierraToCasmCompiler; @@ -24,6 +24,11 @@ pub struct GatewayCompiler { } impl GatewayCompiler { + pub fn new_command_line_compiler(config: SierraToCasmCompilationConfig) -> Self { + Self { sierra_to_casm_compiler: Arc::new(CommandLineCompiler::new(config)) } + } + + // TODO(Arni): Cosider deleting `CairoLangSierraToCasmCompiler`. pub fn new_cairo_lang_compiler(config: SierraToCasmCompilationConfig) -> Self { Self { sierra_to_casm_compiler: Arc::new(CairoLangSierraToCasmCompiler { config }) } } @@ -31,7 +36,7 @@ impl GatewayCompiler { /// Formats the contract class for compilation, compiles it, and returns the compiled contract /// class wrapped in a [`ClassInfo`]. /// Assumes the contract class is of a Sierra program which is compiled to Casm. - pub fn process_declare_tx( + pub(crate) fn process_declare_tx( &self, declare_tx: &RpcDeclareTransaction, ) -> GatewayResult { @@ -41,8 +46,6 @@ impl GatewayCompiler { let casm_contract_class = self.compile(cairo_lang_contract_class)?; - validate_compiled_class_hash(&casm_contract_class, &tx.compiled_class_hash)?; - Ok(ClassInfo { casm_contract_class, sierra_program_length: rpc_contract_class.sierra_program.len(), @@ -67,20 +70,3 @@ impl GatewayCompiler { } } } - -/// Validates that the compiled class hash of the compiled contract class matches the supplied -/// compiled class hash. -fn validate_compiled_class_hash( - casm_contract_class: &CasmContractClass, - supplied_compiled_class_hash: &CompiledClassHash, -) -> GatewayResult<()> { - let compiled_class_hash = CompiledClassHash(casm_contract_class.compiled_class_hash()); - if compiled_class_hash != *supplied_compiled_class_hash { - debug!( - "Compiled class hash mismatch. Supplied: {:?}, Hash result: {:?}", - supplied_compiled_class_hash, compiled_class_hash - ); - return Err(GatewaySpecError::CompiledClassHashMismatch); - } - Ok(()) -} diff --git a/crates/gateway/src/compilation_test.rs b/crates/gateway/src/compilation_test.rs index 8c41913c12..4ef67bdaf5 100644 --- a/crates/gateway/src/compilation_test.rs +++ b/crates/gateway/src/compilation_test.rs @@ -19,7 +19,7 @@ use crate::errors::GatewaySpecError; #[fixture] fn gateway_compiler() -> GatewayCompiler { - GatewayCompiler::new_cairo_lang_compiler(SierraToCasmCompilationConfig::default()) + GatewayCompiler::new_command_line_compiler(SierraToCasmCompilationConfig::default()) } #[fixture] @@ -30,42 +30,20 @@ fn declare_tx_v3() -> RpcDeclareTransactionV3 { ) } -// TODO(Arni): Redesign this test once the compiler is passed with dependancy injection. -#[traced_test] -#[rstest] -fn test_compile_contract_class_compiled_class_hash_mismatch( - gateway_compiler: GatewayCompiler, - mut declare_tx_v3: RpcDeclareTransactionV3, -) { - let expected_hash = declare_tx_v3.compiled_class_hash; - let wrong_supplied_hash = CompiledClassHash::default(); - declare_tx_v3.compiled_class_hash = wrong_supplied_hash; - let declare_tx = RpcDeclareTransaction::V3(declare_tx_v3); - - let err = gateway_compiler.process_declare_tx(&declare_tx).unwrap_err(); - assert_eq!(err, GatewaySpecError::CompiledClassHashMismatch); - assert!(logs_contain( - format!( - "Compiled class hash mismatch. Supplied: {:?}, Hash result: {:?}", - wrong_supplied_hash, expected_hash - ) - .as_str() - )); -} - // TODO(Arni): Redesign this test once the compiler is passed with dependancy injection. #[traced_test] #[rstest] fn test_compile_contract_class_bytecode_size_validation(declare_tx_v3: RpcDeclareTransactionV3) { let gateway_compiler = - GatewayCompiler::new_cairo_lang_compiler(SierraToCasmCompilationConfig { + GatewayCompiler::new_command_line_compiler(SierraToCasmCompilationConfig { max_bytecode_size: 1, }); let result = gateway_compiler.process_declare_tx(&RpcDeclareTransaction::V3(declare_tx_v3)); assert_matches!(result.unwrap_err(), GatewaySpecError::CompilationFailed); - let expected_compilation_error = - CompilationUtilError::CompilationError("Code size limit exceeded.".to_owned()); + let expected_compilation_error = CompilationUtilError::CompilationError( + "Error: Compilation failed.\n\nCaused by:\n Code size limit exceeded.\n".to_owned(), + ); assert!(logs_contain(format!("Compilation failed: {:?}", expected_compilation_error).as_str())); } @@ -84,7 +62,7 @@ fn test_compile_contract_class_bad_sierra( assert_eq!(err, GatewaySpecError::CompilationFailed); let expected_compilation_error = - CompilationUtilError::CompilationError("Invalid Sierra program.".to_owned()); + CompilationUtilError::CompilationError("Error: Invalid Sierra program.\n".to_owned()); assert!(logs_contain(format!("Compilation failed: {:?}", expected_compilation_error).as_str())); } diff --git a/crates/gateway/src/errors.rs b/crates/gateway/src/errors.rs index 0b875ad946..ad4cbb7773 100644 --- a/crates/gateway/src/errors.rs +++ b/crates/gateway/src/errors.rs @@ -33,6 +33,8 @@ pub type GatewayResult = Result; impl IntoResponse for GatewaySpecError { fn into_response(self) -> Response { let as_rpc = self.into_rpc(); + // TODO(Arni): Fix the status code. The status code should be a HTTP status code - not a + // Json RPC error code. status code. let status = StatusCode::from_u16(u16::try_from(as_rpc.code).expect("Expecting a valid u16")) .expect("Expecting a valid error code"); @@ -50,25 +52,11 @@ impl IntoResponse for GatewaySpecError { #[derive(Debug, Error)] #[cfg_attr(test, derive(PartialEq))] pub enum StatelessTransactionValidatorError { - #[error("Expected a positive amount of {resource:?}. Got {resource_bounds:?}.")] - ZeroResourceBounds { resource: Resource, resource_bounds: ResourceBounds }, #[error( "Calldata length exceeded maximum: length {calldata_length} (allowed length: {max_calldata_length})." )] CalldataTooLong { calldata_length: usize, max_calldata_length: usize }, - #[error( - "Signature length exceeded maximum: length {signature_length} - (allowed length: {max_signature_length})." - )] - SignatureTooLong { signature_length: usize, max_signature_length: usize }, - #[error(transparent)] - InvalidSierraVersion(#[from] VersionIdError), - #[error( - "Sierra versions older than {min_version} or newer than {max_version} are not supported. \ - The Sierra version of the declared contract is {version}." - )] - UnsupportedSierraVersion { version: VersionId, min_version: VersionId, max_version: VersionId }, #[error( "Cannot declare contract class with size of {contract_class_object_size}; max allowed \ size: {max_contract_class_object_size}." @@ -79,30 +67,36 @@ pub enum StatelessTransactionValidatorError { }, #[error("Entry points must be unique and sorted.")] EntryPointsNotUniquelySorted, + #[error(transparent)] + InvalidSierraVersion(#[from] VersionIdError), + #[error( + "Signature length exceeded maximum: length {signature_length} + (allowed length: {max_signature_length})." + )] + SignatureTooLong { signature_length: usize, max_signature_length: usize }, + #[error( + "Sierra versions older than {min_version} or newer than {max_version} are not supported. \ + The Sierra version of the declared contract is {version}." + )] + UnsupportedSierraVersion { version: VersionId, min_version: VersionId, max_version: VersionId }, + #[error("Expected a positive amount of {resource:?}. Got {resource_bounds:?}.")] + ZeroResourceBounds { resource: Resource, resource_bounds: ResourceBounds }, } impl From for GatewaySpecError { fn from(e: StatelessTransactionValidatorError) -> Self { match e { - StatelessTransactionValidatorError::ZeroResourceBounds { .. } => { - GatewaySpecError::ValidationFailure { data: e.to_string() } - } - StatelessTransactionValidatorError::CalldataTooLong { .. } => { - GatewaySpecError::ValidationFailure { data: e.to_string() } - } - StatelessTransactionValidatorError::SignatureTooLong { .. } => { - GatewaySpecError::ValidationFailure { data: e.to_string() } - } - StatelessTransactionValidatorError::InvalidSierraVersion(..) => { - GatewaySpecError::ValidationFailure { data: e.to_string() } + StatelessTransactionValidatorError::ContractClassObjectSizeTooLarge { .. } => { + GatewaySpecError::ContractClassSizeIsTooLarge } StatelessTransactionValidatorError::UnsupportedSierraVersion { .. } => { GatewaySpecError::UnsupportedContractClassVersion } - StatelessTransactionValidatorError::ContractClassObjectSizeTooLarge { .. } => { - GatewaySpecError::ContractClassSizeIsTooLarge - } - StatelessTransactionValidatorError::EntryPointsNotUniquelySorted => { + StatelessTransactionValidatorError::CalldataTooLong { .. } + | StatelessTransactionValidatorError::EntryPointsNotUniquelySorted + | StatelessTransactionValidatorError::InvalidSierraVersion(..) + | StatelessTransactionValidatorError::SignatureTooLong { .. } + | StatelessTransactionValidatorError::ZeroResourceBounds { .. } => { GatewaySpecError::ValidationFailure { data: e.to_string() } } } @@ -126,14 +120,14 @@ pub enum RPCStateReaderError { BlockNotFound(Value), #[error("Class hash not found for request {0}")] ClassHashNotFound(Value), - #[error("Failed to parse gas price {:?}", 0)] - GasPriceParsingFailure(GasPrice), #[error("Contract address not found for request {0}")] ContractAddressNotFound(Value), - #[error(transparent)] - ReqwestError(#[from] reqwest::Error), + #[error("Failed to parse gas price {:?}", 0)] + GasPriceParsingFailure(GasPrice), #[error("RPC error: {0}")] RPCError(StatusCode), + #[error(transparent)] + ReqwestError(#[from] reqwest::Error), #[error("Unexpected error code: {0}")] UnexpectedErrorCode(u16), } @@ -166,34 +160,34 @@ pub fn serde_err_to_state_err(err: SerdeError) -> StateError { #[derive(Debug, Clone, Eq, PartialEq, Assoc, Error)] #[func(pub fn into_rpc(self) -> JsonRpcError)] pub enum GatewaySpecError { - #[assoc(into_rpc = CLASS_HASH_NOT_FOUND)] - ClassHashNotFound, #[assoc(into_rpc = CLASS_ALREADY_DECLARED)] ClassAlreadyDeclared, - #[assoc(into_rpc = INVALID_TRANSACTION_NONCE)] - InvalidTransactionNonce, - #[assoc(into_rpc = INSUFFICIENT_MAX_FEE)] - InsufficientMaxFee, - #[assoc(into_rpc = INSUFFICIENT_ACCOUNT_BALANCE)] - InsufficientAccountBalance, - #[assoc(into_rpc = validation_failure(_data))] - ValidationFailure { data: String }, + #[assoc(into_rpc = CLASS_HASH_NOT_FOUND)] + ClassHashNotFound, + #[assoc(into_rpc = COMPILED_CLASS_HASH_MISMATCH)] + CompiledClassHashMismatch, #[assoc(into_rpc = COMPILATION_FAILED)] CompilationFailed, #[assoc(into_rpc = CONTRACT_CLASS_SIZE_IS_TOO_LARGE)] ContractClassSizeIsTooLarge, - #[assoc(into_rpc = NON_ACCOUNT)] - NonAccount, #[assoc(into_rpc = DUPLICATE_TX)] DuplicateTx, - #[assoc(into_rpc = COMPILED_CLASS_HASH_MISMATCH)] - CompiledClassHashMismatch, - #[assoc(into_rpc = UNSUPPORTED_TX_VERSION)] - UnsupportedTxVersion, - #[assoc(into_rpc = UNSUPPORTED_CONTRACT_CLASS_VERSION)] - UnsupportedContractClassVersion, + #[assoc(into_rpc = INSUFFICIENT_ACCOUNT_BALANCE)] + InsufficientAccountBalance, + #[assoc(into_rpc = INSUFFICIENT_MAX_FEE)] + InsufficientMaxFee, + #[assoc(into_rpc = INVALID_TRANSACTION_NONCE)] + InvalidTransactionNonce, + #[assoc(into_rpc = NON_ACCOUNT)] + NonAccount, #[assoc(into_rpc = unexpected_error(_data))] UnexpectedError { data: String }, + #[assoc(into_rpc = UNSUPPORTED_CONTRACT_CLASS_VERSION)] + UnsupportedContractClassVersion, + #[assoc(into_rpc = UNSUPPORTED_TX_VERSION)] + UnsupportedTxVersion, + #[assoc(into_rpc = validation_failure(_data))] + ValidationFailure { data: String }, } impl Display for GatewaySpecError { diff --git a/crates/gateway/src/gateway.rs b/crates/gateway/src/gateway.rs index 7a8ca45093..8c5677a4a2 100644 --- a/crates/gateway/src/gateway.rs +++ b/crates/gateway/src/gateway.rs @@ -6,7 +6,6 @@ use async_trait::async_trait; use axum::extract::State; use axum::routing::{get, post}; use axum::{Json, Router}; -use blockifier::execution::contract_class::ClassInfo; use starknet_api::executable_transaction::Transaction; use starknet_api::rpc_transaction::RpcTransaction; use starknet_api::transaction::TransactionHash; @@ -23,6 +22,7 @@ use crate::rpc_state_reader::RpcStateReaderFactory; use crate::state_reader::StateReaderFactory; use crate::stateful_transaction_validator::StatefulTransactionValidator; use crate::stateless_transaction_validator::StatelessTransactionValidator; +use crate::utils::compile_contract_and_build_executable_tx; #[cfg(test)] #[path = "gateway_test.rs"] @@ -130,25 +130,44 @@ fn process_tx( // Perform stateless validations. stateless_tx_validator.validate(&tx)?; - // Compile Sierra to Casm. - let optional_class_info = match &tx { - RpcTransaction::Declare(declare_tx) => Some( - ClassInfo::try_from(gateway_compiler.process_declare_tx(declare_tx)?).map_err(|e| { + // TODO(Arni): remove copy_of_rpc_tx and use executable_tx directly as the mempool input. + let copy_of_rpc_tx = tx.clone(); + let executable_tx = compile_contract_and_build_executable_tx( + tx, + &gateway_compiler, + &stateful_tx_validator.config.chain_info.chain_id, + )?; + + // Perfom post compilation validations. + if let Transaction::Declare(executable_declare_tx) = &executable_tx { + if !executable_declare_tx.validate_compiled_class_hash() { + return Err(GatewaySpecError::CompiledClassHashMismatch); + } + } + + let optional_class_info = match executable_tx { + starknet_api::executable_transaction::Transaction::Declare(tx) => { + Some(tx.class_info.try_into().map_err(|e| { error!("Failed to convert Starknet API ClassInfo to Blockifier ClassInfo: {:?}", e); GatewaySpecError::UnexpectedError { data: "Internal server error.".to_owned() } - })?, - ), + })?) + } _ => None, }; let validator = stateful_tx_validator.instantiate_validator(state_reader_factory)?; // TODO(Yael 31/7/24): refactor after IntrnalTransaction is ready, delete validate_info and // compute all the info outside of run_validate. - let validate_info = stateful_tx_validator.run_validate(&tx, optional_class_info, validator)?; + let validate_info = + stateful_tx_validator.run_validate(©_of_rpc_tx, optional_class_info, validator)?; // TODO(Arni): Add the Sierra and the Casm to the mempool input. Ok(MempoolInput { - tx: Transaction::new_from_rpc_tx(tx, validate_info.tx_hash, validate_info.sender_address), + tx: Transaction::new_from_rpc_tx( + copy_of_rpc_tx, + validate_info.tx_hash, + validate_info.sender_address, + ), account: Account { sender_address: validate_info.sender_address, state: AccountState { nonce: validate_info.account_nonce }, @@ -163,7 +182,7 @@ pub fn create_gateway( mempool_client: SharedMempoolClient, ) -> Gateway { let state_reader_factory = Arc::new(RpcStateReaderFactory { config: rpc_state_reader_config }); - let gateway_compiler = GatewayCompiler::new_cairo_lang_compiler(compiler_config); + let gateway_compiler = GatewayCompiler::new_command_line_compiler(compiler_config); Gateway::new(config, state_reader_factory, gateway_compiler, mempool_client) } diff --git a/crates/gateway/src/gateway_test.rs b/crates/gateway/src/gateway_test.rs index 0015858609..24022a0b53 100644 --- a/crates/gateway/src/gateway_test.rs +++ b/crates/gateway/src/gateway_test.rs @@ -1,22 +1,24 @@ use std::sync::Arc; +use assert_matches::assert_matches; use axum::body::{Bytes, HttpBody}; use axum::extract::State; use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; use blockifier::context::ChainInfo; use blockifier::test_utils::CairoVersion; -use mempool_test_utils::starknet_api_test_utils::{create_executable_tx, invoke_tx}; +use mempool_test_utils::starknet_api_test_utils::{create_executable_tx, declare_tx, invoke_tx}; use mockall::predicate::eq; -use starknet_api::core::ContractAddress; -use starknet_api::rpc_transaction::RpcTransaction; -use starknet_api::transaction::TransactionHash; +use starknet_api::core::{CompiledClassHash, ContractAddress}; +use starknet_api::rpc_transaction::{RpcDeclareTransaction, RpcTransaction}; +use starknet_api::transaction::{TransactionHash, ValidResourceBounds}; use starknet_mempool_types::communication::MockMempoolClient; use starknet_mempool_types::mempool_types::{Account, AccountState, MempoolInput}; use starknet_sierra_compile::config::SierraToCasmCompilationConfig; use crate::compilation::GatewayCompiler; use crate::config::{StatefulTransactionValidatorConfig, StatelessTransactionValidatorConfig}; +use crate::errors::GatewaySpecError; use crate::gateway::{add_tx, AppState, SharedMempoolClient}; use crate::state_reader_test_utils::{local_test_state_reader_factory, TestStateReaderFactory}; use crate::stateful_transaction_validator::StatefulTransactionValidator; @@ -34,7 +36,7 @@ pub fn app_state( stateful_tx_validator: Arc::new(StatefulTransactionValidator { config: StatefulTransactionValidatorConfig::create_for_testing(), }), - gateway_compiler: GatewayCompiler::new_cairo_lang_compiler( + gateway_compiler: GatewayCompiler::new_command_line_compiler( SierraToCasmCompilationConfig::default(), ), state_reader_factory: Arc::new(state_reader_factory), @@ -72,7 +74,7 @@ async fn test_add_tx() { tx_hash, *tx.tip(), *tx.nonce(), - tx.resource_bounds().clone().into(), + ValidResourceBounds::AllResources(tx.resource_bounds().clone()), ), account: Account { sender_address, state: AccountState { nonce: *tx.nonce() } }, })) @@ -93,6 +95,25 @@ async fn to_bytes(res: Response) -> Bytes { res.into_body().collect().await.unwrap().to_bytes() } +// Gateway spec errors tests. +// TODO(Arni): Add tests for all the error cases. Check the response (use `into_response` on the +// result of `add_tx`). + +#[tokio::test] +async fn test_compiled_class_hash_mismatch() { + let mut declare_tx = + assert_matches!(declare_tx(), RpcTransaction::Declare(RpcDeclareTransaction::V3(tx)) => tx); + declare_tx.compiled_class_hash = CompiledClassHash::default(); + let tx = RpcTransaction::Declare(RpcDeclareTransaction::V3(declare_tx)); + + let mock_mempool_client = MockMempoolClient::new(); + let state_reader_factory = local_test_state_reader_factory(CairoVersion::Cairo1, false); + let app_state = app_state(Arc::new(mock_mempool_client), state_reader_factory); + + let err = add_tx(State(app_state), tx.into()).await.unwrap_err(); + assert_matches!(err, GatewaySpecError::CompiledClassHashMismatch); +} + fn calculate_hash(rpc_tx: &RpcTransaction) -> TransactionHash { let optional_class_info = match &rpc_tx { RpcTransaction::Declare(_declare_tx) => { diff --git a/crates/gateway/src/stateful_transaction_validator_test.rs b/crates/gateway/src/stateful_transaction_validator_test.rs index afefb0ae9c..58421ebf68 100644 --- a/crates/gateway/src/stateful_transaction_validator_test.rs +++ b/crates/gateway/src/stateful_transaction_validator_test.rs @@ -3,14 +3,13 @@ use blockifier::blockifier::stateful_validator::{ StatefulValidatorResult as BlockifierStatefulValidatorResult, }; use blockifier::context::BlockContext; -use blockifier::execution::contract_class::ClassInfo; use blockifier::test_utils::CairoVersion; use blockifier::transaction::errors::{TransactionFeeError, TransactionPreValidationError}; use mempool_test_utils::invoke_tx_args; use mempool_test_utils::starknet_api_test_utils::{ deploy_account_tx, - external_invoke_tx, invoke_tx, + rpc_invoke_tx, TEST_SENDER_ADDRESS, VALID_L1_GAS_MAX_AMOUNT, VALID_L1_GAS_MAX_PRICE_PER_UNIT, @@ -21,13 +20,11 @@ use pretty_assertions::assert_eq; use rstest::{fixture, rstest}; use starknet_api::core::{ContractAddress, Nonce, PatriciaKey}; use starknet_api::rpc_transaction::RpcTransaction; -use starknet_api::transaction::TransactionHash; +use starknet_api::transaction::{Resource, TransactionHash}; use starknet_api::{contract_address, felt, patricia_key}; -use starknet_sierra_compile::config::SierraToCasmCompilationConfig; use starknet_types_core::felt::Felt; use super::ValidateInfo; -use crate::compilation::GatewayCompiler; use crate::config::StatefulTransactionValidatorConfig; use crate::errors::GatewaySpecError; use crate::state_reader::{MockStateReaderFactory, StateReaderFactory}; @@ -40,7 +37,8 @@ use crate::stateful_transaction_validator::{ pub const STATEFUL_VALIDATOR_FEE_ERROR: BlockifierStatefulValidatorError = BlockifierStatefulValidatorError::TransactionPreValidationError( TransactionPreValidationError::TransactionFeeError( - TransactionFeeError::L1GasBoundsExceedBalance { + TransactionFeeError::GasBoundsExceedBalance { + resource: Resource::L1DataGas, max_amount: VALID_L1_GAS_MAX_AMOUNT, max_price: VALID_L1_GAS_MAX_PRICE_PER_UNIT, balance: BigUint::ZERO, @@ -65,6 +63,7 @@ fn stateful_validator(block_context: BlockContext) -> StatefulTransactionValidat } } +// TODO(Arni): consider testing declare and deploy account. #[rstest] #[case::valid_tx( invoke_tx(CairoVersion::Cairo1), @@ -82,18 +81,6 @@ fn test_stateful_tx_validator( #[case] expected_result: BlockifierStatefulValidatorResult, stateful_validator: StatefulTransactionValidator, ) { - let optional_class_info = match &rpc_tx { - RpcTransaction::Declare(declare_tx) => Some( - ClassInfo::try_from( - GatewayCompiler::new_cairo_lang_compiler(SierraToCasmCompilationConfig::default()) - .process_declare_tx(declare_tx) - .unwrap(), - ) - .unwrap(), - ), - _ => None, - }; - let expected_result_as_stateful_transaction_result = expected_result.as_ref().map(|validate_info| *validate_info).map_err(|blockifier_error| { GatewaySpecError::ValidationFailure { data: blockifier_error.to_string() } @@ -103,7 +90,7 @@ fn test_stateful_tx_validator( mock_validator.expect_validate().return_once(|_, _| expected_result.map(|_| ())); mock_validator.expect_get_nonce().returning(|_| Ok(Nonce(Felt::ZERO))); - let result = stateful_validator.run_validate(&rpc_tx, optional_class_info, mock_validator); + let result = stateful_validator.run_validate(&rpc_tx, None, mock_validator); assert_eq!(result, expected_result_as_stateful_transaction_result); } @@ -143,18 +130,18 @@ fn test_instantiate_validator() { #[rstest] #[case::should_skip_validation( - external_invoke_tx(invoke_tx_args!{nonce: Nonce(Felt::ONE)}), + rpc_invoke_tx(invoke_tx_args!{nonce: Nonce(Felt::ONE)}), Nonce::default(), true )] #[case::should_not_skip_validation_nonce_over_max_nonce_for_skip( - external_invoke_tx(invoke_tx_args!{nonce: Nonce(Felt::TWO)}), + rpc_invoke_tx(invoke_tx_args!{nonce: Nonce(Felt::TWO)}), Nonce::default(), false )] #[case::should_not_skip_validation_non_invoke(deploy_account_tx(), Nonce::default(), false)] #[case::should_not_skip_validation_account_nonce_1( - external_invoke_tx(invoke_tx_args!{sender_address: ContractAddress::from(TEST_SENDER_ADDRESS), nonce: Nonce(Felt::ONE)}), + rpc_invoke_tx(invoke_tx_args!{sender_address: ContractAddress::from(TEST_SENDER_ADDRESS), nonce: Nonce(Felt::ONE)}), Nonce(Felt::ONE), false )] diff --git a/crates/gateway/src/stateless_transaction_validator.rs b/crates/gateway/src/stateless_transaction_validator.rs index b663bf5852..0a60bf2e06 100644 --- a/crates/gateway/src/stateless_transaction_validator.rs +++ b/crates/gateway/src/stateless_transaction_validator.rs @@ -1,12 +1,11 @@ use starknet_api::rpc_transaction::{ - ResourceBoundsMapping, RpcDeclareTransaction, RpcDeployAccountTransaction, RpcInvokeTransaction, RpcTransaction, }; use starknet_api::state::EntryPoint; -use starknet_api::transaction::Resource; +use starknet_api::transaction::{AllResourceBounds, Resource}; use starknet_types_core::felt::Felt; use tracing::{instrument, Level}; @@ -176,14 +175,10 @@ impl StatelessTransactionValidator { } fn validate_resource_is_non_zero( - resource_bounds_mapping: &ResourceBoundsMapping, + all_resource_bounds: &AllResourceBounds, resource: Resource, ) -> StatelessTransactionValidatorResult<()> { - let resource_bounds = match resource { - Resource::L1Gas => resource_bounds_mapping.l1_gas, - Resource::L2Gas => resource_bounds_mapping.l2_gas, - Resource::L1DataGas => todo!(), - }; + let resource_bounds = all_resource_bounds.get_bound(resource); if resource_bounds.max_amount == 0 || resource_bounds.max_price_per_unit == 0 { return Err(StatelessTransactionValidatorError::ZeroResourceBounds { resource, diff --git a/crates/gateway/src/stateless_transaction_validator_test.rs b/crates/gateway/src/stateless_transaction_validator_test.rs index 880706615e..9d6475b285 100644 --- a/crates/gateway/src/stateless_transaction_validator_test.rs +++ b/crates/gateway/src/stateless_transaction_validator_test.rs @@ -5,7 +5,7 @@ use assert_matches::assert_matches; use mempool_test_utils::declare_tx_args; use mempool_test_utils::starknet_api_test_utils::{ create_resource_bounds_mapping, - external_declare_tx, + rpc_declare_tx, rpc_tx_for_testing, zero_resource_bounds_mapping, TransactionType, @@ -13,9 +13,15 @@ use mempool_test_utils::starknet_api_test_utils::{ }; use rstest::rstest; use starknet_api::core::EntryPointSelector; -use starknet_api::rpc_transaction::{ContractClass, EntryPointByType, ResourceBoundsMapping}; +use starknet_api::rpc_transaction::{ContractClass, EntryPointByType}; use starknet_api::state::EntryPoint; -use starknet_api::transaction::{Calldata, Resource, ResourceBounds, TransactionSignature}; +use starknet_api::transaction::{ + AllResourceBounds, + Calldata, + Resource, + ResourceBounds, + TransactionSignature, +}; use starknet_api::{calldata, felt}; use starknet_types_core::felt::Felt; @@ -67,7 +73,11 @@ fn default_validator_config_for_testing() -> &'static StatelessTransactionValida validate_non_zero_l2_gas_fee: false, ..default_validator_config_for_testing().clone() }, - create_resource_bounds_mapping(NON_EMPTY_RESOURCE_BOUNDS, ResourceBounds::default()), + create_resource_bounds_mapping( + NON_EMPTY_RESOURCE_BOUNDS, + ResourceBounds::default(), + ResourceBounds::default(), + ), calldata![], TransactionSignature::default() )] @@ -77,7 +87,11 @@ fn default_validator_config_for_testing() -> &'static StatelessTransactionValida validate_non_zero_l2_gas_fee: true, ..default_validator_config_for_testing().clone() }, - create_resource_bounds_mapping(ResourceBounds::default(), NON_EMPTY_RESOURCE_BOUNDS), + create_resource_bounds_mapping( + ResourceBounds::default(), + NON_EMPTY_RESOURCE_BOUNDS, + ResourceBounds::default(), + ), calldata![], TransactionSignature::default() )] @@ -87,7 +101,11 @@ fn default_validator_config_for_testing() -> &'static StatelessTransactionValida validate_non_zero_l2_gas_fee: true, ..default_validator_config_for_testing().clone() }, - create_resource_bounds_mapping(NON_EMPTY_RESOURCE_BOUNDS, NON_EMPTY_RESOURCE_BOUNDS), + create_resource_bounds_mapping( + NON_EMPTY_RESOURCE_BOUNDS, + NON_EMPTY_RESOURCE_BOUNDS, + ResourceBounds::default(), + ), calldata![], TransactionSignature::default() )] @@ -111,7 +129,7 @@ fn default_validator_config_for_testing() -> &'static StatelessTransactionValida )] fn test_positive_flow( #[case] config: StatelessTransactionValidatorConfig, - #[case] resource_bounds: ResourceBoundsMapping, + #[case] resource_bounds: AllResourceBounds, #[case] tx_calldata: Calldata, #[case] signature: TransactionSignature, #[values(TransactionType::Declare, TransactionType::DeployAccount, TransactionType::Invoke)] @@ -141,14 +159,18 @@ fn test_positive_flow( validate_non_zero_l2_gas_fee: true, ..default_validator_config_for_testing().clone() }, - create_resource_bounds_mapping(NON_EMPTY_RESOURCE_BOUNDS, ResourceBounds::default()), + create_resource_bounds_mapping( + NON_EMPTY_RESOURCE_BOUNDS, + ResourceBounds::default(), + ResourceBounds::default(), + ), StatelessTransactionValidatorError::ZeroResourceBounds{ resource: Resource::L2Gas, resource_bounds: ResourceBounds::default() } )] fn test_invalid_resource_bounds( #[case] config: StatelessTransactionValidatorConfig, - #[case] resource_bounds: ResourceBoundsMapping, + #[case] resource_bounds: AllResourceBounds, #[case] expected_error: StatelessTransactionValidatorError, #[values(TransactionType::Declare, TransactionType::DeployAccount, TransactionType::Invoke)] tx_type: TransactionType, @@ -283,7 +305,7 @@ fn test_declare_sierra_version_failure( StatelessTransactionValidator { config: default_validator_config_for_testing().clone() }; let contract_class = ContractClass { sierra_program, ..Default::default() }; - let tx = external_declare_tx(declare_tx_args!(contract_class)); + let tx = rpc_declare_tx(declare_tx_args!(contract_class)); assert_eq!(tx_validator.validate(&tx).unwrap_err(), expected_error); } @@ -303,7 +325,7 @@ fn test_declare_sierra_version_sucsses(#[case] sierra_program: Vec) { StatelessTransactionValidator { config: default_validator_config_for_testing().clone() }; let contract_class = ContractClass { sierra_program, ..Default::default() }; - let tx = external_declare_tx(declare_tx_args!(contract_class)); + let tx = rpc_declare_tx(declare_tx_args!(contract_class)); assert_matches!(tx_validator.validate(&tx), Ok(())); } @@ -322,7 +344,7 @@ fn test_declare_contract_class_size_too_long() { ..Default::default() }; let contract_class_length = serde_json::to_string(&contract_class).unwrap().len(); - let tx = external_declare_tx(declare_tx_args!(contract_class)); + let tx = rpc_declare_tx(declare_tx_args!(contract_class)); assert_matches!( tx_validator.validate(&tx).unwrap_err(), @@ -390,7 +412,7 @@ fn test_declare_entry_points_not_sorted_by_selector( }, ..Default::default() }; - let tx = external_declare_tx(declare_tx_args!(contract_class)); + let tx = rpc_declare_tx(declare_tx_args!(contract_class)); assert_eq!(tx_validator.validate(&tx), expected); @@ -403,7 +425,7 @@ fn test_declare_entry_points_not_sorted_by_selector( }, ..Default::default() }; - let tx = external_declare_tx(declare_tx_args!(contract_class)); + let tx = rpc_declare_tx(declare_tx_args!(contract_class)); assert_eq!(tx_validator.validate(&tx), expected); @@ -416,7 +438,7 @@ fn test_declare_entry_points_not_sorted_by_selector( }, ..Default::default() }; - let tx = external_declare_tx(declare_tx_args!(contract_class)); + let tx = rpc_declare_tx(declare_tx_args!(contract_class)); assert_eq!(tx_validator.validate(&tx), expected); } diff --git a/crates/gateway/src/utils.rs b/crates/gateway/src/utils.rs index 1b8af37bb6..adf3705e58 100644 --- a/crates/gateway/src/utils.rs +++ b/crates/gateway/src/utils.rs @@ -6,6 +6,12 @@ use blockifier::transaction::transactions::{ InvokeTransaction as BlockifierInvokeTransaction, }; use starknet_api::core::{calculate_contract_address, ChainId, ClassHash, ContractAddress}; +use starknet_api::executable_transaction::{ + DeclareTransaction as ExecutableDeclareTransaction, + DeployAccountTransaction as ExecutableDeployAccountTransaction, + InvokeTransaction as ExecutableInvokeTransaction, + Transaction as ExecutableTransaction, +}; use starknet_api::rpc_transaction::{ RpcDeclareTransaction, RpcDeployAccountTransaction, @@ -19,11 +25,79 @@ use starknet_api::transaction::{ DeployAccountTransactionV3, InvokeTransactionV3, TransactionHasher, + ValidResourceBounds, }; -use tracing::error; +use tracing::{debug, error}; + +use crate::compilation::GatewayCompiler; +use crate::errors::{GatewayResult, GatewaySpecError, StatefulTransactionValidatorResult}; + +/// Converts an RPC transaction to an executable transaction. +/// Note, for declare transaction this step is heavy, as it requires compilation of Sierra to +/// executable contract class. +pub fn compile_contract_and_build_executable_tx( + rpc_tx: RpcTransaction, + gateway_compiler: &GatewayCompiler, + chain_id: &ChainId, +) -> GatewayResult { + Ok(match rpc_tx { + RpcTransaction::Declare(rpc_declare_tx) => { + let executable_declare_tx = compile_contract_and_build_executable_declare_tx( + rpc_declare_tx, + gateway_compiler, + chain_id, + )?; + ExecutableTransaction::Declare(executable_declare_tx) + } + RpcTransaction::DeployAccount(rpc_deploy_account_tx) => { + let executable_deploy_account_tx = + ExecutableDeployAccountTransaction::from_rpc_tx(rpc_deploy_account_tx, chain_id) + .map_err(|error| { + error!( + "Failed to convert RPC deploy account transaction to executable \ + transaction: {}", + error + ); + GatewaySpecError::UnexpectedError { + data: "Internal server error".to_owned(), + } + })?; + ExecutableTransaction::DeployAccount(executable_deploy_account_tx) + } + RpcTransaction::Invoke(rpc_invoke_tx) => { + let executable_invoke_tx = ExecutableInvokeTransaction::from_rpc_tx( + rpc_invoke_tx, + chain_id, + ) + .map_err(|error| { + error!( + "Failed to convert RPC invoke transaction to executable transaction: {}", + error + ); + GatewaySpecError::UnexpectedError { data: "Internal server error".to_owned() } + })?; + ExecutableTransaction::Invoke(executable_invoke_tx) + } + }) +} -use crate::errors::{GatewaySpecError, StatefulTransactionValidatorResult}; +fn compile_contract_and_build_executable_declare_tx( + rpc_tx: RpcDeclareTransaction, + gateway_compiler: &GatewayCompiler, + chain_id: &ChainId, +) -> GatewayResult { + let class_info = gateway_compiler.process_declare_tx(&rpc_tx)?; + let declare_tx: starknet_api::transaction::DeclareTransaction = rpc_tx.into(); + let executable_declare_tx = + ExecutableDeclareTransaction::create(declare_tx, class_info, chain_id).map_err(|err| { + debug!("Failed to create executable declare transaction {:?}", err); + GatewaySpecError::UnexpectedError { data: "Internal server error.".to_owned() } + })?; + + Ok(executable_declare_tx) +} +// TODO(Arni): Remove this function. pub fn rpc_tx_to_account_tx( rpc_tx: &RpcTransaction, // FIXME(yael 15/4/24): calculate class_info inside the function once compilation code is ready @@ -35,7 +109,7 @@ pub fn rpc_tx_to_account_tx( let declare_tx = DeclareTransaction::V3(DeclareTransactionV3 { class_hash: ClassHash::default(), /* FIXME(yael 15/4/24): call the starknet-api * function once ready */ - resource_bounds: tx.resource_bounds.clone().into(), + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds.clone()), tip: tx.tip, signature: tx.signature.clone(), nonce: tx.nonce, @@ -63,7 +137,7 @@ pub fn rpc_tx_to_account_tx( } RpcTransaction::DeployAccount(RpcDeployAccountTransaction::V3(tx)) => { let deploy_account_tx = DeployAccountTransaction::V3(DeployAccountTransactionV3 { - resource_bounds: tx.resource_bounds.clone().into(), + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds.clone()), tip: tx.tip, signature: tx.signature.clone(), nonce: tx.nonce, @@ -99,7 +173,7 @@ pub fn rpc_tx_to_account_tx( } RpcTransaction::Invoke(RpcInvokeTransaction::V3(tx)) => { let invoke_tx = starknet_api::transaction::InvokeTransaction::V3(InvokeTransactionV3 { - resource_bounds: tx.resource_bounds.clone().into(), + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds.clone()), tip: tx.tip, signature: tx.signature.clone(), nonce: tx.nonce, diff --git a/crates/gateway_types/Cargo.toml b/crates/gateway_types/Cargo.toml new file mode 100644 index 0000000000..009a988397 --- /dev/null +++ b/crates/gateway_types/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "starknet_gateway_types" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[lints] +workspace = true diff --git a/crates/gateway_types/src/lib.rs b/crates/gateway_types/src/lib.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/crates/gateway_types/src/lib.rs @@ -0,0 +1 @@ + diff --git a/crates/http_server/Cargo.toml b/crates/http_server/Cargo.toml new file mode 100644 index 0000000000..48d99ffb97 --- /dev/null +++ b/crates/http_server/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "starknet_http_server" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[lints] +workspace = true diff --git a/crates/http_server/src/lib.rs b/crates/http_server/src/lib.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/crates/http_server/src/lib.rs @@ -0,0 +1 @@ + diff --git a/crates/mempool/src/lib.rs b/crates/mempool/src/lib.rs index 322265e5d7..6dc5fe9fa5 100644 --- a/crates/mempool/src/lib.rs +++ b/crates/mempool/src/lib.rs @@ -1,4 +1,5 @@ pub mod communication; pub mod mempool; +pub(crate) mod suspended_transaction_pool; pub(crate) mod transaction_pool; pub(crate) mod transaction_queue; diff --git a/crates/mempool/src/mempool.rs b/crates/mempool/src/mempool.rs index a34e4d0ec3..a5f9539838 100644 --- a/crates/mempool/src/mempool.rs +++ b/crates/mempool/src/mempool.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::executable_transaction::Transaction; -use starknet_api::transaction::{DeprecatedResourceBoundsMapping, Resource, Tip, TransactionHash}; +use starknet_api::transaction::{Tip, TransactionHash, ValidResourceBounds}; use starknet_mempool_types::errors::MempoolError; use starknet_mempool_types::mempool_types::{Account, AccountState, MempoolInput, MempoolResult}; @@ -13,6 +13,8 @@ use crate::transaction_queue::TransactionQueue; #[path = "mempool_test.rs"] pub mod mempool_test; +type AccountToNonce = HashMap; + #[derive(Debug, Default)] pub struct Mempool { // TODO: add docstring explaining visibility and coupling of the fields. @@ -22,6 +24,8 @@ pub struct Mempool { tx_queue: TransactionQueue, // Represents the current state of the mempool during block creation. mempool_state: HashMap, + // The most recent account nonces received, for all account in the pool. + account_nonces: AccountToNonce, } impl Mempool { @@ -54,6 +58,10 @@ impl Mempool { let mut eligible_txs: Vec = Vec::with_capacity(n_txs); for tx_ref in &eligible_tx_references { let tx = self.tx_pool.remove(tx_ref.tx_hash)?; + let address = tx.contract_address(); + if !self.tx_pool.contains_account(address) { + self.account_nonces.remove(&address); + } eligible_txs.push(tx); } @@ -70,7 +78,11 @@ impl Mempool { /// TODO: check Account nonce and balance. pub fn add_tx(&mut self, input: MempoolInput) -> MempoolResult<()> { self.validate_input(&input)?; - self.insert_tx(input) + let MempoolInput { tx, account: Account { sender_address, state: AccountState { nonce } } } = + input; + self.tx_pool.insert(tx)?; + self.align_to_account_state(sender_address, nonce); + Ok(()) } /// Update the mempool's internal state according to the committed block (resolves nonce gaps, @@ -100,14 +112,9 @@ impl Mempool { Ok(()) } - fn insert_tx(&mut self, input: MempoolInput) -> MempoolResult<()> { - let MempoolInput { tx, account: Account { sender_address, state: AccountState { nonce } } } = - input; - - self.tx_pool.insert(tx)?; - self.align_to_account_state(sender_address, nonce); - - Ok(()) + // TODO(Mohammad): Rename this method once consensus API is added. + fn _update_gas_price_threshold(&mut self, threshold: u128) { + self.tx_queue._update_gas_price_threshold(threshold); } fn validate_input(&self, input: &MempoolInput) -> MempoolResult<()> { @@ -170,11 +177,25 @@ impl Mempool { // Maybe remove out-of-date transactions. // Note: != is equivalent to > in `add_tx`, as lower nonces are rejected in validation. if self.tx_queue.get_nonce(address).is_some_and(|queued_nonce| queued_nonce != nonce) { - self.tx_queue.remove(address); + assert!(self.tx_queue.remove(address), "Expected to remove address from queue."); } + // Remove from pool. self.tx_pool.remove_up_to_nonce(address, nonce); + if self.tx_pool.contains_account(address) { + match self.account_nonces.get(&address) { + // Skip updating the account nonce if it is greater than the received nonce. + Some(current_account_nonce) if current_account_nonce > &nonce => {} + _ => { + self.account_nonces.insert(address, nonce); + } + } + } else { + // Remove address if no transactions from it left. + self.account_nonces.remove(&address); + } + // Maybe close nonce gap. if self.tx_queue.get_nonce(address).is_none() { if let Some(tx_reference) = self.tx_pool.get_by_address_and_nonce(address, nonce) { @@ -184,7 +205,7 @@ impl Mempool { } #[cfg(test)] - pub(crate) fn _tx_pool(&self) -> &TransactionPool { + pub(crate) fn tx_pool(&self) -> &TransactionPool { &self.tx_pool } } @@ -194,13 +215,13 @@ impl Mempool { /// TODO(Mohammad): rename this struct to `ThinTransaction` once that name /// becomes available, to better reflect its purpose and usage. /// TODO(Mohammad): restore the Copy once ResourceBoundsMapping implements it. -#[derive(Clone, Debug, Default, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct TransactionReference { pub sender_address: ContractAddress, pub nonce: Nonce, pub tx_hash: TransactionHash, pub tip: Tip, - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, } impl TransactionReference { @@ -218,10 +239,6 @@ impl TransactionReference { } pub fn get_l2_gas_price(&self) -> u128 { - self.resource_bounds - .0 - .get(&Resource::L2Gas) - .map(|bounds| bounds.max_price_per_unit) - .expect("Expected a valid L2 gas resource bounds.") + self.resource_bounds.get_l2_bounds().max_price_per_unit } } diff --git a/crates/mempool/src/mempool_test.rs b/crates/mempool/src/mempool_test.rs index 5e220056ec..2a58675d1c 100644 --- a/crates/mempool/src/mempool_test.rs +++ b/crates/mempool/src/mempool_test.rs @@ -11,13 +11,13 @@ use rstest::{fixture, rstest}; use starknet_api::core::{ContractAddress, Nonce, PatriciaKey}; use starknet_api::executable_transaction::Transaction; use starknet_api::hash::StarkHash; -use starknet_api::transaction::{Tip, TransactionHash}; +use starknet_api::transaction::{Tip, TransactionHash, ValidResourceBounds}; use starknet_api::{contract_address, felt, patricia_key}; use starknet_mempool_types::errors::MempoolError; use starknet_mempool_types::mempool_types::{Account, AccountState}; use starknet_types_core::felt::Felt; -use crate::mempool::{Mempool, MempoolInput, TransactionReference}; +use crate::mempool::{AccountToNonce, Mempool, MempoolInput, TransactionReference}; use crate::transaction_pool::TransactionPool; use crate::transaction_queue::TransactionQueue; @@ -25,21 +25,14 @@ use crate::transaction_queue::TransactionQueue; /// Represents the internal content of the mempool. /// Enables customized (and potentially inconsistent) creation for unit testing. -#[derive(Debug)] -struct MempoolContent { +#[derive(Debug, Default)] +struct MempoolContent { tx_pool: Option, tx_queue: Option, - // Artificially use generic type, for the compiler. - _phantom: std::marker::PhantomData, + account_nonces: Option, } -#[derive(Debug)] -struct FullContent; -#[allow(dead_code)] -#[derive(Debug)] -struct PartialContent; - -impl MempoolContent { +impl MempoolContent { fn with_pool_and_queue(pool_txs: P, queue_txs: Q) -> Self where P: IntoIterator, @@ -49,68 +42,70 @@ impl MempoolContent { Self { tx_pool: Some(pool_txs.into_iter().collect()), tx_queue: Some(queue_txs.into_iter().collect()), - _phantom: std::marker::PhantomData, + ..Self::default() } } -} -impl MempoolContent { - fn with_pool

(pool_txs: P) -> Self + fn with_pool_and_account_nonces(pool_txs: P, account_nonce_pairs: A) -> Self where P: IntoIterator, + A: IntoIterator, { Self { tx_pool: Some(pool_txs.into_iter().collect()), - tx_queue: None, - _phantom: std::marker::PhantomData, + account_nonces: Some(account_nonce_pairs.into_iter().collect()), + ..Self::default() } } + fn with_pool

(pool_txs: P) -> Self + where + P: IntoIterator, + { + Self { tx_pool: Some(pool_txs.into_iter().collect()), ..Self::default() } + } + fn with_queue(queue_txs: Q) -> Self where Q: IntoIterator, { - Self { - tx_queue: Some(queue_txs.into_iter().collect()), - tx_pool: None, - _phantom: std::marker::PhantomData, - } + Self { tx_queue: Some(queue_txs.into_iter().collect()), ..Self::default() } + } + + fn with_account_nonces(account_nonce_pairs: A) -> Self + where + A: IntoIterator, + { + Self { account_nonces: Some(account_nonce_pairs.into_iter().collect()), ..Self::default() } } -} -impl MempoolContent { fn assert_eq_pool_and_queue_content(&self, mempool: &Mempool) { - self.assert_eq_pool_content(mempool); - self.assert_eq_queue_content(mempool); + self.assert_eq_transaction_pool_content(mempool); + self.assert_eq_transaction_queue_content(mempool); } - fn assert_eq_pool_content(&self, mempool: &Mempool) { + fn assert_eq_transaction_pool_content(&self, mempool: &Mempool) { assert_eq!(self.tx_pool.as_ref().unwrap(), &mempool.tx_pool); } - fn assert_eq_queue_content(&self, mempool: &Mempool) { + fn assert_eq_transaction_queue_content(&self, mempool: &Mempool) { assert_eq!(self.tx_queue.as_ref().unwrap(), &mempool.tx_queue); } + + fn assert_eq_account_nonces(&self, mempool: &Mempool) { + assert_eq!(self.account_nonces.as_ref().unwrap(), &mempool.account_nonces); + } } -impl From> for Mempool { - fn from(mempool_content: MempoolContent) -> Mempool { - let MempoolContent { tx_pool, tx_queue, _phantom: _ } = mempool_content; +impl From for Mempool { + fn from(mempool_content: MempoolContent) -> Mempool { + let MempoolContent { tx_pool, tx_queue, account_nonces } = mempool_content; Mempool { tx_pool: tx_pool.unwrap_or_default(), tx_queue: tx_queue.unwrap_or_default(), // TODO: Add implementation when needed. mempool_state: Default::default(), - } - } -} - -impl Default for MempoolContent { - fn default() -> Self { - Self { - tx_pool: Some(TransactionPool::default()), - tx_queue: Some(TransactionQueue::default()), - _phantom: std::marker::PhantomData, + account_nonces: account_nonces.unwrap_or_default(), } } } @@ -150,8 +145,15 @@ fn add_tx_expect_error(mempool: &mut Mempool, input: &MempoolInput, expected_err /// 1. add_tx_input!(tip: 1, tx_hash: 2, sender_address: 3_u8, tx_nonce: 4, account_nonce: 3) /// 2. add_tx_input!(tx_hash: 2, sender_address: 3_u8, tx_nonce: 4, account_nonce: 3) /// 3. add_tx_input!(tip: 1, tx_hash: 2, sender_address: 3_u8) -/// 4. add_tx_input!(tx_hash: 1, tx_nonce: 1, account_nonce: 0) -/// 5. add_tx_input!(tip: 1, tx_hash: 2) +/// 4. add_tx_input!(resource_bound: resource_bound, tx_hash: 1, tx_nonce: 1, account_nonce: 0) +/// 5. add_tx_input!(tx_hash: 1, tx_nonce: 1, account_nonce: 0) +/// 6. add_tx_input!(tx_nonce: 1, account_nonce: 0) +/// 7. add_tx_input!(tip: 1, tx_hash: 2) +/// 8. add_tx_input!() + +// TODO(Mohammad): remove the unused macro once the non-default resource bounds and default +// transaction input are implemented. +#[allow(unused_macro_rules)] macro_rules! add_tx_input { (tip: $tip:expr, tx_hash: $tx_hash:expr, sender_address: $sender_address:expr, tx_nonce: $tx_nonce:expr, account_nonce: $account_nonce:expr, resource_bounds: $resource_bounds:expr) => {{ @@ -170,7 +172,7 @@ macro_rules! add_tx_input { }}; (tip: $tip:expr, tx_hash: $tx_hash:expr, sender_address: $sender_address:expr, tx_nonce: $tx_nonce:expr, account_nonce: $account_nonce:expr) => {{ - add_tx_input!(tip: $tip, tx_hash: $tx_hash, sender_address: $sender_address, tx_nonce: $tx_nonce, account_nonce: $account_nonce, resource_bounds: test_resource_bounds_mapping().into()) + add_tx_input!(tip: $tip, tx_hash: $tx_hash, sender_address: $sender_address, tx_nonce: $tx_nonce, account_nonce: $account_nonce, resource_bounds: ValidResourceBounds::AllResources(test_resource_bounds_mapping())) }}; (tx_hash: $tx_hash:expr, sender_address: $sender_address:expr, tx_nonce: $tx_nonce:expr, account_nonce: $account_nonce:expr) => { add_tx_input!(tip: 0, tx_hash: $tx_hash, sender_address: $sender_address, tx_nonce: $tx_nonce, account_nonce: $account_nonce) @@ -178,12 +180,21 @@ macro_rules! add_tx_input { (tip: $tip:expr, tx_hash: $tx_hash:expr, sender_address: $sender_address:expr) => { add_tx_input!(tip: $tip, tx_hash: $tx_hash, sender_address: $sender_address, tx_nonce: 0_u8, account_nonce: 0_u8) }; + (tx_hash: $tx_hash:expr, tx_nonce: $tx_nonce:expr, account_nonce: $account_nonce:expr, resource_bounds: $resource_bounds:expr) => { + add_tx_input!(tip: 1, tx_hash: $tx_hash, sender_address: "0x0", tx_nonce: $tx_nonce, account_nonce: $account_nonce, resource_bounds: $resource_bounds) + }; (tx_hash: $tx_hash:expr, tx_nonce: $tx_nonce:expr, account_nonce: $account_nonce:expr) => { add_tx_input!(tip: 1, tx_hash: $tx_hash, sender_address: "0x0", tx_nonce: $tx_nonce, account_nonce: $account_nonce) }; + (tx_nonce: $tx_nonce:expr, account_nonce: $account_nonce:expr) => { + add_tx_input!(tip: 1, tx_hash: 0_u8, sender_address: "0x0", tx_nonce: $tx_nonce, account_nonce: $account_nonce) + }; (tip: $tip:expr, tx_hash: $tx_hash:expr) => { add_tx_input!(tip: $tip, tx_hash: $tx_hash, sender_address: "0x0", tx_nonce: 0_u8, account_nonce: 0_u8) }; + () => { + add_tx_input!(tip: 0, tx_hash: 0, sender_address: "0x0", tx_nonce: 0_u8, account_nonce: 0_u8) + }; } // Fixtures. @@ -254,7 +265,7 @@ fn test_get_txs_multi_nonce() { // Assert: all transactions are returned. assert_eq!(fetched_txs, &pool_txs); - let expected_mempool_content = MempoolContent::default(); + let expected_mempool_content = MempoolContent::with_pool_and_queue([], []); expected_mempool_content.assert_eq_pool_and_queue_content(&mempool); } @@ -280,7 +291,7 @@ fn test_get_txs_replenishes_queue_only_between_chunks() { // Replenishment done in chunks: account 1 transaction is returned before the one of account 0, // although its priority is higher. assert_eq!(txs, &[tx_address_0_nonce_0, tx_address_1_nonce_0, tx_address_0_nonce_1]); - let expected_mempool_content = MempoolContent::default(); + let expected_mempool_content = MempoolContent::with_pool_and_queue([], []); expected_mempool_content.assert_eq_pool_and_queue_content(&mempool); } @@ -366,6 +377,55 @@ fn test_get_txs_with_holes_single_account() { expected_mempool_content.assert_eq_pool_and_queue_content(&mempool); } +#[rstest] +fn test_get_txs_while_decreasing_gas_price_threshold() { + // Setup. + let input_tx = add_tx_input!(tx_nonce: 0_u8, account_nonce: 0_u8); + + let pool_txs = [input_tx.tx.clone()]; + let queue_txs = [TransactionReference::new(&input_tx.tx)]; + let mut mempool: Mempool = MempoolContent::with_pool_and_queue(pool_txs, queue_txs).into(); + + // Test. + // High gas price threshold, no transactions should be returned. + mempool._update_gas_price_threshold(1000000000000); + let txs = mempool.get_txs(1).unwrap(); + assert!(txs.is_empty()); + + // Updating the gas price threshold should happen in a new block creation. + assert!(mempool.commit_block(HashMap::default()).is_ok()); + // Low gas price threshold, the transaction should be returned. + mempool._update_gas_price_threshold(100); + let txs = mempool.get_txs(1).unwrap(); + + assert_eq!(txs, &[input_tx.tx]); +} + +#[rstest] +fn test_get_txs_while_increasing_gas_price_threshold() { + // Setup. + // Both transactions have the same gas price. + let input_tx_nonce_0 = add_tx_input!(tx_nonce: 0_u8, account_nonce: 0_u8); + let input_tx_nonce_1 = add_tx_input!(tx_hash: 1, tx_nonce: 1_u8, account_nonce: 0_u8); + + let pool_txs = [input_tx_nonce_0.tx.clone(), input_tx_nonce_1.tx]; + let queue_txs = [TransactionReference::new(&input_tx_nonce_0.tx)]; + let mut mempool: Mempool = MempoolContent::with_pool_and_queue(pool_txs, queue_txs).into(); + + // Test. + // Low gas price threshold, the transaction should be returned. + mempool._update_gas_price_threshold(100); + let txs = mempool.get_txs(1).unwrap(); + assert_eq!(txs, &[input_tx_nonce_0.tx]); + + // Updating the gas price threshold should happen in a new block creation. + assert!(mempool.commit_block(HashMap::default()).is_ok()); + // High gas price threshold, no transactions should be returned. + mempool._update_gas_price_threshold(1000000000000); + let txs = mempool.get_txs(1).unwrap(); + assert!(txs.is_empty()); +} + // add_tx tests. #[rstest] @@ -435,7 +495,7 @@ fn test_add_tx_with_duplicate_tx(mut mempool: Mempool) { // Assert: the original transaction remains. let expected_mempool_content = MempoolContent::with_pool([input.tx]); - expected_mempool_content.assert_eq_pool_content(&mempool); + expected_mempool_content.assert_eq_transaction_pool_content(&mempool); } #[rstest] @@ -453,7 +513,7 @@ fn test_add_tx_lower_than_queued_nonce() { // Test and assert the original transaction remains. assert_matches!(mempool.add_tx(lower_nonce_input), Err(MempoolError::DuplicateNonce { .. })); - expected_mempool_content.assert_eq_queue_content(&mempool); + expected_mempool_content.assert_eq_transaction_queue_content(&mempool); } #[rstest] @@ -473,7 +533,7 @@ fn test_add_tx_updates_queue_with_higher_account_nonce() { // Assert: the higher account nonce transaction is in the queue. let expected_queue_txs = [TransactionReference::new(&higher_account_nonce_input.tx)]; let expected_mempool_content = MempoolContent::with_queue(expected_queue_txs); - expected_mempool_content.assert_eq_queue_content(&mempool); + expected_mempool_content.assert_eq_transaction_queue_content(&mempool); } #[rstest] @@ -541,7 +601,7 @@ fn test_tip_priority_over_tx_hash(mut mempool: Mempool) { let expected_queue_txs = [&input_big_tip_small_hash.tx, &input_small_tip_big_hash.tx].map(TransactionReference::new); let expected_mempool_content = MempoolContent::with_queue(expected_queue_txs); - expected_mempool_content.assert_eq_queue_content(&mempool); + expected_mempool_content.assert_eq_transaction_queue_content(&mempool); } #[rstest] @@ -556,19 +616,19 @@ fn test_add_tx_account_state_fills_hole(mut mempool: Mempool) { // First, with gap. add_tx(&mut mempool, &tx_input_nonce_1); let expected_mempool_content = MempoolContent::with_queue([]); - expected_mempool_content.assert_eq_queue_content(&mempool); + expected_mempool_content.assert_eq_transaction_queue_content(&mempool); // Then, fill it. add_tx(&mut mempool, &tx_input_nonce_2); let expected_queue_txs = [&tx_input_nonce_1.tx].map(TransactionReference::new); let expected_mempool_content = MempoolContent::with_queue(expected_queue_txs); - expected_mempool_content.assert_eq_queue_content(&mempool); + expected_mempool_content.assert_eq_transaction_queue_content(&mempool); } #[rstest] fn test_add_tx_sequential_nonces(mut mempool: Mempool) { // Setup. - let input_nonce_0 = add_tx_input!(tx_hash: 0, tx_nonce: 0_u8, account_nonce: 0_u8); + let input_nonce_0 = add_tx_input!(tx_nonce: 0_u8, account_nonce: 0_u8); let input_nonce_1 = add_tx_input!(tx_hash: 1, tx_nonce: 1_u8, account_nonce: 0_u8); // Test. @@ -678,7 +738,7 @@ fn test_commit_block_rewinds_nonce() { // Assert. let expected_mempool_content = MempoolContent::with_queue([]); - expected_mempool_content.assert_eq_queue_content(&mempool); + expected_mempool_content.assert_eq_transaction_queue_content(&mempool); } #[rstest] @@ -706,7 +766,98 @@ fn test_commit_block_from_different_leader() { // Assert. let expected_queue_txs = [&tx_address0_nonce6].map(TransactionReference::new); let expected_mempool_content = MempoolContent::with_queue(expected_queue_txs); - expected_mempool_content.assert_eq_queue_content(&mempool); + expected_mempool_content.assert_eq_transaction_queue_content(&mempool); +} + +// account_nonces tests. + +#[rstest] +fn test_account_nonces_update_in_add_tx(mut mempool: Mempool) { + // Setup. + let input = add_tx_input!(tx_nonce: 1_u8, account_nonce: 1_u8); + + // Test: update through new input. + add_tx(&mut mempool, &input); + + // Assert. + let expected_mempool_content = MempoolContent::with_account_nonces(vec![( + input.account.sender_address, + input.account.state.nonce, + )]); + expected_mempool_content.assert_eq_account_nonces(&mempool); +} + +#[rstest] +fn test_account_nonce_does_not_decrease_in_add_tx() { + // Setup. + let input_with_lower_account_nonce = add_tx_input!(tx_nonce: 0_u8, account_nonce: 0_u8); + let account_nonces = + [(input_with_lower_account_nonce.account.sender_address, Nonce(felt!(2_u8)))]; + let mut mempool: Mempool = MempoolContent::with_account_nonces(account_nonces).into(); + + // Test: receives a transaction with a lower account nonce. + add_tx(&mut mempool, &input_with_lower_account_nonce); + + // Assert: the account nonce is not updated. + let expected_mempool_content = MempoolContent::with_account_nonces(account_nonces); + expected_mempool_content.assert_eq_account_nonces(&mempool); +} + +#[rstest] +fn test_account_nonces_update_in_commit_block() { + // Setup. + let input = add_tx_input!(tx_nonce: 2_u8, account_nonce: 0_u8); + let address = input.account.sender_address; + let pool_txs = [input.tx]; + let account_nonces = [(address, input.account.state.nonce)]; + let mut mempool: Mempool = + MempoolContent::with_pool_and_account_nonces(pool_txs, account_nonces).into(); + let committed_nonce = Nonce(Felt::ZERO); + + // Test: update through a commit block. + let state_changes = HashMap::from([(address, AccountState { nonce: committed_nonce })]); + assert_eq!(mempool.commit_block(state_changes), Ok(())); + + // Assert. + let expected_mempool_content = MempoolContent::with_account_nonces(vec![( + address, + committed_nonce.try_increment().unwrap(), + )]); + expected_mempool_content.assert_eq_account_nonces(&mempool); +} + +#[rstest] +fn test_account_nonce_does_not_decrease_in_commit_block() { + // Setup. + let input_account_nonce_2 = add_tx_input!(tx_nonce: 3_u8, account_nonce: 2_u8); + let address = input_account_nonce_2.account.sender_address; + let account_nonces = [(address, input_account_nonce_2.account.state.nonce)]; + let pool_txs = [input_account_nonce_2.tx]; + let mut mempool: Mempool = + MempoolContent::with_pool_and_account_nonces(pool_txs, account_nonces).into(); + + // Test: commits state change of a lower account nonce. + let state_changes = HashMap::from([(address, AccountState { nonce: Nonce(felt!(0_u8)) })]); + assert_eq!(mempool.commit_block(state_changes), Ok(())); + + // Assert: the account nonce is not updated. + let expected_mempool_content = MempoolContent::with_account_nonces(account_nonces); + expected_mempool_content.assert_eq_account_nonces(&mempool); +} + +#[rstest] +fn test_account_nonces_removal_in_commit_block(mut mempool: Mempool) { + // Setup. + let address = contract_address!("0x0"); + let nonce = Nonce(felt!(0_u8)); + + // Test: commit block returns information about account that is not in the mempool. + let state_changes = HashMap::from([(address, AccountState { nonce })]); + assert_eq!(mempool.commit_block(state_changes), Ok(())); + + // Assert: account is not added to the mempool. + let expected_mempool_content = MempoolContent::with_account_nonces(vec![]); + expected_mempool_content.assert_eq_account_nonces(&mempool); } // Flow tests. @@ -811,7 +962,7 @@ fn test_flow_commit_block_closes_hole() { // Assert: hole was indeed closed. let expected_queue_txs = [&tx_nonce5].map(TransactionReference::new); let expected_mempool_content = MempoolContent::with_queue(expected_queue_txs); - expected_mempool_content.assert_eq_queue_content(&mempool); + expected_mempool_content.assert_eq_transaction_queue_content(&mempool); let res = mempool.add_tx(tx_input_nonce4); assert_eq!( @@ -852,5 +1003,37 @@ fn test_flow_send_same_nonce_tx_after_previous_not_included() { assert_eq!(txs, &[tx_input_nonce4.tx]); let expected_queue_txs = [TransactionReference::new(&tx_nonce5)]; let expected_mempool_content = MempoolContent::with_queue(expected_queue_txs); - expected_mempool_content.assert_eq_queue_content(&mempool); + expected_mempool_content.assert_eq_transaction_queue_content(&mempool); +} + +#[rstest] +fn test_tx_pool_capacity(mut mempool: Mempool) { + let input_1 = + add_tx_input!(tx_hash: 0, sender_address: 0_u8, tx_nonce: 0_u8, account_nonce: 0_u8); + let input_2 = + add_tx_input!(tx_hash: 1, sender_address: 1_u8, tx_nonce: 0_u8, account_nonce: 0_u8); + + // Test and assert: add txs to the counter. + add_tx(&mut mempool, &input_1); + add_tx(&mut mempool, &input_2); + assert_eq!(mempool.tx_pool().n_txs(), 2); + + // Test and assert: duplicate transaction doesn't affect capacity. + add_tx_expect_error( + &mut mempool, + &input_1, + MempoolError::DuplicateTransaction { tx_hash: input_1.tx.tx_hash() }, + ); + assert_eq!(mempool.tx_pool().n_txs(), 2); + + // Test and assert: updates pool capacity when a transaction is removed upon receiving state + // changes. + let state_changes = + HashMap::from([(contract_address!("0x0"), AccountState { nonce: Nonce(felt!(4_u8)) })]); + assert!(mempool.commit_block(state_changes).is_ok()); + assert_eq!(mempool.tx_pool().n_txs(), 1); + + // Test and assert: remove the transactions, counter does not go below 0. + mempool.get_txs(2).unwrap(); + assert_eq!(mempool.tx_pool().n_txs(), 0); } diff --git a/crates/mempool/src/suspended_transaction_pool.rs b/crates/mempool/src/suspended_transaction_pool.rs new file mode 100644 index 0000000000..49b10ab85c --- /dev/null +++ b/crates/mempool/src/suspended_transaction_pool.rs @@ -0,0 +1,14 @@ +use std::collections::HashMap; + +use starknet_api::core::{ContractAddress, Nonce}; + +use crate::mempool::TransactionReference; + +type AddressNonceToTransaction = HashMap<(ContractAddress, Nonce), TransactionReference>; + +#[derive(Debug, Default)] +pub struct SuspendedTransactionPool { + _suspended_tx_pool: AddressNonceToTransaction, +} + +impl SuspendedTransactionPool {} diff --git a/crates/mempool/src/transaction_pool.rs b/crates/mempool/src/transaction_pool.rs index 2e6ea52eb9..f10b78b62d 100644 --- a/crates/mempool/src/transaction_pool.rs +++ b/crates/mempool/src/transaction_pool.rs @@ -20,6 +20,8 @@ pub struct TransactionPool { tx_pool: HashToTransaction, // Transactions organized by account address, sorted by ascending nonce values. txs_by_account: AccountTransactionIndex, + // Tracks the capacity of the pool. + capacity: PoolCapacity, } impl TransactionPool { @@ -43,6 +45,8 @@ impl TransactionPool { ) }; + self.capacity.add(); + Ok(()) } @@ -59,6 +63,8 @@ impl TransactionPool { ) }); + self.capacity.remove(); + Ok(tx) } @@ -72,6 +78,8 @@ impl TransactionPool { in account mapping, but does not appear in the main mapping" ); }); + + self.capacity.remove(); } } @@ -97,7 +105,11 @@ impl TransactionPool { Ok(self.get_by_address_and_nonce(sender_address, next_nonce)) } - #[allow(dead_code)] + #[cfg(test)] + pub fn n_txs(&self) -> usize { + self.capacity.n_txs + } + pub fn contains_account(&self, address: ContractAddress) -> bool { self.txs_by_account.contains(address) } @@ -154,3 +166,20 @@ impl AccountTransactionIndex { self.0.contains_key(&address) } } + +#[derive(Debug, Default, Eq, PartialEq)] +pub struct PoolCapacity { + n_txs: usize, + // TODO(Ayelet): Add size tracking. +} + +impl PoolCapacity { + fn add(&mut self) { + self.n_txs += 1; + } + + fn remove(&mut self) { + self.n_txs = + self.n_txs.checked_sub(1).expect("Underflow: Cannot subtract from an empty pool."); + } +} diff --git a/crates/mempool/src/transaction_queue.rs b/crates/mempool/src/transaction_queue.rs index 60935e784d..a550a83208 100644 --- a/crates/mempool/src/transaction_queue.rs +++ b/crates/mempool/src/transaction_queue.rs @@ -2,15 +2,26 @@ use std::cmp::Ordering; use std::collections::{BTreeSet, HashMap}; use starknet_api::core::{ContractAddress, Nonce}; +use starknet_api::transaction::{ + AllResourceBounds, + ResourceBounds, + Tip, + TransactionHash, + ValidResourceBounds, +}; use crate::mempool::TransactionReference; +// A queue holding the transaction that with nonces that match account nonces. // Note: the derived comparison functionality considers the order guaranteed by the data structures // used. #[derive(Debug, Default, Eq, PartialEq)] pub struct TransactionQueue { - // Priority queue of transactions with associated priority. + gas_price_threshold: u128, + // Transactions with gas price above gas price threshold (sorted by tip). priority_queue: BTreeSet, + // Transactions with gas price below gas price threshold (sorted by price). + pending_queue: BTreeSet, // Set of account addresses for efficient existence checks. address_to_tx: HashMap, } @@ -18,8 +29,6 @@ pub struct TransactionQueue { impl TransactionQueue { /// Adds a transaction to the mempool, ensuring unique keys. /// Panics: if given a duplicate tx. - // TODO(Mohammad): Add test for two transactions from the same address, expecting specific - // assert. pub fn insert(&mut self, tx_reference: TransactionReference) { assert_eq!( self.address_to_tx.insert(tx_reference.sender_address, tx_reference.clone()), @@ -27,8 +36,15 @@ impl TransactionQueue { "Only a single transaction from the same contract class can be in the mempool at a \ time." ); + + let new_tx_successfully_inserted = + if tx_reference.get_l2_gas_price() < self.gas_price_threshold { + self.pending_queue.insert(tx_reference.into()) + } else { + self.priority_queue.insert(tx_reference.into()) + }; assert!( - self.priority_queue.insert(tx_reference.into()), + new_tx_successfully_inserted, "Keys should be unique; duplicates are checked prior." ); } @@ -57,15 +73,65 @@ impl TransactionQueue { /// Removes the transaction of the given account address from the queue. /// This is well-defined, since there is at most one transaction per address in the queue. pub fn remove(&mut self, address: ContractAddress) -> bool { - if let Some(tx) = self.address_to_tx.remove(&address) { - return self.priority_queue.remove(&tx.into()); - } - false + let Some(tx_reference) = self.address_to_tx.remove(&address) else { + return false; + }; + + self.priority_queue.remove(&tx_reference.clone().into()) + || self.pending_queue.remove(&tx_reference.into()) } pub fn has_ready_txs(&self) -> bool { self.priority_queue.is_empty() } + + pub fn _update_gas_price_threshold(&mut self, threshold: u128) { + match threshold.cmp(&self.gas_price_threshold) { + Ordering::Less => self._promote_txs_to_priority(threshold), + Ordering::Greater => self._demote_txs_to_pending(threshold), + Ordering::Equal => {} + } + + self.gas_price_threshold = threshold; + } + + fn _promote_txs_to_priority(&mut self, threshold: u128) { + let tmp_split_tx = PendingTransaction(TransactionReference { + resource_bounds: ValidResourceBounds::AllResources(AllResourceBounds { + l2_gas: ResourceBounds { max_amount: 0, max_price_per_unit: threshold }, + ..Default::default() + }), + sender_address: ContractAddress::default(), + nonce: Nonce::default(), + tx_hash: TransactionHash::default(), + tip: Tip::default(), + }); + + // Split off the pending queue at the given transaction higher than the threshold. + let txs_over_threshold = self.pending_queue.split_off(&tmp_split_tx).into_iter(); + + // Insert all transactions from the split point into the priority queue, skip + // `tmp_split_tx`. + // Note: extend will reorder transactions by `Tip` during insertion, despite them being + // initially ordered by fee. + self.priority_queue.extend(txs_over_threshold.map(|tx| tx.0.into())); + } + + fn _demote_txs_to_pending(&mut self, threshold: u128) { + let mut to_remove = Vec::new(); + + // Remove all transactions from the priority queue that are below the threshold. + for priority_tx in &self.priority_queue { + if priority_tx.get_l2_gas_price() < threshold { + to_remove.push(priority_tx.clone()); + } + } + + for tx in &to_remove { + self.priority_queue.remove(tx); + } + self.pending_queue.extend(to_remove.into_iter().map(|tx| tx.0.into())); + } } /// Encapsulates a transaction reference to assess its order (i.e., gas price). diff --git a/crates/mempool_infra/Cargo.toml b/crates/mempool_infra/Cargo.toml index a36bde1434..3bdb5b3bd3 100644 --- a/crates/mempool_infra/Cargo.toml +++ b/crates/mempool_infra/Cargo.toml @@ -19,7 +19,7 @@ papyrus_config.workspace = true rstest.workspace = true serde = { workspace = true, features = ["derive"] } thiserror.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } tracing.workspace = true tracing-subscriber = { workspace = true, features = ["env-filter"] } validator.workspace = true diff --git a/crates/mempool_p2p/Cargo.toml b/crates/mempool_p2p/Cargo.toml new file mode 100644 index 0000000000..fd54989f89 --- /dev/null +++ b/crates/mempool_p2p/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "starknet_mempool_p2p" +version = "0.0.0" +edition.workspace = true +license.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +async-trait.workspace = true +papyrus_network.workspace = true +papyrus_proc_macros.workspace = true +serde = { workspace = true, features = ["derive"] } +starknet_api.workspace = true +starknet_mempool_infra.workspace = true +thiserror.workspace = true diff --git a/crates/mempool_p2p/src/lib.rs b/crates/mempool_p2p/src/lib.rs new file mode 100644 index 0000000000..a707360f2f --- /dev/null +++ b/crates/mempool_p2p/src/lib.rs @@ -0,0 +1,13 @@ +pub mod receiver; +pub mod sender; + +use papyrus_network::NetworkConfig; + +use crate::receiver::MempoolP2pReceiver; +use crate::sender::MempoolP2pSender; + +pub fn create_p2p_sender_and_receiver( + _network_config: NetworkConfig, +) -> (MempoolP2pSender, MempoolP2pReceiver) { + unimplemented!() +} diff --git a/crates/mempool_p2p/src/receiver/mod.rs b/crates/mempool_p2p/src/receiver/mod.rs new file mode 100644 index 0000000000..689096849b --- /dev/null +++ b/crates/mempool_p2p/src/receiver/mod.rs @@ -0,0 +1,11 @@ +use async_trait::async_trait; +use starknet_mempool_infra::component_runner::{ComponentStartError, ComponentStarter}; + +pub struct MempoolP2pReceiver; + +#[async_trait] +impl ComponentStarter for MempoolP2pReceiver { + async fn start(&mut self) -> Result<(), ComponentStartError> { + unimplemented!() + } +} diff --git a/crates/mempool_p2p/src/sender/mod.rs b/crates/mempool_p2p/src/sender/mod.rs new file mode 100644 index 0000000000..bf103b0792 --- /dev/null +++ b/crates/mempool_p2p/src/sender/mod.rs @@ -0,0 +1,104 @@ +use std::sync::Arc; + +use async_trait::async_trait; +pub use papyrus_network::network_manager::BroadcastedMessageManager; +use papyrus_proc_macros::handle_response_variants; +use serde::{Deserialize, Serialize}; +use starknet_api::rpc_transaction::RpcTransaction; +use starknet_mempool_infra::component_client::{ClientError, LocalComponentClient}; +use starknet_mempool_infra::component_definitions::ComponentRequestHandler; +use thiserror::Error; + +pub struct MempoolP2pSender; + +// This error is defined even though it's empty to be compatible with the other components. +#[derive(Debug, Error, Serialize, Deserialize, Clone)] +pub enum MempoolP2pSenderError {} + +pub type MempoolP2pSenderResult = Result; + +#[derive(Clone, Debug, Error)] +pub enum MempoolP2pSenderClientError { + #[error(transparent)] + ClientError(#[from] ClientError), + #[error(transparent)] + MempoolP2pSenderError(#[from] MempoolP2pSenderError), +} + +pub type MempoolP2pSenderClientResult = Result; + +#[async_trait] +pub trait MempoolP2pSenderClient: Send + Sync { + /// Adds a transaction to be propagated to other peers. This should only be called on a new + /// transaction coming from the user and not from another peer. To handle transactions coming + /// from other peers, use `continue_propagation`. + async fn add_transaction( + &self, + transaction: RpcTransaction, + ) -> MempoolP2pSenderClientResult<()>; + + /// Continues the propagation of a transaction we've received from another peer. + async fn continue_propagation( + &self, + propagation_manager: BroadcastedMessageManager, + ) -> MempoolP2pSenderClientResult<()>; +} + +pub type SharedMempoolP2pSenderClient = Arc; + +#[derive(Debug, Serialize, Deserialize)] +pub enum MempoolP2pSenderRequest { + AddTransaction(RpcTransaction), + ContinuePropagation(BroadcastedMessageManager), +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum MempoolP2pSenderResponse { + AddTransaction(MempoolP2pSenderResult<()>), + ContinuePropagation(MempoolP2pSenderResult<()>), +} + +#[async_trait] +impl ComponentRequestHandler + for MempoolP2pSender +{ + async fn handle_request( + &mut self, + _request: MempoolP2pSenderRequest, + ) -> MempoolP2pSenderResponse { + unimplemented!() + } +} + +#[async_trait] +impl MempoolP2pSenderClient + for LocalComponentClient +{ + async fn add_transaction( + &self, + transaction: RpcTransaction, + ) -> MempoolP2pSenderClientResult<()> { + let request = MempoolP2pSenderRequest::AddTransaction(transaction); + let response = self.send(request).await; + handle_response_variants!( + MempoolP2pSenderResponse, + AddTransaction, + MempoolP2pSenderClientError, + MempoolP2pSenderError + ) + } + + async fn continue_propagation( + &self, + propagation_manager: BroadcastedMessageManager, + ) -> MempoolP2pSenderClientResult<()> { + let request = MempoolP2pSenderRequest::ContinuePropagation(propagation_manager); + let response = self.send(request).await; + handle_response_variants!( + MempoolP2pSenderResponse, + ContinuePropagation, + MempoolP2pSenderClientError, + MempoolP2pSenderError + ) + } +} diff --git a/crates/mempool_test_utils/src/starknet_api_test_utils.rs b/crates/mempool_test_utils/src/starknet_api_test_utils.rs index 1688bc4111..32880351d7 100644 --- a/crates/mempool_test_utils/src/starknet_api_test_utils.rs +++ b/crates/mempool_test_utils/src/starknet_api_test_utils.rs @@ -14,7 +14,6 @@ use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::executable_transaction::{InvokeTransaction, Transaction}; use starknet_api::rpc_transaction::{ ContractClass, - ResourceBoundsMapping, RpcDeclareTransactionV3, RpcDeployAccountTransactionV3, RpcInvokeTransactionV3, @@ -22,15 +21,16 @@ use starknet_api::rpc_transaction::{ }; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, - DeprecatedResourceBoundsMapping as ExecutableResourceBoundsMapping, PaymasterData, ResourceBounds, Tip, TransactionHash, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_api::{calldata, felt}; use starknet_types_core::felt::Felt; @@ -49,6 +49,8 @@ pub const VALID_L1_GAS_MAX_AMOUNT: u64 = 203484; pub const VALID_L1_GAS_MAX_PRICE_PER_UNIT: u128 = 100000000000; pub const VALID_L2_GAS_MAX_AMOUNT: u64 = 203484; pub const VALID_L2_GAS_MAX_PRICE_PER_UNIT: u128 = 100000000000; +pub const VALID_L1_DATA_GAS_MAX_AMOUNT: u64 = 203484; +pub const VALID_L1_DATA_GAS_MAX_PRICE_PER_UNIT: u128 = 100000000000; pub const TEST_SENDER_ADDRESS: u128 = 0x1000; // Utils. @@ -60,7 +62,7 @@ pub enum TransactionType { pub fn rpc_tx_for_testing( tx_type: TransactionType, - resource_bounds: ResourceBoundsMapping, + resource_bounds: AllResourceBounds, calldata: Calldata, signature: TransactionSignature, ) -> RpcTransaction { @@ -80,15 +82,15 @@ pub fn rpc_tx_for_testing( ], ..Default::default() }; - external_declare_tx(declare_tx_args!(resource_bounds, signature, contract_class)) + rpc_declare_tx(declare_tx_args!(resource_bounds, signature, contract_class)) } - TransactionType::DeployAccount => external_deploy_account_tx(deploy_account_tx_args!( + TransactionType::DeployAccount => rpc_deploy_account_tx(deploy_account_tx_args!( resource_bounds, constructor_calldata: calldata, signature )), TransactionType::Invoke => { - external_invoke_tx(invoke_tx_args!(signature, resource_bounds, calldata)) + rpc_invoke_tx(invoke_tx_args!(signature, resource_bounds, calldata)) } } } @@ -96,18 +98,24 @@ pub fn rpc_tx_for_testing( pub const NON_EMPTY_RESOURCE_BOUNDS: ResourceBounds = ResourceBounds { max_amount: 1, max_price_per_unit: 1 }; +// TODO(Nimrod): Delete this function. pub fn create_resource_bounds_mapping( l1_resource_bounds: ResourceBounds, l2_resource_bounds: ResourceBounds, -) -> ResourceBoundsMapping { - ResourceBoundsMapping { l1_gas: l1_resource_bounds, l2_gas: l2_resource_bounds } + l1_data_resource_bounds: ResourceBounds, +) -> AllResourceBounds { + AllResourceBounds { + l1_gas: l1_resource_bounds, + l2_gas: l2_resource_bounds, + l1_data_gas: l1_data_resource_bounds, + } } -pub fn zero_resource_bounds_mapping() -> ResourceBoundsMapping { - create_resource_bounds_mapping(ResourceBounds::default(), ResourceBounds::default()) +pub fn zero_resource_bounds_mapping() -> AllResourceBounds { + AllResourceBounds::default() } -pub fn test_resource_bounds_mapping() -> ResourceBoundsMapping { +pub fn test_resource_bounds_mapping() -> AllResourceBounds { create_resource_bounds_mapping( ResourceBounds { max_amount: VALID_L1_GAS_MAX_AMOUNT, @@ -117,6 +125,10 @@ pub fn test_resource_bounds_mapping() -> ResourceBoundsMapping { max_amount: VALID_L2_GAS_MAX_AMOUNT, max_price_per_unit: VALID_L2_GAS_MAX_PRICE_PER_UNIT, }, + ResourceBounds { + max_amount: VALID_L1_DATA_GAS_MAX_AMOUNT, + max_price_per_unit: VALID_L1_DATA_GAS_MAX_PRICE_PER_UNIT, + }, ) } @@ -143,7 +155,7 @@ pub fn declare_tx() -> RpcTransaction { let mut nonce_manager = NonceManager::default(); let nonce = nonce_manager.next(account_address); - external_declare_tx(declare_tx_args!( + rpc_declare_tx(declare_tx_args!( signature: TransactionSignature(vec![Felt::ZERO]), sender_address: account_address, resource_bounds: test_resource_bounds_mapping(), @@ -268,7 +280,7 @@ impl AccountTransactionGenerator { nonce: self.next_nonce(), calldata: create_trivial_calldata(self.test_contract_address()), ); - external_invoke_tx(invoke_args) + rpc_invoke_tx(invoke_args) } pub fn generate_default_deploy_account(&mut self) -> RpcTransaction { @@ -280,7 +292,7 @@ impl AccountTransactionGenerator { class_hash: self.account.get_class_hash(), resource_bounds: test_resource_bounds_mapping() ); - external_deploy_account_tx(deploy_account_args) + rpc_deploy_account_tx(deploy_account_args) } // TODO: support more contracts, instead of this hardcoded type. @@ -299,7 +311,7 @@ impl AccountTransactionGenerator { /// Note: This is a best effort attempt to make the API more useful; amend or add new methods /// as needed. pub fn generate_raw(&mut self, invoke_tx_args: InvokeTxArgs) -> RpcTransaction { - external_invoke_tx(invoke_tx_args) + rpc_invoke_tx(invoke_tx_args) } pub fn sender_address(&mut self) -> ContractAddress { @@ -369,7 +381,7 @@ pub struct InvokeTxArgs { pub sender_address: ContractAddress, pub calldata: Calldata, pub version: TransactionVersion, - pub resource_bounds: ResourceBoundsMapping, + pub resource_bounds: AllResourceBounds, pub tip: Tip, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, @@ -400,7 +412,7 @@ impl Default for InvokeTxArgs { pub struct DeployAccountTxArgs { pub signature: TransactionSignature, pub version: TransactionVersion, - pub resource_bounds: ResourceBoundsMapping, + pub resource_bounds: AllResourceBounds, pub tip: Tip, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, @@ -434,7 +446,7 @@ pub struct DeclareTxArgs { pub signature: TransactionSignature, pub sender_address: ContractAddress, pub version: TransactionVersion, - pub resource_bounds: ResourceBoundsMapping, + pub resource_bounds: AllResourceBounds, pub tip: Tip, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, @@ -464,7 +476,7 @@ impl Default for DeclareTxArgs { } } -pub fn external_invoke_tx(invoke_args: InvokeTxArgs) -> RpcTransaction { +pub fn rpc_invoke_tx(invoke_args: InvokeTxArgs) -> RpcTransaction { if invoke_args.version != TransactionVersion::THREE { panic!("Unsupported transaction version: {:?}.", invoke_args.version); } @@ -485,7 +497,7 @@ pub fn external_invoke_tx(invoke_args: InvokeTxArgs) -> RpcTransaction { ) } -pub fn external_deploy_account_tx(deploy_tx_args: DeployAccountTxArgs) -> RpcTransaction { +pub fn rpc_deploy_account_tx(deploy_tx_args: DeployAccountTxArgs) -> RpcTransaction { if deploy_tx_args.version != TransactionVersion::THREE { panic!("Unsupported transaction version: {:?}.", deploy_tx_args.version); } @@ -508,7 +520,7 @@ pub fn external_deploy_account_tx(deploy_tx_args: DeployAccountTxArgs) -> RpcTra ) } -pub fn external_declare_tx(declare_tx_args: DeclareTxArgs) -> RpcTransaction { +pub fn rpc_declare_tx(declare_tx_args: DeclareTxArgs) -> RpcTransaction { if declare_tx_args.version != TransactionVersion::THREE { panic!("Unsupported transaction version: {:?}.", declare_tx_args.version); } @@ -555,7 +567,7 @@ pub fn create_executable_tx( tx_hash: TransactionHash, tip: Tip, nonce: Nonce, - resource_bounds: ExecutableResourceBoundsMapping, + resource_bounds: ValidResourceBounds, ) -> Transaction { Transaction::Invoke(InvokeTransaction { tx: starknet_api::transaction::InvokeTransaction::V3( diff --git a/crates/mempool_types/src/communication.rs b/crates/mempool_types/src/communication.rs index f3f74665ee..7956ad8235 100644 --- a/crates/mempool_types/src/communication.rs +++ b/crates/mempool_types/src/communication.rs @@ -30,6 +30,8 @@ pub type SharedMempoolClient = Arc; #[automock] #[async_trait] pub trait MempoolClient: Send + Sync { + // TODO: Add Option as an argument for add_transaction + // TODO: Rename tx to transaction async fn add_tx(&self, mempool_input: MempoolInput) -> MempoolClientResult<()>; async fn get_txs(&self, n_txs: usize) -> MempoolClientResult>; } diff --git a/crates/native_blockifier/src/py_block_executor.rs b/crates/native_blockifier/src/py_block_executor.rs index eb4832282e..841619756c 100644 --- a/crates/native_blockifier/src/py_block_executor.rs +++ b/crates/native_blockifier/src/py_block_executor.rs @@ -52,21 +52,14 @@ pub(crate) struct ThinTransactionExecutionInfo { } impl ThinTransactionExecutionInfo { - pub fn from_tx_execution_info( - block_context: &BlockContext, - tx_execution_info: TransactionExecutionInfo, - ) -> Self { + pub fn from_tx_execution_info(tx_execution_info: TransactionExecutionInfo) -> Self { Self { validate_call_info: tx_execution_info.validate_call_info, execute_call_info: tx_execution_info.execute_call_info, fee_transfer_call_info: tx_execution_info.fee_transfer_call_info, actual_fee: tx_execution_info.receipt.fee, da_gas: tx_execution_info.receipt.da_gas, - actual_resources: tx_execution_info.receipt.resources.to_resources_mapping( - block_context.versioned_constants(), - block_context.block_info().use_kzg_da, - true, - ), + actual_resources: tx_execution_info.receipt.to_resources_mapping(true), revert_error: tx_execution_info.revert_error, total_gas: tx_execution_info.receipt.gas, } @@ -167,10 +160,8 @@ impl PyBlockExecutor { ) -> NativeBlockifierResult> { let tx: Transaction = py_tx(tx, optional_py_class_info).expect(PY_TX_PARSING_ERR); let tx_execution_info = self.tx_executor().execute(&tx)?; - let thin_tx_execution_info = ThinTransactionExecutionInfo::from_tx_execution_info( - &self.tx_executor().block_context, - tx_execution_info, - ); + let thin_tx_execution_info = + ThinTransactionExecutionInfo::from_tx_execution_info(tx_execution_info); // Serialize and convert to PyBytes. let serialized_tx_execution_info = thin_tx_execution_info.serialize(); @@ -199,7 +190,6 @@ impl PyBlockExecutor { // Process results. // TODO(Yoni, 15/5/2024): serialize concurrently. - let block_context = &self.tx_executor().block_context; let serialized_results: Vec<(bool, RawTransactionExecutionResult)> = results .into_iter() // Note: there might be less results than txs (if there is no room for all of them). @@ -207,7 +197,6 @@ impl PyBlockExecutor { Ok(tx_execution_info) => ( true, ThinTransactionExecutionInfo::from_tx_execution_info( - block_context, tx_execution_info, ) .serialize(), diff --git a/crates/native_blockifier/src/py_declare.rs b/crates/native_blockifier/src/py_declare.rs index 9e01caaaaf..b8d74535f0 100644 --- a/crates/native_blockifier/src/py_declare.rs +++ b/crates/native_blockifier/src/py_declare.rs @@ -10,7 +10,6 @@ use starknet_api::transaction::{ DeclareTransactionV0V1, DeclareTransactionV2, DeclareTransactionV3, - DeprecatedResourceBoundsMapping, Fee, PaymasterData, Tip, @@ -88,7 +87,7 @@ impl TryFrom for DeclareTransactionV3 { type Error = NativeBlockifierInputError; fn try_from(tx: PyDeclareTransactionV3) -> Result { Ok(Self { - resource_bounds: DeprecatedResourceBoundsMapping::try_from(tx.resource_bounds)?, + resource_bounds: tx.resource_bounds.try_into()?, tip: Tip(tx.tip), signature: TransactionSignature(from_py_felts(tx.signature)), nonce: Nonce(tx.nonce.0), diff --git a/crates/native_blockifier/src/py_deploy_account.rs b/crates/native_blockifier/src/py_deploy_account.rs index a5671842a0..b25b464103 100644 --- a/crates/native_blockifier/src/py_deploy_account.rs +++ b/crates/native_blockifier/src/py_deploy_account.rs @@ -10,7 +10,6 @@ use starknet_api::transaction::{ ContractAddressSalt, DeployAccountTransactionV1, DeployAccountTransactionV3, - DeprecatedResourceBoundsMapping, Fee, PaymasterData, Tip, @@ -64,7 +63,7 @@ impl TryFrom for DeployAccountTransactionV3 { type Error = NativeBlockifierInputError; fn try_from(tx: PyDeployAccountTransactionV3) -> Result { Ok(Self { - resource_bounds: DeprecatedResourceBoundsMapping::try_from(tx.resource_bounds)?, + resource_bounds: tx.resource_bounds.try_into()?, tip: Tip(tx.tip), signature: TransactionSignature(from_py_felts(tx.signature)), nonce: Nonce(tx.nonce.0), diff --git a/crates/native_blockifier/src/py_invoke_function.rs b/crates/native_blockifier/src/py_invoke_function.rs index 64f7559917..974d0b9b1d 100644 --- a/crates/native_blockifier/src/py_invoke_function.rs +++ b/crates/native_blockifier/src/py_invoke_function.rs @@ -9,7 +9,6 @@ use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::transaction::{ AccountDeploymentData, Calldata, - DeprecatedResourceBoundsMapping, Fee, InvokeTransactionV0, InvokeTransactionV1, @@ -87,7 +86,7 @@ impl TryFrom for InvokeTransactionV3 { type Error = NativeBlockifierInputError; fn try_from(tx: PyInvokeTransactionV3) -> Result { Ok(Self { - resource_bounds: DeprecatedResourceBoundsMapping::try_from(tx.resource_bounds)?, + resource_bounds: tx.resource_bounds.try_into()?, tip: Tip(tx.tip), signature: TransactionSignature(from_py_felts(tx.signature)), nonce: Nonce(tx.nonce.0), diff --git a/crates/native_blockifier/src/py_state_diff.rs b/crates/native_blockifier/src/py_state_diff.rs index fb71058e88..4aba1bc291 100644 --- a/crates/native_blockifier/src/py_state_diff.rs +++ b/crates/native_blockifier/src/py_state_diff.rs @@ -162,9 +162,9 @@ impl Default for PyBlockInfo { }, l2_gas_price: PyResourcePrice { price_in_wei: VersionedConstants::latest_constants() - .l1_to_l2_gas_price_conversion(DEFAULT_ETH_L1_GAS_PRICE), + .convert_l1_to_l2_gas(DEFAULT_ETH_L1_GAS_PRICE), price_in_fri: VersionedConstants::latest_constants() - .l1_to_l2_gas_price_conversion(DEFAULT_STRK_L1_GAS_PRICE), + .convert_l1_to_l2_gas(DEFAULT_STRK_L1_GAS_PRICE), }, sequencer_address: PyFelt::default(), use_kzg_da: bool::default(), diff --git a/crates/native_blockifier/src/py_transaction.rs b/crates/native_blockifier/src/py_transaction.rs index 443ed57c90..708c8499b8 100644 --- a/crates/native_blockifier/src/py_transaction.rs +++ b/crates/native_blockifier/src/py_transaction.rs @@ -11,7 +11,12 @@ use blockifier::transaction::transaction_execution::Transaction; use blockifier::transaction::transaction_types::TransactionType; use pyo3::exceptions::PyValueError; use pyo3::prelude::*; -use starknet_api::transaction::{Resource, ResourceBounds}; +use starknet_api::transaction::{ + DeprecatedResourceBoundsMapping, + Resource, + ResourceBounds, + ValidResourceBounds, +}; use starknet_api::StarknetApiError; use crate::errors::{NativeBlockifierInputError, NativeBlockifierResult}; @@ -68,19 +73,17 @@ impl From for starknet_api::transaction::ResourceBounds { #[derive(Clone, FromPyObject)] pub struct PyResourceBoundsMapping(pub BTreeMap); -impl TryFrom - for starknet_api::transaction::DeprecatedResourceBoundsMapping -{ +impl TryFrom for ValidResourceBounds { type Error = StarknetApiError; fn try_from(py_resource_bounds_mapping: PyResourceBoundsMapping) -> Result { - let resource_bounds_vec: Vec<(Resource, ResourceBounds)> = py_resource_bounds_mapping + let map = py_resource_bounds_mapping .0 .into_iter() .map(|(py_resource_type, py_resource_bounds)| { (Resource::from(py_resource_type), ResourceBounds::from(py_resource_bounds)) }) .collect(); - Self::try_from(resource_bounds_vec) + DeprecatedResourceBoundsMapping(map).try_into() } } diff --git a/crates/papyrus_base_layer/Cargo.toml b/crates/papyrus_base_layer/Cargo.toml index 3cd7a533f7..426f6a3e7a 100644 --- a/crates/papyrus_base_layer/Cargo.toml +++ b/crates/papyrus_base_layer/Cargo.toml @@ -18,10 +18,10 @@ tokio = { workspace = true, features = ["full", "sync"] } url.workspace = true [dev-dependencies] -ethers-core = { version = "2.0.3" } +ethers-core.workspace = true pretty_assertions.workspace = true starknet-types-core.workspace = true starknet_api = { workspace = true, features = ["testing"] } -tar = { version = "0.4.38" } +tar.workspace = true tempfile.workspace = true -test-with = { version = "0.9.3", default-features = false, features = ["executable"] } +test-with = { workspace = true, default-features = false, features = ["executable"] } diff --git a/crates/papyrus_common/Cargo.toml b/crates/papyrus_common/Cargo.toml index b13070dafe..7ff451e872 100644 --- a/crates/papyrus_common/Cargo.toml +++ b/crates/papyrus_common/Cargo.toml @@ -10,7 +10,6 @@ description = "Common utils and objects for a Starknet node." cairo-lang-starknet-classes.workspace = true hex.workspace = true indexmap.workspace = true -itertools.workspace = true lazy_static.workspace = true rand.workspace = true serde.workspace = true @@ -18,7 +17,6 @@ serde_json.workspace = true sha3.workspace = true starknet-types-core = { workspace = true, features = ["hash"] } starknet_api.workspace = true -thiserror.workspace = true [dev-dependencies] assert_matches.workspace = true diff --git a/crates/papyrus_common/src/block_hash.rs b/crates/papyrus_common/src/block_hash.rs deleted file mode 100644 index eaee133485..0000000000 --- a/crates/papyrus_common/src/block_hash.rs +++ /dev/null @@ -1,216 +0,0 @@ -#[cfg(test)] -#[path = "block_hash_test.rs"] -mod block_hash_test; - -use std::iter::zip; - -use starknet_api::block::{BlockBody, BlockHash, BlockHeader}; -use starknet_api::core::{ - ChainId, - EventCommitment, - SequencerContractAddress, - TransactionCommitment, -}; -use starknet_api::crypto::patricia_hash::calculate_root; -use starknet_api::hash::StarkHash; -use starknet_api::transaction::{ - DeployAccountTransaction, - Event, - Transaction, - TransactionHash, - TransactionOutput, -}; -use starknet_api::StarknetApiError; -use starknet_types_core::felt::Felt; -use starknet_types_core::hash::{Pedersen, StarkHash as CoreStarkHash}; - -use crate::transaction_hash::{ascii_as_felt, HashChain, ZERO}; -use crate::usize_into_felt; - -#[derive(Debug, thiserror::Error)] -pub enum BlockHashError { - #[error("Header is missing data (transaction_commitment / event_commitment)")] - MissingHeaderData, - #[error(transparent)] - StarknetApiError(#[from] StarknetApiError), -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] -enum BlockHashVersion { - V0, - V1, - V2, - V3, -} - -/// Validates hash of a starknet header. -/// A hash is valid if it is the result of one of the hash functions that were ever used in -/// Starknet. -pub fn validate_header(header: &BlockHeader, chain_id: &ChainId) -> Result { - for version in - [BlockHashVersion::V3, BlockHashVersion::V2, BlockHashVersion::V1, BlockHashVersion::V0] - { - if calculate_block_hash_by_version(header, version, chain_id)? == header.block_hash { - return Ok(true); - } - } - Ok(false) -} - -/// Validates the body of a starknet block. -pub fn validate_body( - body: &BlockBody, - transaction_commitment: &TransactionCommitment, - event_commitment: &EventCommitment, -) -> Result { - for version in - [BlockHashVersion::V3, BlockHashVersion::V2, BlockHashVersion::V1, BlockHashVersion::V0] - { - let calculated_transaction_commitment = - calculate_transaction_commitment_by_version(body, &version)?; - if calculated_transaction_commitment != *transaction_commitment { - continue; - } - let calculated_event_commitment = - calculate_event_commitment_by_version(&body.transaction_outputs, &version); - if calculated_event_commitment != *event_commitment { - continue; - } - return Ok(true); - } - Ok(false) -} - -// Calculates hash of a starknet block by version, ignoring the block hash field in the given block. -fn calculate_block_hash_by_version( - header: &BlockHeader, - version: BlockHashVersion, - chain_id: &ChainId, -) -> Result { - // Can't implement as a closure because ascii_as_felt returns a Result. - let chain_id_as_felt = if version == BlockHashVersion::V0 { - Some(ascii_as_felt(chain_id.to_string().as_str())?) - } else { - None - }; - - Ok(BlockHash( - HashChain::new() - .chain(&header.block_number.0.into()) - .chain(&header.state_root.0) - .chain_if_fn( - || { - if header.sequencer != SequencerContractAddress::default() || version != BlockHashVersion::V2 { - return Some(*header.sequencer.0.key()); - } - // V2 block with no sequencer address. - Some(get_chain_sequencer_address(chain_id)) - } - ) - .chain_if_fn(|| { - if version >= BlockHashVersion::V1 { - Some(header.timestamp.0.into()) - } else { - Some(*ZERO) - } - }) - .chain(&usize_into_felt(header.n_transactions)) - .chain(&header.transaction_commitment.ok_or(BlockHashError::MissingHeaderData)?.0) - .chain(&usize_into_felt(header.n_events)) - .chain(&header.event_commitment.ok_or(BlockHashError::MissingHeaderData)?.0) - .chain(&ZERO) // Not implemented Element. - .chain(&ZERO) // Not implemented Element. - .chain_if_fn(|| { - chain_id_as_felt - }) - - .chain(&header.parent_hash.0).get_pedersen_hash(), - )) -} - -// Returns the transaction commitment. -fn calculate_transaction_commitment_by_version( - block_body: &BlockBody, - version: &BlockHashVersion, -) -> Result { - let transaction_patricia_leaves = - zip(block_body.transactions.iter(), block_body.transaction_hashes.iter()) - .map(|(transaction, transaction_hash)| { - get_transaction_leaf(transaction, transaction_hash, version) - }) - .collect::, _>>()?; - let transactions_patricia_root = calculate_root::(transaction_patricia_leaves); - Ok(TransactionCommitment(transactions_patricia_root)) -} - -// Returns a Patricia leaf value for a transaction. -fn get_transaction_leaf( - transaction: &Transaction, - transaction_hash: &TransactionHash, - version: &BlockHashVersion, -) -> Result { - let signature = if version >= &BlockHashVersion::V3 { - get_transaction_signature(transaction) - } else { - get_signature_only_from_invoke(transaction) - }; - let signature_hash = HashChain::new().chain_iter(signature.iter()).get_pedersen_hash(); - Ok(Pedersen::hash(&transaction_hash.0, &signature_hash)) -} - -fn get_transaction_signature(transaction: &Transaction) -> Vec { - match transaction { - Transaction::Declare(declare) => declare.signature().0, - Transaction::Deploy(_) => vec![], - Transaction::DeployAccount(deploy_account) => match deploy_account { - DeployAccountTransaction::V1(deploy_account_v1) => { - deploy_account_v1.signature.0.to_owned() - } - DeployAccountTransaction::V3(deploy_account_v3) => { - deploy_account_v3.signature.0.to_owned() - } - }, - Transaction::Invoke(invoke) => invoke.signature().0, - Transaction::L1Handler(_) => vec![], - } -} - -fn get_signature_only_from_invoke(transaction: &Transaction) -> Vec { - if let Transaction::Invoke(invoke) = transaction { invoke.signature().0 } else { vec![] } -} - -// Returns the number of the events, and the Patricia root of the events. -fn calculate_event_commitment_by_version( - transaction_outputs: &[TransactionOutput], - version: &BlockHashVersion, -) -> EventCommitment { - if version < &BlockHashVersion::V1 { - return EventCommitment(*ZERO); - } - let event_patricia_leaves: Vec<_> = - transaction_outputs.iter().flat_map(|output| output.events()).map(get_event_leaf).collect(); - let event_patricia_root = calculate_root::(event_patricia_leaves); - EventCommitment(event_patricia_root) -} - -// Returns a Patricia leaf value for an event. -fn get_event_leaf(event: &Event) -> StarkHash { - let event_keys: Vec<_> = event.content.keys.iter().map(|key| key.0).collect(); - HashChain::new() - .chain(event.from_address.0.key()) - .chain(&HashChain::new().chain_iter(event_keys.iter()).get_pedersen_hash()) - .chain(&HashChain::new().chain_iter(event.content.data.0.iter()).get_pedersen_hash()) - .get_pedersen_hash() -} - -// The fixed sequencer addresses of the chains that have historic blocks with block hash version 2. -fn get_chain_sequencer_address(chain_id: &ChainId) -> StarkHash { - match chain_id { - ChainId::Mainnet => StarkHash::from_hex_unchecked( - "0x021f4b90b0377c82bf330b7b5295820769e72d79d8acd0effa0ebde6e9988bc5", - ), - // TODO(yoav): Add sequencers for the rest of the supported chains that have historic blocks - // with block hash version 2. - _ => unimplemented!("Sequencer address for chain"), - } -} diff --git a/crates/papyrus_common/src/block_hash_test.rs b/crates/papyrus_common/src/block_hash_test.rs deleted file mode 100644 index 6ab92e63aa..0000000000 --- a/crates/papyrus_common/src/block_hash_test.rs +++ /dev/null @@ -1,64 +0,0 @@ -use assert_matches::assert_matches; -use papyrus_test_utils::read_json_file; -use starknet_api::block::Block; -use starknet_api::core::ChainId; - -use crate::block_hash::{ - calculate_block_hash_by_version, - calculate_event_commitment_by_version, - calculate_transaction_commitment_by_version, - BlockHashError, - BlockHashVersion, -}; - -fn validate_block_hash_util(file_name: &str, version: BlockHashVersion) { - let chain_id = ChainId::Mainnet; - let block: Block = serde_json::from_value(read_json_file(file_name)).unwrap(); - let calculated_hash = - calculate_block_hash_by_version(&block.header, version, &chain_id).unwrap(); - assert_eq!(calculated_hash, block.header.block_hash); - - let calculated_transaction_commitment = - calculate_transaction_commitment_by_version(&block.body, &version).unwrap(); - assert_eq!(calculated_transaction_commitment, block.header.transaction_commitment.unwrap()); - - let calculated_event_commitment = - calculate_event_commitment_by_version(&block.body.transaction_outputs, &version); - assert_eq!(calculated_event_commitment, block.header.event_commitment.unwrap()); -} - -#[test] -fn test_block_hash() { - validate_block_hash_util("block_hash.json", BlockHashVersion::V3); -} - -#[test] -fn test_deprecated_block_hash_v2() { - validate_block_hash_util("deprecated_block_hash_v2.json", BlockHashVersion::V2); -} - -#[test] -fn test_deprecated_block_hash_v1_no_events() { - validate_block_hash_util("deprecated_block_hash_v1_no_events.json", BlockHashVersion::V1); -} - -#[test] -fn test_deprecated_block_hash_v1() { - validate_block_hash_util("deprecated_block_hash_v1.json", BlockHashVersion::V1); -} - -#[test] -fn test_deprecated_block_hash_v0() { - validate_block_hash_util("deprecated_block_hash_v0.json", BlockHashVersion::V0); -} - -#[test] -fn test_missing_header_data() { - let chain_id = ChainId::Mainnet; - let mut block: Block = serde_json::from_value(read_json_file("block_hash.json")).unwrap(); - block.header.transaction_commitment = None; - let err = calculate_block_hash_by_version(&block.header, BlockHashVersion::V3, &chain_id) - .unwrap_err(); - - assert_matches!(err, BlockHashError::MissingHeaderData); -} diff --git a/crates/papyrus_common/src/lib.rs b/crates/papyrus_common/src/lib.rs index fb9ab6c0b0..d6d14eb69f 100644 --- a/crates/papyrus_common/src/lib.rs +++ b/crates/papyrus_common/src/lib.rs @@ -2,13 +2,11 @@ use serde::{Deserialize, Serialize}; use starknet_api::block::{BlockHash, BlockNumber}; use starknet_types_core::felt::Felt; -pub mod block_hash; pub mod class_hash; pub mod deprecated_class_abi; pub mod metrics; pub mod pending_classes; pub mod state; -pub mod state_diff_commitment; pub mod storage_query; pub mod transaction_hash; diff --git a/crates/papyrus_common/src/state_diff_commitment.rs b/crates/papyrus_common/src/state_diff_commitment.rs deleted file mode 100644 index aac2994937..0000000000 --- a/crates/papyrus_common/src/state_diff_commitment.rs +++ /dev/null @@ -1,112 +0,0 @@ -#[cfg(test)] -#[path = "state_diff_commitment_test.rs"] -mod state_diff_commitment_test; - -use itertools::Itertools; -use starknet_api::core::StateDiffCommitment; -use starknet_api::data_availability::DataAvailabilityMode; -use starknet_api::hash::PoseidonHash; -use starknet_api::state::ThinStateDiff; -use starknet_types_core::felt::Felt; -use starknet_types_core::hash::{Poseidon, StarkHash}; - -const SUPPORTED_DA_MODES_STATE_DIFF_V0: [DataAvailabilityMode; 1] = [DataAvailabilityMode::L1]; - -/// The version of the state diff for the state diff commitment. -// The version is used to support different data availability modes, currently only L1. -#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] -pub enum StateDiffVersion { - #[default] - V0, -} - -impl StateDiffVersion { - /// Returns the supported data availability modes for the given state diff version. - pub fn supported_da_modes(&self) -> Vec { - match self { - StateDiffVersion::V0 => SUPPORTED_DA_MODES_STATE_DIFF_V0.to_vec(), - } - } -} - -impl From for Felt { - fn from(version: StateDiffVersion) -> Self { - match version { - StateDiffVersion::V0 => Felt::ZERO, - } - } -} - -/// Calculates the state diff commitment. -/// The computation is described here: . -pub fn calculate_state_diff_commitment( - state_diff: &ThinStateDiff, - state_diff_version: StateDiffVersion, -) -> StateDiffCommitment { - let mut flattened_total_state_diff = vec![Felt::from(state_diff_version)]; - - // Deployed contracts and replaced classes are squashed. - // Assumption: same contract address cannot be found in deployed and replaced in the same state - // diff. - let num_deployed_contracts = - state_diff.deployed_contracts.len() + state_diff.replaced_classes.len(); - let deployed_contracts_iter = state_diff - .deployed_contracts - .iter() - .chain(state_diff.replaced_classes.iter()) - .sorted_by_key(|(contract_address, _)| *contract_address); - let mut flattened_deployed_contracts = vec![Felt::from(num_deployed_contracts as u64)]; - for (contract_address, class_hash) in deployed_contracts_iter { - flattened_deployed_contracts.push(*contract_address.0.key()); - flattened_deployed_contracts.push(class_hash.0); - } - let hash_of_deployed_contracts = Poseidon::hash_array(&flattened_deployed_contracts); - flattened_total_state_diff.push(hash_of_deployed_contracts); - - let mut flattened_declared_classes = vec![Felt::from(state_diff.declared_classes.len() as u64)]; - for (class_hash, compiled_class_hash) in &state_diff.declared_classes { - flattened_declared_classes.push(class_hash.0); - flattened_declared_classes.push(compiled_class_hash.0); - } - let hash_of_declared_classes = Poseidon::hash_array(&flattened_declared_classes); - flattened_total_state_diff.push(hash_of_declared_classes); - - let mut flattened_deprecated_declared_classes = - vec![Felt::from(state_diff.deprecated_declared_classes.len() as u64)]; - for class_hash in &state_diff.deprecated_declared_classes { - flattened_deprecated_declared_classes.push(class_hash.0); - } - let hash_of_deprecated_declared_classes = - Poseidon::hash_array(&flattened_deprecated_declared_classes); - flattened_total_state_diff.push(hash_of_deprecated_declared_classes); - - let da_modes = state_diff_version.supported_da_modes(); - flattened_total_state_diff.push(Felt::from(da_modes.len() as u64)); - - for da_mode in da_modes { - flattened_total_state_diff.push(Felt::from(da_mode)); - // When more data availability modes are added, the following code should be updated so that - // only the data of the current mode is included. - let mut flattened_storage_diffs = vec![Felt::from(state_diff.storage_diffs.len() as u64)]; - for (contract_address, diffs) in &state_diff.storage_diffs { - flattened_storage_diffs.push(*contract_address.0.key()); - flattened_storage_diffs.push(Felt::from(diffs.len() as u64)); - for (key, value) in diffs { - flattened_storage_diffs.push(*key.0.key()); - flattened_storage_diffs.push(*value); - } - } - let mut flattened_nonces = vec![Felt::from(state_diff.nonces.len() as u64)]; - for (contract_address, nonce) in &state_diff.nonces { - flattened_nonces.push(*contract_address.0.key()); - flattened_nonces.push(nonce.0); - } - let storage_diffs_and_nonces: Vec<_> = - flattened_storage_diffs.into_iter().chain(flattened_nonces).collect(); - let hash_of_storage_domain_state_diff = - Poseidon::hash_array(storage_diffs_and_nonces.as_slice()); - flattened_total_state_diff.push(hash_of_storage_domain_state_diff); - } - - StateDiffCommitment(PoseidonHash(Poseidon::hash_array(flattened_total_state_diff.as_slice()))) -} diff --git a/crates/papyrus_common/src/state_diff_commitment_test.rs b/crates/papyrus_common/src/state_diff_commitment_test.rs deleted file mode 100644 index c49142367f..0000000000 --- a/crates/papyrus_common/src/state_diff_commitment_test.rs +++ /dev/null @@ -1,85 +0,0 @@ -use pretty_assertions::assert_eq; -use starknet_api::core::{ - ClassHash, - CompiledClassHash, - ContractAddress, - Nonce, - PatriciaKey, - StateDiffCommitment, -}; -use starknet_api::hash::PoseidonHash; -use starknet_api::state::{StateDiff, StorageKey, ThinStateDiff}; -use starknet_api::{class_hash, contract_address, felt, patricia_key}; - -use crate::state_diff_commitment::{calculate_state_diff_commitment, StateDiffVersion}; - -#[test] -fn state_diff_commitment() { - let contract_address = contract_address!("0x1"); - let storage_key = StorageKey(patricia_key!("0x1")); - let storage_value = felt!("0x999"); - let nonce = Nonce(felt!("0x1")); - let class_hash = class_hash!("0x70"); - let compiled_class_hash = CompiledClassHash(felt!("0x700")); - let old_class_hash = class_hash!("0x71"); - let replaced_contract_address = contract_address!("0x2"); - let replacing_class_hash = class_hash!("0x72"); - - let thin_state_diff = ThinStateDiff { - deployed_contracts: [(contract_address, class_hash)].into(), - storage_diffs: [(contract_address, [(storage_key, storage_value)].into())].into(), - declared_classes: [(class_hash, compiled_class_hash)].into(), - deprecated_declared_classes: vec![old_class_hash], - nonces: [(contract_address, nonce)].into(), - replaced_classes: [(replaced_contract_address, replacing_class_hash)].into(), - }; - - let calculated_commitment = - calculate_state_diff_commitment(&thin_state_diff, StateDiffVersion::V0); - - // The expected commitment was calculated using the Python implementation of Starknet. - let expected_commitment = StateDiffCommitment(PoseidonHash(felt!( - "0x30eec29bb733bc07197b0e0a41a53808860b2bf9dbb6b4472677a9fc6168a4f" - ))); - - assert_eq!(calculated_commitment, expected_commitment); -} - -#[test] -fn empty_storage_diff() { - // TODO: derive default in ThinStateDiff. - let state_diff = ThinStateDiff::from(StateDiff::default()); - let state_diff_with_empty_storage_diff = ThinStateDiff::from(StateDiff { - storage_diffs: [(ContractAddress::default(), [].into())].into(), - ..Default::default() - }); - - assert_ne!( - calculate_state_diff_commitment(&state_diff, StateDiffVersion::V0), - calculate_state_diff_commitment(&state_diff_with_empty_storage_diff, StateDiffVersion::V0) - ); -} - -#[test] -fn deployed_and_replaced_contracts_are_sorted_for_hashing() { - // Tests a bug fix where the squashing of deployed and replaced contracts was not sorted by - // contract address. - let state_diff = ThinStateDiff { - deployed_contracts: [(contract_address!("0x2"), class_hash!("0x2"))].into(), - storage_diffs: [].into(), - declared_classes: [].into(), - deprecated_declared_classes: [].into(), - nonces: [].into(), - replaced_classes: [ - (contract_address!("0x1"), class_hash!("0x1")), - (contract_address!("0x3"), class_hash!("0x3")), - ] - .into(), - }; - - let calculated_commitment = calculate_state_diff_commitment(&state_diff, StateDiffVersion::V0); - assert_eq!( - calculated_commitment.0.0.to_hex_string(), - "0x5264ab018246d1ab06704c6016285e90962e843561ebb82c4325d7254b1724b" - ); -} diff --git a/crates/papyrus_common/src/transaction_hash.rs b/crates/papyrus_common/src/transaction_hash.rs index 6b4da55441..927455a7f3 100644 --- a/crates/papyrus_common/src/transaction_hash.rs +++ b/crates/papyrus_common/src/transaction_hash.rs @@ -16,18 +16,17 @@ use starknet_api::transaction::{ DeployAccountTransactionV1, DeployAccountTransactionV3, DeployTransaction, - DeprecatedResourceBoundsMapping, InvokeTransaction, InvokeTransactionV0, InvokeTransactionV1, InvokeTransactionV3, L1HandlerTransaction, - Resource, ResourceBounds, Tip, Transaction, TransactionHash, TransactionVersion, + ValidResourceBounds, }; use starknet_api::StarknetApiError; use starknet_types_core::felt::Felt; @@ -151,6 +150,7 @@ fn get_deprecated_transaction_hashes( } /// Validates the hash of a starknet transaction. +/// /// For transactions on testnet or those with a low block_number, we validate the /// transaction hash against all potential historical hash computations. For recent /// transactions on mainnet, the hash is validated by calculating the precise hash @@ -220,16 +220,14 @@ pub(crate) fn ascii_as_felt(ascii_str: &str) -> Result { // An implementation of the SNIP: https://github.com/EvyatarO/SNIPs/blob/snip-8/SNIPS/snip-8.md fn get_tip_resource_bounds_hash( - resource_bounds_mapping: &DeprecatedResourceBoundsMapping, + resource_bounds: &ValidResourceBounds, tip: &Tip, ) -> Result { - let l1_resource_bounds = - resource_bounds_mapping.0.get(&Resource::L1Gas).expect("Missing l1 resource"); - let l1_resource = get_concat_resource(l1_resource_bounds, L1_GAS)?; + let l1_resource_bounds = resource_bounds.get_l1_bounds(); + let l2_resource_bounds = resource_bounds.get_l2_bounds(); - let l2_resource_bounds = - resource_bounds_mapping.0.get(&Resource::L2Gas).expect("Missing l2 resource"); - let l2_resource = get_concat_resource(l2_resource_bounds, L2_GAS)?; + let l1_resource = get_concat_resource(&l1_resource_bounds, L1_GAS)?; + let l2_resource = get_concat_resource(&l2_resource_bounds, L2_GAS)?; Ok(HashChain::new() .chain(&tip.0.into()) diff --git a/crates/papyrus_execution/resources/versioned_constants_13_0.json b/crates/papyrus_execution/resources/versioned_constants_13_0.json deleted file mode 100644 index da35da1279..0000000000 --- a/crates/papyrus_execution/resources/versioned_constants_13_0.json +++ /dev/null @@ -1,532 +0,0 @@ -{ - "gateway": { - "max_calldata_length": 4000, - "max_contract_bytecode_size": 61440 - }, - "invoke_tx_max_n_steps": 3000000, - "max_recursion_depth": 50, - "os_constants": { - "block_hash_contract_address": 1, - "call_contract_gas_cost": { - "entry_point_gas_cost": 1, - "step_gas_cost": 10, - "syscall_base_gas_cost": 1 - }, - "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", - "default_entry_point_selector": 0, - "deploy_gas_cost": { - "entry_point_gas_cost": 1, - "step_gas_cost": 200, - "syscall_base_gas_cost": 1 - }, - "emit_event_gas_cost": { - "step_gas_cost": 10, - "syscall_base_gas_cost": 1 - }, - "entry_point_gas_cost": { - "entry_point_initial_budget": 1, - "step_gas_cost": 500 - }, - "entry_point_initial_budget": { - "step_gas_cost": 100 - }, - "entry_point_type_constructor": 2, - "entry_point_type_external": 0, - "entry_point_type_l1_handler": 1, - "error_block_number_out_of_range": "Block number out of range", - "error_invalid_argument": "Invalid argument", - "error_invalid_input_len": "Invalid input length", - "error_out_of_gas": "Out of gas", - "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", - "fee_transfer_gas_cost": { - "entry_point_gas_cost": 1, - "step_gas_cost": 100 - }, - "get_block_hash_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "get_execution_info_gas_cost": { - "step_gas_cost": 10, - "syscall_base_gas_cost": 1 - }, - "initial_gas_cost": { - "step_gas_cost": 100000000 - }, - "keccak_gas_cost": { - "syscall_base_gas_cost": 1 - }, - "keccak_round_cost_gas_cost": 180000, - "l1_gas": "L1_GAS", - "l1_gas_index": 0, - "l1_handler_version": 0, - "l2_gas": "L2_GAS", - "l2_gas_index": 1, - "library_call_gas_cost": { - "call_contract_gas_cost": 1 - }, - "memory_hole_gas_cost": 10, - "nop_entry_point_offset": -1, - "range_check_gas_cost": 70, - "replace_class_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "secp256k1_add_gas_cost": { - "range_check_gas_cost": 29, - "step_gas_cost": 406 - }, - "secp256k1_get_point_from_x_gas_cost": { - "memory_hole_gas_cost": 20, - "range_check_gas_cost": 30, - "step_gas_cost": 391 - }, - "secp256k1_get_xy_gas_cost": { - "memory_hole_gas_cost": 40, - "range_check_gas_cost": 11, - "step_gas_cost": 239 - }, - "secp256k1_mul_gas_cost": { - "range_check_gas_cost": 7045, - "step_gas_cost": 76401 - }, - "secp256k1_new_gas_cost": { - "memory_hole_gas_cost": 40, - "range_check_gas_cost": 35, - "step_gas_cost": 475 - }, - "secp256r1_add_gas_cost": { - "range_check_gas_cost": 57, - "step_gas_cost": 589 - }, - "secp256r1_get_point_from_x_gas_cost": { - "memory_hole_gas_cost": 20, - "range_check_gas_cost": 44, - "step_gas_cost": 510 - }, - "secp256r1_get_xy_gas_cost": { - "memory_hole_gas_cost": 40, - "range_check_gas_cost": 11, - "step_gas_cost": 241 - }, - "secp256r1_mul_gas_cost": { - "range_check_gas_cost": 13961, - "step_gas_cost": 125240 - }, - "secp256r1_new_gas_cost": { - "memory_hole_gas_cost": 40, - "range_check_gas_cost": 49, - "step_gas_cost": 594 - }, - "send_message_to_l1_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "sha256_process_block_gas_cost": { - "range_check_gas_cost": 0, - "step_gas_cost": 0, - "syscall_base_gas_cost": 0 - }, - "sierra_array_len_bound": 4294967296, - "step_gas_cost": 100, - "storage_read_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "storage_write_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "stored_block_hash_buffer": 10, - "syscall_base_gas_cost": { - "step_gas_cost": 100 - }, - "transaction_gas_cost": { - "entry_point_gas_cost": 2, - "fee_transfer_gas_cost": 1, - "step_gas_cost": 100 - }, - "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", - "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", - "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", - "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", - "validated": "VALID" - }, - "os_resources": { - "compute_os_kzg_commitment_info": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "execute_syscalls": { - "CallContract": { - "builtin_instance_counter": { - "range_check_builtin": 19 - }, - "n_memory_holes": 0, - "n_steps": 691 - }, - "DelegateCall": { - "builtin_instance_counter": { - "range_check_builtin": 19 - }, - "n_memory_holes": 0, - "n_steps": 713 - }, - "DelegateL1Handler": { - "builtin_instance_counter": { - "range_check_builtin": 15 - }, - "n_memory_holes": 0, - "n_steps": 692 - }, - "Deploy": { - "builtin_instance_counter": { - "pedersen_builtin": 7, - "range_check_builtin": 18 - }, - "n_memory_holes": 0, - "n_steps": 944 - }, - "EmitEvent": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 19 - }, - "GetBlockHash": { - "builtin_instance_counter": { - "range_check_builtin": 2 - }, - "n_memory_holes": 0, - "n_steps": 74 - }, - "GetBlockNumber": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 40 - }, - "GetBlockTimestamp": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 38 - }, - "GetCallerAddress": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 32 - }, - "GetContractAddress": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 36 - }, - "GetExecutionInfo": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 29 - }, - "GetSequencerAddress": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 34 - }, - "GetTxInfo": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 29 - }, - "GetTxSignature": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 44 - }, - "Keccak": { - "builtin_instance_counter": { - "bitwise_builtin": 6, - "keccak_builtin": 1, - "range_check_builtin": 56 - }, - "n_memory_holes": 0, - "n_steps": 381 - }, - "LibraryCall": { - "builtin_instance_counter": { - "range_check_builtin": 19 - }, - "n_memory_holes": 0, - "n_steps": 680 - }, - "LibraryCallL1Handler": { - "builtin_instance_counter": { - "range_check_builtin": 15 - }, - "n_memory_holes": 0, - "n_steps": 659 - }, - "ReplaceClass": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 73 - }, - "Secp256k1Add": { - "builtin_instance_counter": { - "range_check_builtin": 29 - }, - "n_memory_holes": 0, - "n_steps": 406 - }, - "Secp256k1GetPointFromX": { - "builtin_instance_counter": { - "range_check_builtin": 30 - }, - "n_memory_holes": 20, - "n_steps": 391 - }, - "Secp256k1GetXy": { - "builtin_instance_counter": { - "range_check_builtin": 11 - }, - "n_memory_holes": 40, - "n_steps": 239 - }, - "Secp256k1Mul": { - "builtin_instance_counter": { - "range_check_builtin": 7045 - }, - "n_memory_holes": 0, - "n_steps": 76401 - }, - "Secp256k1New": { - "builtin_instance_counter": { - "range_check_builtin": 35 - }, - "n_memory_holes": 40, - "n_steps": 475 - }, - "Secp256r1Add": { - "builtin_instance_counter": { - "range_check_builtin": 57 - }, - "n_memory_holes": 0, - "n_steps": 589 - }, - "Secp256r1GetPointFromX": { - "builtin_instance_counter": { - "range_check_builtin": 44 - }, - "n_memory_holes": 20, - "n_steps": 510 - }, - "Secp256r1GetXy": { - "builtin_instance_counter": { - "range_check_builtin": 11 - }, - "n_memory_holes": 40, - "n_steps": 241 - }, - "Secp256r1Mul": { - "builtin_instance_counter": { - "range_check_builtin": 13961 - }, - "n_memory_holes": 0, - "n_steps": 125240 - }, - "Secp256r1New": { - "builtin_instance_counter": { - "range_check_builtin": 49 - }, - "n_memory_holes": 40, - "n_steps": 594 - }, - "SendMessageToL1": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 84 - }, - "Sha256ProcessBlock": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "StorageRead": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 44 - }, - "StorageWrite": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 46 - } - }, - "execute_txs_inner": { - "Declare": { - "deprecated_resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "constant": { - "builtin_instance_counter": { - "pedersen_builtin": 15, - "range_check_builtin": 63 - }, - "n_memory_holes": 0, - "n_steps": 2711 - } - }, - "resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "constant": { - "builtin_instance_counter": { - "pedersen_builtin": 15, - "range_check_builtin": 63 - }, - "n_memory_holes": 0, - "n_steps": 2711 - } - } - }, - "DeployAccount": { - "deprecated_resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "constant": { - "builtin_instance_counter": { - "pedersen_builtin": 23, - "range_check_builtin": 83 - }, - "n_memory_holes": 0, - "n_steps": 3628 - } - }, - "resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "constant": { - "builtin_instance_counter": { - "pedersen_builtin": 23, - "range_check_builtin": 83 - }, - "n_memory_holes": 0, - "n_steps": 3628 - } - } - }, - "InvokeFunction": { - "deprecated_resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "constant": { - "builtin_instance_counter": { - "pedersen_builtin": 16, - "range_check_builtin": 80 - }, - "n_memory_holes": 0, - "n_steps": 3382 - } - }, - "resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "constant": { - "builtin_instance_counter": { - "pedersen_builtin": 16, - "range_check_builtin": 80 - }, - "n_memory_holes": 0, - "n_steps": 3382 - } - } - }, - "L1Handler": { - "deprecated_resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "constant": { - "builtin_instance_counter": { - "pedersen_builtin": 11, - "range_check_builtin": 17 - }, - "n_memory_holes": 0, - "n_steps": 1069 - } - }, - "resources": { - "calldata_factor": { - "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 0 - }, - "constant": { - "builtin_instance_counter": { - "pedersen_builtin": 11, - "range_check_builtin": 17 - }, - "n_memory_holes": 0, - "n_steps": 1069 - } - } - } - } - }, - "validate_max_n_steps": 1000000, - "vm_resource_fee_cost": { - "bitwise_builtin": [ - 32, - 100 - ], - "ec_op_builtin": [ - 512, - 100 - ], - "ecdsa_builtin": [ - 1024, - 100 - ], - "keccak_builtin": [ - 1024, - 100 - ], - "n_steps": [ - 5, - 1000 - ], - "output_builtin": [ - 0, - 1 - ], - "pedersen_builtin": [ - 16, - 100 - ], - "poseidon_builtin": [ - 16, - 100 - ], - "range_check_builtin": [ - 8, - 100 - ] - } -} diff --git a/crates/papyrus_execution/src/execution_test.rs b/crates/papyrus_execution/src/execution_test.rs index 4862e02ff0..78aea699e4 100644 --- a/crates/papyrus_execution/src/execution_test.rs +++ b/crates/papyrus_execution/src/execution_test.rs @@ -852,8 +852,11 @@ fn blockifier_error_mapping() { fn test_get_versioned_constants() { let starknet_version_13_0 = StarknetVersion("0.13.0".to_string()); let starknet_version_13_1 = StarknetVersion("0.13.1".to_string()); + let starknet_version_13_2 = StarknetVersion("0.13.2".to_string()); let versioned_constants = get_versioned_constants(Some(&starknet_version_13_0)).unwrap(); assert_eq!(versioned_constants.invoke_tx_max_n_steps, 3_000_000); let versioned_constants = get_versioned_constants(Some(&starknet_version_13_1)).unwrap(); assert_eq!(versioned_constants.invoke_tx_max_n_steps, 4_000_000); + let versioned_constants = get_versioned_constants(Some(&starknet_version_13_2)).unwrap(); + assert_eq!(versioned_constants.invoke_tx_max_n_steps, 10_000_000); } diff --git a/crates/papyrus_execution/src/lib.rs b/crates/papyrus_execution/src/lib.rs index 1409313452..e4502626ff 100644 --- a/crates/papyrus_execution/src/lib.rs +++ b/crates/papyrus_execution/src/lib.rs @@ -22,8 +22,7 @@ pub mod objects; use std::cell::Cell; use std::collections::BTreeMap; use std::num::NonZeroU128; -use std::path::Path; -use std::sync::{Arc, LazyLock}; +use std::sync::Arc; use blockifier::blockifier::block::{pre_process_block, BlockInfo, BlockNumberHashPair, GasPrices}; use blockifier::bouncer::BouncerConfig; @@ -44,7 +43,10 @@ use blockifier::transaction::objects::{ }; use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction; use blockifier::transaction::transactions::ExecutableTransaction; -use blockifier::versioned_constants::VersionedConstants; +use blockifier::versioned_constants::{ + StarknetVersion as BlockifierStarknetVersion, + VersionedConstants, +}; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; @@ -98,20 +100,6 @@ const INITIAL_GAS_COST: u64 = 10000000000; /// Result type for execution functions. pub type ExecutionResult = Result; -static VERSIONED_CONSTANTS_13_0: LazyLock = LazyLock::new(|| { - VersionedConstants::try_from(Path::new("./resources/versioned_constants_13_0.json")) - .expect("Versioned constants JSON file is malformed") -}); -static VERSIONED_CONSTANTS_13_1: LazyLock = LazyLock::new(|| { - VersionedConstants::try_from(Path::new("./resources/versioned_constants_13_1.json")) - .expect("Versioned constants JSON file is malformed") -}); - -static VERSIONED_CONSTANTS_13_2: LazyLock = LazyLock::new(|| { - VersionedConstants::try_from(Path::new("./resources/versioned_constants_13_2.json")) - .expect("Versioned constants JSON file is malformed") -}); - #[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)] /// Parameters that are needed for execution. pub struct ExecutionConfig { @@ -267,8 +255,7 @@ pub fn execute_call( tx_info: TransactionInfo::Deprecated(DeprecatedTransactionInfo::default()), }), true, // limit_steps_by_resources - ) - .map_err(|err| ExecutionError::ContractError(err.into()))?; + ); let res = call_entry_point .execute(&mut cached_state, &mut ExecutionResources::default(), &mut context) @@ -872,18 +859,19 @@ fn get_versioned_constants( starknet_version: Option<&StarknetVersion>, ) -> ExecutionResult<&'static VersionedConstants> { let versioned_constants = match starknet_version { - Some(starknet_version) => match starknet_version { - StarknetVersion(version) if version == STARKNET_VERSION_O_13_0 => { - &VERSIONED_CONSTANTS_13_0 - } - StarknetVersion(version) if version == STARKNET_VERSION_O_13_1 => { - &VERSIONED_CONSTANTS_13_1 - } - StarknetVersion(version) if version == STARKNET_VERSION_O_13_2 => { - &VERSIONED_CONSTANTS_13_2 - } - _ => VersionedConstants::latest_constants(), - }, + Some(starknet_version) => { + let version = starknet_version.to_string(); + let blockifier_starknet_version = if version == STARKNET_VERSION_O_13_0 { + BlockifierStarknetVersion::V0_13_0 + } else if version == STARKNET_VERSION_O_13_1 { + BlockifierStarknetVersion::V0_13_1 + } else if version == STARKNET_VERSION_O_13_2 { + BlockifierStarknetVersion::V0_13_2 + } else { + BlockifierStarknetVersion::Latest + }; + VersionedConstants::get(blockifier_starknet_version) + } None => VersionedConstants::latest_constants(), }; Ok(versioned_constants) diff --git a/crates/papyrus_load_test/Cargo.toml b/crates/papyrus_load_test/Cargo.toml index 495f695d1c..2e385ee200 100644 --- a/crates/papyrus_load_test/Cargo.toml +++ b/crates/papyrus_load_test/Cargo.toml @@ -11,7 +11,7 @@ compare_endpoints = [] [dependencies] anyhow.workspace = true assert_matches.workspace = true -goose = "0.17.0" +goose.workspace = true once_cell.workspace = true rand.workspace = true reqwest.workspace = true diff --git a/crates/papyrus_monitoring_gateway/Cargo.toml b/crates/papyrus_monitoring_gateway/Cargo.toml index 611eb96e93..d2c713d4d7 100644 --- a/crates/papyrus_monitoring_gateway/Cargo.toml +++ b/crates/papyrus_monitoring_gateway/Cargo.toml @@ -8,8 +8,8 @@ license-file.workspace = true [dependencies] axum.workspace = true hyper = { workspace = true, features = ["full"] } -metrics-exporter-prometheus = { version = "0.12.1" } -metrics-process = { version = "1.0.11" } +metrics-exporter-prometheus.workspace = true +metrics-process.workspace = true papyrus_config.workspace = true papyrus_storage.workspace = true rand.workspace = true @@ -22,7 +22,7 @@ tracing.workspace = true validator = { workspace = true, features = ["derive"] } [dev-dependencies] -http-body = { version = "0.4.5" } +http-body.workspace = true metrics.workspace = true papyrus_storage = { workspace = true, features = ["testing"] } pretty_assertions.workspace = true diff --git a/crates/papyrus_network/Cargo.toml b/crates/papyrus_network/Cargo.toml index 2ebfef86ed..7695eec907 100644 --- a/crates/papyrus_network/Cargo.toml +++ b/crates/papyrus_network/Cargo.toml @@ -10,11 +10,13 @@ testing = [] [dependencies] async-stream.workspace = true +async-trait.workspace = true bytes.workspace = true derive_more.workspace = true futures.workspace = true lazy_static.workspace = true libp2p = { workspace = true, features = [ + "dns", "gossipsub", "identify", "kad", diff --git a/crates/papyrus_network/src/bin_utils/mod.rs b/crates/papyrus_network/src/bin_utils/mod.rs index dfe9ea105f..53cd97449c 100644 --- a/crates/papyrus_network/src/bin_utils/mod.rs +++ b/crates/papyrus_network/src/bin_utils/mod.rs @@ -30,6 +30,8 @@ where .with_tokio() .with_tcp(Default::default(), noise::Config::new, yamux::Config::default) .expect("Error building TCP transport") + .with_dns() + .expect("Error building DNS transport") // TODO: quic transpot does not work (failure appears in the command line when running in debug mode) // .with_quic() .with_behaviour(|key| behaviour(key.clone())) diff --git a/crates/papyrus_network/src/e2e_broadcast_test.rs b/crates/papyrus_network/src/e2e_broadcast_test.rs index 6893a75606..bc83b76a5a 100644 --- a/crates/papyrus_network/src/e2e_broadcast_test.rs +++ b/crates/papyrus_network/src/e2e_broadcast_test.rs @@ -91,7 +91,6 @@ async fn broadcast_subscriber_end_to_end_test() { let subscriber_channels2_1 = network_manager2.register_broadcast_topic::(topic1.clone(), BUFFER_SIZE).unwrap(); - let subscriber_channels2_2 = network_manager2.register_broadcast_topic::(topic2.clone(), BUFFER_SIZE).unwrap(); @@ -106,20 +105,20 @@ async fn broadcast_subscriber_end_to_end_test() { tokio::time::sleep(Duration::from_secs(1)).await; let number1 = Number(1); let number2 = Number(2); - let mut broadcasted_messages_receiver2_1 = - subscriber_channels2_1.broadcasted_messages_receiver; - let mut broadcasted_messages_receiver2_2 = - subscriber_channels2_2.broadcasted_messages_receiver; + let mut broadcast_client2_1 = + subscriber_channels2_1.broadcast_client_channels; + let mut broadcast_client2_2 = + subscriber_channels2_2.broadcast_client_channels; subscriber_channels1_1.messages_to_broadcast_sender.send(number1).await.unwrap(); subscriber_channels1_2.messages_to_broadcast_sender.send(number2).await.unwrap(); let (received_number1, _report_callback) = - broadcasted_messages_receiver2_1.next().await.unwrap(); + broadcast_client2_1.next().await.unwrap(); let (received_number2, _report_callback) = - broadcasted_messages_receiver2_2.next().await.unwrap(); + broadcast_client2_2.next().await.unwrap(); assert_eq!(received_number1.unwrap(), number1); assert_eq!(received_number2.unwrap(), number2); - assert!(broadcasted_messages_receiver2_1.next().now_or_never().is_none()); - assert!(broadcasted_messages_receiver2_2.next().now_or_never().is_none()); + assert!(broadcast_client2_1.next().now_or_never().is_none()); + assert!(broadcast_client2_2.next().now_or_never().is_none()); } ) => { result.unwrap() diff --git a/crates/papyrus_network/src/lib.rs b/crates/papyrus_network/src/lib.rs index 0ce213ba9b..5c0b33a789 100644 --- a/crates/papyrus_network/src/lib.rs +++ b/crates/papyrus_network/src/lib.rs @@ -44,7 +44,7 @@ pub struct NetworkConfig { #[validate(custom = "validate_vec_u256")] #[serde(deserialize_with = "deserialize_optional_vec_u8")] pub(crate) secret_key: Option>, - pub hardcoded_external_multiaddr: Option, + pub advertised_multiaddr: Option, pub chain_id: ChainId, } @@ -100,7 +100,7 @@ impl SerializeConfig for NetworkConfig { config.extend(ser_optional_param( &self.bootstrap_peer_multiaddr, Multiaddr::empty(), - "hardcoded_external_multiaddr", + "advertised_multiaddr", "The external address other peers see this node. If this is set, the node will not \ try to find out which addresses it has and will write this address as external \ instead", @@ -119,7 +119,7 @@ impl Default for NetworkConfig { idle_connection_timeout: Duration::from_secs(120), bootstrap_peer_multiaddr: None, secret_key: None, - hardcoded_external_multiaddr: None, + advertised_multiaddr: None, chain_id: ChainId::Mainnet, } } diff --git a/crates/papyrus_network/src/mixed_behaviour.rs b/crates/papyrus_network/src/mixed_behaviour.rs index 5f6daebeb1..6563e71a03 100644 --- a/crates/papyrus_network/src/mixed_behaviour.rs +++ b/crates/papyrus_network/src/mixed_behaviour.rs @@ -20,7 +20,7 @@ const ONE_MEGA: usize = 1 << 20; #[derive(NetworkBehaviour)] #[behaviour(out_event = "Event")] pub struct MixedBehaviour { - pub peer_manager: peer_manager::PeerManager, + pub peer_manager: peer_manager::PeerManager, pub discovery: Toggle, pub identify: identify::Behaviour, // TODO(shahak): Consider using a different store. diff --git a/crates/papyrus_network/src/network_manager/mod.rs b/crates/papyrus_network/src/network_manager/mod.rs index 6a44f64a5b..bfa77abf1c 100644 --- a/crates/papyrus_network/src/network_manager/mod.rs +++ b/crates/papyrus_network/src/network_manager/mod.rs @@ -9,6 +9,7 @@ use std::collections::HashMap; use std::pin::Pin; use std::task::{Context, Poll}; +use async_trait::async_trait; use futures::channel::mpsc::{Receiver, SendError, Sender}; use futures::channel::oneshot; use futures::future::{ready, BoxFuture, Ready}; @@ -20,6 +21,7 @@ use libp2p::swarm::SwarmEvent; use libp2p::{Multiaddr, PeerId, StreamProtocol, Swarm}; use metrics::gauge; use papyrus_common::metrics as papyrus_metrics; +use serde::{Deserialize, Serialize}; use sqmr::Bytes; use tracing::{debug, error, info, trace, warn}; @@ -38,12 +40,14 @@ pub enum NetworkError { DialError(#[from] libp2p::swarm::DialError), } +// TODO: Understand whats the correct thing to do here. +const MESSAGE_MANAGER_BUFFER_SIZE: usize = 100000; + pub struct GenericNetworkManager { swarm: SwarmT, inbound_protocol_to_buffer_size: HashMap, sqmr_inbound_response_receivers: StreamHashMap, sqmr_inbound_payload_senders: HashMap, - sqmr_outbound_payload_receivers: StreamHashMap, sqmr_outbound_response_senders: HashMap, sqmr_outbound_report_receivers_awaiting_assignment: HashMap, @@ -53,7 +57,11 @@ pub struct GenericNetworkManager { messages_to_broadcast_receivers: StreamHashMap>, broadcasted_messages_senders: HashMap>, reported_peer_receivers: FuturesUnordered>>, - hardcoded_external_multiaddr: Option, + advertised_multiaddr: Option, + reported_peers_receiver: Receiver, + reported_peers_sender: Sender, + continue_propagation_sender: Sender, + continue_propagation_receiver: Receiver, // Fields for metrics num_active_inbound_sessions: usize, num_active_outbound_sessions: usize, @@ -71,23 +79,28 @@ impl GenericNetworkManager { Some((topic_hash, message)) = self.messages_to_broadcast_receivers.next() => { self.broadcast_message(message, topic_hash); } - Some(Some(peer_id)) = self.reported_peer_receivers.next() => self.swarm.report_peer(peer_id), + Some(Some(peer_id)) = self.reported_peer_receivers.next() => self.swarm.report_peer_as_malicious(peer_id), + Some(peer_id) = self.reported_peers_receiver.next() => self.swarm.report_peer_as_malicious(peer_id), + Some(broadcasted_message_manager) = self.continue_propagation_receiver.next() => { + self.swarm.continue_propagation(broadcasted_message_manager); + } } } } - // TODO(shahak): remove the hardcoded_external_multiaddr arg once we manage external addresses + // TODO(shahak): remove the advertised_multiaddr arg once we manage external addresses // in a behaviour. - pub(crate) fn generic_new( - mut swarm: SwarmT, - hardcoded_external_multiaddr: Option, - ) -> Self { + pub(crate) fn generic_new(mut swarm: SwarmT, advertised_multiaddr: Option) -> Self { gauge!(papyrus_metrics::PAPYRUS_NUM_CONNECTED_PEERS, 0f64); let reported_peer_receivers = FuturesUnordered::new(); reported_peer_receivers.push(futures::future::pending().boxed()); - if let Some(address) = hardcoded_external_multiaddr.clone() { + if let Some(address) = advertised_multiaddr.clone() { swarm.add_external_address(address); } + let (reported_peers_sender, reported_peers_receiver) = + futures::channel::mpsc::channel(MESSAGE_MANAGER_BUFFER_SIZE); + let (continue_propagation_sender, continue_propagation_receiver) = + futures::channel::mpsc::channel(MESSAGE_MANAGER_BUFFER_SIZE); Self { swarm, inbound_protocol_to_buffer_size: HashMap::new(), @@ -99,7 +112,11 @@ impl GenericNetworkManager { messages_to_broadcast_receivers: StreamHashMap::new(HashMap::new()), broadcasted_messages_senders: HashMap::new(), reported_peer_receivers, - hardcoded_external_multiaddr, + advertised_multiaddr, + reported_peers_receiver, + reported_peers_sender, + continue_propagation_sender, + continue_propagation_receiver, num_active_inbound_sessions: 0, num_active_outbound_sessions: 0, } @@ -171,6 +188,8 @@ impl GenericNetworkManager { /// Register a new subscriber for broadcasting and receiving broadcasts for a given topic. /// Panics if this topic is already subscribed. + // TODO: consider splitting into register_broadcast_topic_client and + // register_broadcast_topic_server pub fn register_broadcast_topic( &mut self, topic: Topic, @@ -198,7 +217,7 @@ impl GenericNetworkManager { let insert_result = self .broadcasted_messages_senders - .insert(topic_hash.clone(), broadcasted_messages_sender); + .insert(topic_hash.clone(), broadcasted_messages_sender.clone()); if insert_result.is_some() { panic!("Topic '{}' has already been registered.", topic); } @@ -213,7 +232,17 @@ impl GenericNetworkManager { let broadcasted_messages_receiver = broadcasted_messages_receiver.map(broadcasted_messages_fn); - Ok(BroadcastTopicChannels { messages_to_broadcast_sender, broadcasted_messages_receiver }) + let reported_messages_sender = self + .reported_peers_sender + .clone() + .with(|manager: BroadcastedMessageManager| ready(Ok(manager.peer_id))); + let continue_propagation_sender = self.continue_propagation_sender.clone(); + let broadcast_client_channels = BroadcastClientChannels { + broadcasted_messages_receiver, + reported_messages_sender: Box::new(reported_messages_sender), + continue_propagation_sender: Box::new(continue_propagation_sender), + }; + Ok(BroadcastTopicChannels { messages_to_broadcast_sender, broadcast_client_channels }) } fn handle_swarm_event(&mut self, event: SwarmEvent) { @@ -261,7 +290,7 @@ impl GenericNetworkManager { } SwarmEvent::NewListenAddr { address, .. } => { // TODO(shahak): Find a better way to filter private addresses. - if !is_localhost(&address) && self.hardcoded_external_multiaddr.is_none() { + if !is_localhost(&address) && self.advertised_multiaddr.is_none() { self.swarm.add_external_address(address); } } @@ -448,9 +477,7 @@ impl GenericNetworkManager { fn handle_gossipsub_behaviour_event(&mut self, event: gossipsub_impl::ExternalEvent) { let gossipsub_impl::ExternalEvent::Received { originated_peer_id, message, topic_hash } = event; - let (report_sender, report_receiver) = oneshot::channel::<()>(); - let broadcasted_message_manager = BroadcastedMessageManager { report_sender }; - self.handle_new_report_receiver(originated_peer_id, report_receiver); + let broadcasted_message_manager = BroadcastedMessageManager { peer_id: originated_peer_id }; let Some(sender) = self.broadcasted_messages_senders.get_mut(&topic_hash) else { error!( "Received a message from a topic we're not subscribed to with hash {topic_hash:?}" @@ -581,7 +608,7 @@ impl NetworkManager { session_timeout, idle_connection_timeout, bootstrap_peer_multiaddr, - hardcoded_external_multiaddr, + advertised_multiaddr, secret_key, chain_id, } = config; @@ -601,12 +628,12 @@ impl NetworkManager { node_version, ) }); - let hardcoded_external_multiaddr = hardcoded_external_multiaddr.map(|address| { - address.with_p2p(*swarm.local_peer_id()).expect( - "hardcoded_external_multiaddr has a peer id different than the local peer id", - ) + let advertised_multiaddr = advertised_multiaddr.map(|address| { + address + .with_p2p(*swarm.local_peer_id()) + .expect("advertised_multiaddr has a peer id different than the local peer id") }); - Self::generic_new(swarm, hardcoded_external_multiaddr) + Self::generic_new(swarm, advertised_multiaddr) } pub fn get_local_peer_id(&self) -> String { @@ -695,6 +722,7 @@ pub struct ClientResponsesManager> { } impl> ClientResponsesManager { + /// Use this function to report peer as malicious pub fn report_peer(self) { warn!("Reporting peer"); if let Err(e) = self.report_sender.send(()) { @@ -810,20 +838,10 @@ pub type BroadcastTopicSender = With< fn(T) -> Ready>, >; -// TODO(eitan): consider adding the message to the struct +// TODO(alonl): remove clone +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct BroadcastedMessageManager { - report_sender: ReportSender, -} -impl BroadcastedMessageManager { - pub fn report_peer(self) { - warn!("Reporting peer"); - if let Err(e) = self.report_sender.send(()) { - error!("Failed to report peer. Error: {e:?}"); - } - } - - // TODO(eitan): implement - pub fn continue_propogation(&mut self) {} + peer_id: PeerId, } pub type BroadcastTopicReceiver = @@ -836,5 +854,40 @@ type BroadcastReceivedMessagesConverterFn = pub struct BroadcastTopicChannels> { pub messages_to_broadcast_sender: BroadcastTopicSender, - pub broadcasted_messages_receiver: BroadcastTopicReceiver, + pub broadcast_client_channels: BroadcastClientChannels, +} + +pub struct BroadcastClientChannels> { + broadcasted_messages_receiver: BroadcastTopicReceiver, + reported_messages_sender: GenericSender, + continue_propagation_sender: GenericSender, +} + +impl> Stream for BroadcastClientChannels { + type Item = (Result>::Error>, BroadcastedMessageManager); + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>::Error>, BroadcastedMessageManager)>> { + self.broadcasted_messages_receiver.poll_next_unpin(cx) + } +} + +#[async_trait] +pub trait BroadcastClientTrait>: + Stream>::Error>, BroadcastedMessageManager)> + Unpin +{ + async fn report_message(&mut self, message_manager: BroadcastedMessageManager); + async fn continue_propagation(&mut self, message_manager: &BroadcastedMessageManager); +} + +#[async_trait] +impl> BroadcastClientTrait for BroadcastClientChannels { + async fn report_message(&mut self, message_manager: BroadcastedMessageManager) { + let _ = self.reported_messages_sender.send(message_manager).await; + } + + async fn continue_propagation(&mut self, message_manager: &BroadcastedMessageManager) { + let _ = self.continue_propagation_sender.send(message_manager.clone()).await; + } } diff --git a/crates/papyrus_network/src/network_manager/swarm_trait.rs b/crates/papyrus_network/src/network_manager/swarm_trait.rs index fde1e0e713..bcafa027fb 100644 --- a/crates/papyrus_network/src/network_manager/swarm_trait.rs +++ b/crates/papyrus_network/src/network_manager/swarm_trait.rs @@ -5,6 +5,7 @@ use libp2p::swarm::{DialError, NetworkBehaviour, SwarmEvent}; use libp2p::{Multiaddr, PeerId, StreamProtocol, Swarm}; use tracing::{error, info}; +use super::BroadcastedMessageManager; use crate::gossipsub_impl::Topic; use crate::mixed_behaviour; use crate::peer_manager::ReputationModifier; @@ -49,9 +50,11 @@ pub trait SwarmTrait: Stream + Unpin { fn broadcast_message(&mut self, message: Bytes, topic_hash: TopicHash); - fn report_peer(&mut self, peer_id: PeerId); + fn report_peer_as_malicious(&mut self, peer_id: PeerId); fn add_new_supported_inbound_protocol(&mut self, protocol_name: StreamProtocol); + + fn continue_propagation(&mut self, message_manager: BroadcastedMessageManager); } impl SwarmTrait for Swarm { @@ -122,11 +125,15 @@ impl SwarmTrait for Swarm { } } - fn report_peer(&mut self, peer_id: PeerId) { - let _ = self.behaviour_mut().peer_manager.report_peer(peer_id, ReputationModifier::Bad {}); + fn report_peer_as_malicious(&mut self, peer_id: PeerId) { + let _ = + self.behaviour_mut().peer_manager.report_peer(peer_id, ReputationModifier::Malicious); } fn add_new_supported_inbound_protocol(&mut self, protocol: StreamProtocol) { self.behaviour_mut().sqmr.add_new_supported_inbound_protocol(protocol); } + + // TODO(shahak): Implement this function. + fn continue_propagation(&mut self, _message_manager: BroadcastedMessageManager) {} } diff --git a/crates/papyrus_network/src/network_manager/test.rs b/crates/papyrus_network/src/network_manager/test.rs index 111a22836b..cc42d54f90 100644 --- a/crates/papyrus_network/src/network_manager/test.rs +++ b/crates/papyrus_network/src/network_manager/test.rs @@ -21,10 +21,10 @@ use tokio::sync::Mutex; use tokio::time::sleep; use super::swarm_trait::{Event, SwarmTrait}; -use super::GenericNetworkManager; +use super::{BroadcastTopicChannels, GenericNetworkManager}; use crate::gossipsub_impl::{self, Topic}; use crate::mixed_behaviour; -use crate::network_manager::ServerQueryManager; +use crate::network_manager::{BroadcastClientChannels, ServerQueryManager}; use crate::sqmr::behaviour::{PeerNotConnected, SessionIdNotFoundError}; use crate::sqmr::{Bytes, GenericEvent, InboundSessionId, OutboundSessionId}; @@ -185,7 +185,7 @@ impl SwarmTrait for MockSwarm { } } - fn report_peer(&mut self, peer_id: PeerId) { + fn report_peer_as_malicious(&mut self, peer_id: PeerId) { for sender in &self.reported_peer_senders { sender.unbounded_send(peer_id).unwrap(); } @@ -202,6 +202,11 @@ impl SwarmTrait for MockSwarm { ) -> Result { Ok(PeerId::random()) } + + // TODO (shahak): Add test for continue propagation. + fn continue_propagation(&mut self, _message_manager: super::BroadcastedMessageManager) { + unimplemented!() + } } const BUFFER_SIZE: usize = 100; @@ -353,22 +358,25 @@ async fn receive_broadcasted_message_and_report_it() { let mut network_manager = GenericNetworkManager::generic_new(mock_swarm, None); - let mut broadcasted_messages_receiver = network_manager - .register_broadcast_topic::(topic.clone(), BUFFER_SIZE) - .unwrap() - .broadcasted_messages_receiver; + let BroadcastTopicChannels { broadcast_client_channels, .. } = + network_manager.register_broadcast_topic::(topic.clone(), BUFFER_SIZE).unwrap(); + let BroadcastClientChannels { + mut reported_messages_sender, + mut broadcasted_messages_receiver, + .. + } = broadcast_client_channels; tokio::select! { _ = network_manager.run() => panic!("network manager ended"), // We need to do the entire calculation in the future here so that the network will keep // running while we call report_callback. - reported_peer_result = tokio::time::timeout(TIMEOUT, broadcasted_messages_receiver.next()) - .then(|result| { - let (message_result, broadcasted_message_manager) = result.unwrap().unwrap(); - assert_eq!(message, message_result.unwrap()); - broadcasted_message_manager.report_peer(); - tokio::time::timeout(TIMEOUT, reported_peer_receiver.next()) - }) => { + reported_peer_result = tokio::time::timeout(TIMEOUT, async { + let result = broadcasted_messages_receiver.next().await; + let (message_result, broadcasted_message_manager) = result.unwrap(); + assert_eq!(message, message_result.unwrap()); + reported_messages_sender.send(broadcasted_message_manager).await.unwrap(); + reported_peer_receiver.next().await + }) => { assert_eq!(originated_peer_id, reported_peer_result.unwrap().unwrap()); } } diff --git a/crates/papyrus_network/src/network_manager/test_utils.rs b/crates/papyrus_network/src/network_manager/test_utils.rs index 9fa61099f7..f54b5cbf35 100644 --- a/crates/papyrus_network/src/network_manager/test_utils.rs +++ b/crates/papyrus_network/src/network_manager/test_utils.rs @@ -5,8 +5,10 @@ use futures::sink::With; use futures::stream::Map; use futures::{FutureExt, SinkExt, StreamExt}; use libp2p::gossipsub::SubscriptionError; +use libp2p::PeerId; use super::{ + BroadcastClientChannels, BroadcastedMessageManager, GenericReceiver, ReportReceiver, @@ -74,8 +76,36 @@ where } pub fn create_test_broadcasted_message_manager() -> BroadcastedMessageManager { - let (report_sender, _report_receiver) = oneshot::channel::<()>(); - BroadcastedMessageManager { report_sender } + BroadcastedMessageManager { peer_id: PeerId::random() } +} + +// TODO: remove either this method or the one below +// TODO: also return reported_messages_receiver and continue_propagation_receiver, possibly wrapped +// in a struct +pub fn create_test_broadcast_client_channels() +-> (Sender<(Bytes, BroadcastedMessageManager)>, BroadcastClientChannels) +where + T: TryFrom, +{ + let (broadcasted_messages_sender, broadcasted_messages_receiver) = + futures::channel::mpsc::channel(CHANNEL_BUFFER_SIZE); + let (reported_messages_sender, _mock_reported_messages_receiver) = + futures::channel::mpsc::channel(CHANNEL_BUFFER_SIZE); + let (continue_propagation_sender, _mock_continue_propagation_receiver) = + futures::channel::mpsc::channel(CHANNEL_BUFFER_SIZE); + + let broadcasted_messages_fn: BroadcastReceivedMessagesConverterFn = + |(x, broadcasted_message_manager)| (T::try_from(x), broadcasted_message_manager); + let broadcasted_messages_receiver = broadcasted_messages_receiver.map(broadcasted_messages_fn); + + ( + broadcasted_messages_sender, + BroadcastClientChannels { + broadcasted_messages_receiver, + reported_messages_sender: Box::new(reported_messages_sender), + continue_propagation_sender: Box::new(continue_propagation_sender), + }, + ) } const CHANNEL_BUFFER_SIZE: usize = 10000; @@ -98,8 +128,20 @@ where |(x, report_sender)| (T::try_from(x), report_sender); let broadcasted_messages_receiver = broadcasted_messages_receiver.map(broadcasted_messages_fn); + let (reported_messages_sender, _mock_reported_messages_receiver) = + futures::channel::mpsc::channel(CHANNEL_BUFFER_SIZE); + + let (continue_propagation_sender, _mock_continue_propagation_receiver) = + futures::channel::mpsc::channel(CHANNEL_BUFFER_SIZE); + + let broadcast_client_channels = BroadcastClientChannels { + broadcasted_messages_receiver, + reported_messages_sender: Box::new(reported_messages_sender), + continue_propagation_sender: Box::new(continue_propagation_sender), + }; + let subscriber_channels = - BroadcastTopicChannels { messages_to_broadcast_sender, broadcasted_messages_receiver }; + BroadcastTopicChannels { messages_to_broadcast_sender, broadcast_client_channels }; let mock_broadcasted_messages_fn: MockBroadcastedMessagesFn = |(x, report_call_back)| ready(Ok((Bytes::from(x), report_call_back))); diff --git a/crates/papyrus_network/src/peer_manager/behaviour_impl.rs b/crates/papyrus_network/src/peer_manager/behaviour_impl.rs index 82fa9317bc..ca6d1e5b62 100644 --- a/crates/papyrus_network/src/peer_manager/behaviour_impl.rs +++ b/crates/papyrus_network/src/peer_manager/behaviour_impl.rs @@ -29,10 +29,7 @@ pub enum ToOtherBehaviourEvent { }, } -impl NetworkBehaviour for PeerManager

-where - P: PeerTrait, -{ +impl NetworkBehaviour for PeerManager { type ConnectionHandler = dummy::ConnectionHandler; type ToSwarm = ToOtherBehaviourEvent; @@ -105,7 +102,7 @@ where ); return; } - let res = self.report_peer(peer_id, super::ReputationModifier::Bad); + let res = self.report_peer(peer_id, super::ReputationModifier::Unstable); if res.is_err() { error!("Dial failure of an unknown peer. peer id: {}", peer_id) } diff --git a/crates/papyrus_network/src/peer_manager/mod.rs b/crates/papyrus_network/src/peer_manager/mod.rs index efa4bebb92..95f6c8f540 100644 --- a/crates/papyrus_network/src/peer_manager/mod.rs +++ b/crates/papyrus_network/src/peer_manager/mod.rs @@ -6,6 +6,7 @@ use futures::FutureExt; use libp2p::swarm::dial_opts::DialOpts; use libp2p::swarm::ToSwarm; use libp2p::PeerId; +use peer::Peer; use tracing::info; pub use self::behaviour_impl::ToOtherBehaviourEvent; @@ -21,13 +22,14 @@ pub(crate) mod peer; mod test; #[cfg_attr(test, derive(Debug, PartialEq))] +#[derive(Clone, Copy)] pub enum ReputationModifier { - // TODO: Implement this enum - Bad, + Malicious, + Unstable, } -pub struct PeerManager { - peers: HashMap, +pub struct PeerManager { + peers: HashMap, // TODO: consider implementing a cleanup mechanism to not store all queries forever session_to_peer_map: HashMap, config: PeerManagerConfig, @@ -41,7 +43,8 @@ pub struct PeerManager { #[derive(Clone)] pub struct PeerManagerConfig { - blacklist_timeout: Duration, + malicious_timeout: Duration, + unstable_timeout: Duration, } #[derive(thiserror::Error, Debug)] @@ -58,16 +61,14 @@ impl Default for PeerManagerConfig { fn default() -> Self { Self { // 1 year. - blacklist_timeout: Duration::from_secs(3600 * 24 * 365), + malicious_timeout: Duration::from_secs(3600 * 24 * 365), + unstable_timeout: Duration::from_secs(1), } } } #[allow(dead_code)] -impl

PeerManager

-where - P: PeerTrait, -{ +impl PeerManager { pub(crate) fn new(config: PeerManagerConfig) -> Self { let peers = HashMap::new(); Self { @@ -82,9 +83,8 @@ where } } - fn add_peer(&mut self, mut peer: P) { + fn add_peer(&mut self, peer: Peer) { info!("Peer Manager found new peer {:?}", peer.peer_id()); - peer.set_timeout_duration(self.config.blacklist_timeout); self.peers.insert(peer.peer_id(), peer); // The new peer is unblocked so we don't need to wait for unblocked peer. self.sleep_waiting_for_unblocked_peer = None; @@ -94,7 +94,7 @@ where } #[cfg(test)] - fn get_mut_peer(&mut self, peer_id: PeerId) -> Option<&mut P> { + fn get_mut_peer(&mut self, peer_id: PeerId) -> Option<&mut Peer> { self.peers.get_mut(&peer_id) } @@ -184,7 +184,10 @@ where self.pending_events .push(ToSwarm::GenerateEvent(ToOtherBehaviourEvent::PeerBlacklisted { peer_id })); if let Some(peer) = self.peers.get_mut(&peer_id) { - peer.update_reputation(reason); + peer.update_reputation(match reason { + ReputationModifier::Malicious => self.config.malicious_timeout, + ReputationModifier::Unstable => self.config.unstable_timeout, + }); Ok(()) } else { Err(PeerManagerError::NoSuchPeer(peer_id)) @@ -198,7 +201,10 @@ where ) -> Result<(), PeerManagerError> { if let Some(peer_id) = self.session_to_peer_map.get(&outbound_session_id) { if let Some(peer) = self.peers.get_mut(peer_id) { - peer.update_reputation(reason); + peer.update_reputation(match reason { + ReputationModifier::Malicious => self.config.malicious_timeout, + ReputationModifier::Unstable => self.config.unstable_timeout, + }); Ok(()) } else { Err(PeerManagerError::NoSuchPeer(*peer_id)) @@ -215,7 +221,7 @@ impl From for mixed_behaviour::Event { } } -impl BridgedBehaviour for PeerManager

{ +impl BridgedBehaviour for PeerManager { fn on_other_behaviour_event(&mut self, event: &mixed_behaviour::ToOtherBehaviourEvent) { match event { mixed_behaviour::ToOtherBehaviourEvent::Sqmr( @@ -241,7 +247,7 @@ impl BridgedBehaviour for PeerManager

{ return; }; - let peer = P::new(*peer_id, address.clone()); + let peer = Peer::new(*peer_id, address.clone()); self.add_peer(peer); } _ => {} diff --git a/crates/papyrus_network/src/peer_manager/peer.rs b/crates/papyrus_network/src/peer_manager/peer.rs index e797a321d9..74d56f27a5 100644 --- a/crates/papyrus_network/src/peer_manager/peer.rs +++ b/crates/papyrus_network/src/peer_manager/peer.rs @@ -2,24 +2,17 @@ use std::time::{Duration, Instant}; use libp2p::swarm::ConnectionId; use libp2p::{Multiaddr, PeerId}; -#[cfg(test)] -use mockall::automock; -use tracing::{error, info}; - -use super::ReputationModifier; +use tracing::info; -#[cfg_attr(test, automock)] pub trait PeerTrait { fn new(peer_id: PeerId, multiaddr: Multiaddr) -> Self; - fn update_reputation(&mut self, reason: ReputationModifier); + fn update_reputation(&mut self, timeout_duration: Duration); fn peer_id(&self) -> PeerId; fn multiaddr(&self) -> Multiaddr; - fn set_timeout_duration(&mut self, duration: Duration); - fn is_blocked(&self) -> bool; /// Returns Instant::now if not blocked. @@ -36,36 +29,22 @@ pub trait PeerTrait { pub struct Peer { peer_id: PeerId, multiaddr: Multiaddr, - timed_out_until: Option, - timeout_duration: Option, + timed_out_until: Instant, connection_ids: Vec, } impl PeerTrait for Peer { fn new(peer_id: PeerId, multiaddr: Multiaddr) -> Self { - Self { - peer_id, - multiaddr, - timeout_duration: None, - timed_out_until: None, - connection_ids: Vec::new(), - } + Self { peer_id, multiaddr, timed_out_until: get_instant_now(), connection_ids: Vec::new() } } - fn update_reputation(&mut self, _reason: ReputationModifier) { - if let Some(timeout_duration) = self.timeout_duration { - info!( - "Peer {:?} misbehaved. Blacklisting it for {:.3} seconds.", - self.peer_id, - timeout_duration.as_secs_f64(), - ); - self.timed_out_until = Some(Instant::now() + timeout_duration); - } else { - error!( - "Peer {:?} misbehaved but its timeout duration wasn't set. Not doing anything.", - self.peer_id - ); - } + fn update_reputation(&mut self, timeout_duration: Duration) { + self.timed_out_until = get_instant_now() + timeout_duration; + info!( + "Peer {:?} misbehaved. Blacklisting it for {:.3} seconds.", + self.peer_id, + timeout_duration.as_secs_f64(), + ); } fn peer_id(&self) -> PeerId { @@ -76,20 +55,16 @@ impl PeerTrait for Peer { self.multiaddr.clone() } - fn set_timeout_duration(&mut self, duration: Duration) { - self.timeout_duration = Some(duration); - } - fn is_blocked(&self) -> bool { - if let Some(timed_out_until) = self.timed_out_until { - timed_out_until > Instant::now() - } else { - false - } + self.timed_out_until > get_instant_now() } fn blocked_until(&self) -> Instant { - self.timed_out_until.unwrap_or_else(Instant::now) + if self.timed_out_until > get_instant_now() { + self.timed_out_until + } else { + get_instant_now() + } } fn connection_ids(&self) -> &Vec { @@ -104,3 +79,14 @@ impl PeerTrait for Peer { self.connection_ids.retain(|&id| id != connection_id); } } + +#[cfg(not(test))] +fn get_instant_now() -> Instant { + Instant::now() +} + +// In tests we simulate time passing using tokio, so we need to use tokio's Instant instead of std. +#[cfg(test)] +fn get_instant_now() -> Instant { + tokio::time::Instant::now().into_std() +} diff --git a/crates/papyrus_network/src/peer_manager/test.rs b/crates/papyrus_network/src/peer_manager/test.rs index 5c2c96f469..21480bd218 100644 --- a/crates/papyrus_network/src/peer_manager/test.rs +++ b/crates/papyrus_network/src/peer_manager/test.rs @@ -3,7 +3,7 @@ use core::{panic, time}; use std::pin::Pin; use std::task::{Context, Poll}; -use std::time::{Duration, Instant}; +use std::time::Duration; use assert_matches::assert_matches; use futures::future::poll_fn; @@ -11,7 +11,6 @@ use futures::{FutureExt, Stream, StreamExt}; use libp2p::swarm::behaviour::ConnectionEstablished; use libp2p::swarm::{ConnectionId, NetworkBehaviour, ToSwarm}; use libp2p::{Multiaddr, PeerId}; -use mockall::predicate::eq; use tokio::time::sleep; use void::Void; @@ -19,13 +18,13 @@ use super::behaviour_impl::ToOtherBehaviourEvent; use crate::discovery::identify_impl::IdentifyToOtherBehaviourEvent; use crate::mixed_behaviour; use crate::mixed_behaviour::BridgedBehaviour; -use crate::peer_manager::peer::{MockPeerTrait, Peer, PeerTrait}; +use crate::peer_manager::peer::{Peer, PeerTrait}; use crate::peer_manager::{PeerManager, PeerManagerConfig, ReputationModifier}; use crate::sqmr::OutboundSessionId; -impl Unpin for PeerManager

{} +impl Unpin for PeerManager {} -impl Stream for PeerManager

{ +impl Stream for PeerManager { type Item = ToSwarm; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { @@ -74,12 +73,12 @@ fn peer_assignment_round_robin() { } // check assignment events - for event in peer_manager.pending_events { - let ToSwarm::GenerateEvent(ToOtherBehaviourEvent::SessionAssigned { + while let Some(event) = peer_manager.next().now_or_never() { + let Some(ToSwarm::GenerateEvent(ToOtherBehaviourEvent::SessionAssigned { outbound_session_id, peer_id, connection_id, - }) = event + })) = event else { continue; }; @@ -123,7 +122,7 @@ fn peer_assignment_round_robin() { async fn peer_assignment_no_peers() { // Create a new peer manager let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); // Create a session let outbound_session_id = OutboundSessionId { value: 1 }; @@ -134,9 +133,9 @@ async fn peer_assignment_no_peers() { // Now the peer manager finds a new peer and can assign the session. let connection_id = ConnectionId::new_unchecked(0); - let (mut peer, peer_id) = - create_mock_peer(config.blacklist_timeout, false, Some(connection_id)); - peer.expect_is_blocked().times(1).return_const(false); + let peer_id = PeerId::random(); + let mut peer = Peer::new(peer_id, Multiaddr::empty()); + peer.add_connection_id(connection_id); peer_manager.add_peer(peer); assert_matches!( peer_manager.next().await.unwrap(), @@ -157,21 +156,20 @@ async fn peer_assignment_no_unblocked_peers() { const BLOCKED_UNTIL: Duration = Duration::from_secs(5); const TIMEOUT: Duration = Duration::from_secs(1); // Create a new peer manager - let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let config = PeerManagerConfig { malicious_timeout: TIMEOUT, unstable_timeout: TIMEOUT }; + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); // Create a session let outbound_session_id = OutboundSessionId { value: 1 }; // Create a peer let connection_id = ConnectionId::new_unchecked(0); - let (mut peer, peer_id) = create_mock_peer(config.blacklist_timeout, true, Some(connection_id)); - peer.expect_is_blocked().times(1).return_const(true); - peer.expect_is_blocked().times(1).return_const(false); - peer.expect_blocked_until().times(1).returning(|| Instant::now() + BLOCKED_UNTIL); + let peer_id = PeerId::random(); + let mut peer = Peer::new(peer_id, Multiaddr::empty()); + peer.add_connection_id(connection_id); peer_manager.add_peer(peer); - peer_manager.report_peer(peer_id, ReputationModifier::Bad {}).unwrap(); + peer_manager.report_peer(peer_id, ReputationModifier::Unstable).unwrap(); // Consume the peer blacklisted event let event = tokio::time::timeout(TIMEOUT, peer_manager.next()).await.unwrap().unwrap(); @@ -210,17 +208,17 @@ async fn peer_assignment_no_unblocked_peers() { fn report_peer_calls_update_reputation_and_notifies_kad() { // Create a new peer manager let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); - // Create a mock peer - let (peer, peer_id) = create_mock_peer(config.blacklist_timeout, true, None); + // Create a peer + let peer_id = PeerId::random(); + let peer = Peer::new(peer_id, Multiaddr::empty()); - // Add the mock peer to the peer manager peer_manager.add_peer(peer); // Call the report_peer function on the peer manager - peer_manager.report_peer(peer_id, ReputationModifier::Bad {}).unwrap(); - peer_manager.get_mut_peer(peer_id).unwrap().checkpoint(); + peer_manager.report_peer(peer_id, ReputationModifier::Unstable).unwrap(); + peer_manager.get_mut_peer(peer_id).unwrap(); // Validate that we have an event to notify Kademlia assert_eq!(peer_manager.pending_events.len(), 1); @@ -232,11 +230,10 @@ fn report_peer_calls_update_reputation_and_notifies_kad() { } #[tokio::test] -async fn peer_block_realeased_after_timeout() { +async fn peer_block_released_after_timeout() { const DURATION_IN_MILLIS: u64 = 50; let mut peer = Peer::new(PeerId::random(), Multiaddr::empty()); - peer.set_timeout_duration(Duration::from_millis(DURATION_IN_MILLIS)); - peer.update_reputation(ReputationModifier::Bad {}); + peer.update_reputation(Duration::from_millis(DURATION_IN_MILLIS)); assert!(peer.is_blocked()); sleep(time::Duration::from_millis(DURATION_IN_MILLIS)).await; assert!(!peer.is_blocked()); @@ -245,13 +242,12 @@ async fn peer_block_realeased_after_timeout() { #[test] fn report_peer_on_unknown_peer_id() { // Create a new peer manager - let mut peer_manager: PeerManager = - PeerManager::new(PeerManagerConfig::default()); + let mut peer_manager: PeerManager = PeerManager::new(PeerManagerConfig::default()); // report peer on an unknown peer_id let peer_id = PeerId::random(); peer_manager - .report_peer(peer_id, ReputationModifier::Bad {}) + .report_peer(peer_id, ReputationModifier::Unstable {}) .expect_err("report_peer on unknown peer_id should return an error"); } @@ -259,14 +255,14 @@ fn report_peer_on_unknown_peer_id() { fn report_session_calls_update_reputation() { // Create a new peer manager let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); - // Create a mock peer - let (mut peer, peer_id) = - create_mock_peer(config.blacklist_timeout, true, Some(ConnectionId::new_unchecked(0))); - peer.expect_is_blocked().times(1).return_const(false); + // Create a peer + let peer_id = PeerId::random(); + let mut peer = Peer::new(peer_id, Multiaddr::empty()); + peer.add_connection_id(ConnectionId::new_unchecked(0)); - // Add the mock peer to the peer manager + // Add the peer to the peer manager peer_manager.add_peer(peer); // Create a session @@ -277,21 +273,20 @@ fn report_session_calls_update_reputation() { assert_eq!(res_peer_id, peer_id); // Call the report_peer function on the peer manager - peer_manager.report_session(outbound_session_id, ReputationModifier::Bad {}).unwrap(); - peer_manager.get_mut_peer(peer_id).unwrap().checkpoint(); + peer_manager.report_session(outbound_session_id, ReputationModifier::Unstable {}).unwrap(); + peer_manager.get_mut_peer(peer_id).unwrap(); } #[test] fn report_session_on_unknown_session_id() { // Create a new peer manager - let mut peer_manager: PeerManager = - PeerManager::new(PeerManagerConfig::default()); + let mut peer_manager: PeerManager = PeerManager::new(PeerManagerConfig::default()); // Create a session let outbound_session_id = OutboundSessionId { value: 1 }; peer_manager - .report_session(outbound_session_id, ReputationModifier::Bad {}) + .report_session(outbound_session_id, ReputationModifier::Malicious {}) .expect_err("report_session on unknown outbound_session_id should return an error"); } @@ -299,18 +294,17 @@ fn report_session_on_unknown_session_id() { async fn timed_out_peer_not_assignable_to_queries() { // Create a new peer manager let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); - // Create a mock peer - let (mut peer, peer_id) = create_mock_peer(config.blacklist_timeout, true, None); - peer.expect_is_blocked().times(1).return_const(true); - peer.expect_blocked_until().times(1).returning(|| Instant::now() + Duration::from_secs(1)); + // Create a peer + let peer_id = PeerId::random(); + let peer = Peer::new(peer_id, Multiaddr::empty()); - // Add the mock peer to the peer manager + // Add the peer to the peer manager peer_manager.add_peer(peer); // Report the peer as bad - peer_manager.report_peer(peer_id, ReputationModifier::Bad {}).unwrap(); + peer_manager.report_peer(peer_id, ReputationModifier::Malicious {}).unwrap(); // Create a session let outbound_session_id = OutboundSessionId { value: 1 }; @@ -323,25 +317,25 @@ async fn timed_out_peer_not_assignable_to_queries() { fn wrap_around_in_peer_assignment() { // Create a new peer manager let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); - // Create a mock peer - let (mut peer1, peer_id1) = - create_mock_peer(config.blacklist_timeout, true, Some(ConnectionId::new_unchecked(0))); - peer1.expect_is_blocked().times(..2).return_const(true); + // Create a peer + let peer_id1 = PeerId::random(); + let mut peer1 = Peer::new(peer_id1, Multiaddr::empty()); + peer1.add_connection_id(ConnectionId::new_unchecked(0)); - // Add the mock peer to the peer manager + // Add the peer to the peer manager peer_manager.add_peer(peer1); - // Report the peer as bad - peer_manager.report_peer(peer_id1, ReputationModifier::Bad {}).unwrap(); + // Report the peer as malicious + peer_manager.report_peer(peer_id1, ReputationModifier::Malicious {}).unwrap(); - // Create a mock peer - let (mut peer2, peer_id2) = - create_mock_peer(config.blacklist_timeout, false, Some(ConnectionId::new_unchecked(0))); - peer2.expect_is_blocked().times(2).return_const(false); + // Create a peer + let peer_id2 = PeerId::random(); + let mut peer2 = Peer::new(peer_id2, Multiaddr::empty()); + peer2.add_connection_id(ConnectionId::new_unchecked(0)); - // Add the mock peer to the peer manager + // Add the peer to the peer manager peer_manager.add_peer(peer2); // Create a session @@ -353,51 +347,25 @@ fn wrap_around_in_peer_assignment() { assert_matches!(peer_manager.assign_peer_to_session(outbound_session_id), Some(peer_id) if peer_id == peer_id2); } -fn create_mock_peer( - blacklist_timeout_duration: Duration, - call_update_reputaion: bool, - connection_id: Option, -) -> (MockPeerTrait, PeerId) { - let peer_id = PeerId::random(); - let mut peer = MockPeerTrait::default(); - let mut mockall_seq = mockall::Sequence::new(); - - peer.expect_peer_id().return_const(peer_id); - peer.expect_set_timeout_duration() - .times(1) - .with(eq(blacklist_timeout_duration)) - .return_const(()) - .in_sequence(&mut mockall_seq); - if call_update_reputaion { - peer.expect_update_reputation() - .times(1) - .with(eq(ReputationModifier::Bad {})) - .return_once(|_| ()) - .in_sequence(&mut mockall_seq); - } - peer.expect_connection_ids().return_const(connection_id.map(|x| vec![x]).unwrap_or_default()); - - (peer, peer_id) -} - #[test] fn block_and_allow_inbound_connection() { // Create a new peer manager let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); - // Create a mock peer - blocked - let (mut peer1, peer_id1) = create_mock_peer(config.blacklist_timeout, false, None); - peer1.expect_is_blocked().times(..2).return_const(true); + // Create a peer - report as malicious + let peer_id1 = PeerId::random(); + let peer1 = Peer::new(peer_id1, Multiaddr::empty()); - // Create a mock peer - not blocked - let (mut peer2, peer_id2) = create_mock_peer(config.blacklist_timeout, false, None); - peer2.expect_is_blocked().times(..2).return_const(false); + // Create a peer - not blocked + let peer_id2 = PeerId::random(); + let peer2 = Peer::new(peer_id2, Multiaddr::empty()); - // Add the mock peers to the peer manager peer_manager.add_peer(peer1); peer_manager.add_peer(peer2); + peer_manager.report_peer(peer_id1, ReputationModifier::Malicious).unwrap(); + // call handle_established_inbound_connection with the blocked peer let res = peer_manager.handle_established_inbound_connection( libp2p::swarm::ConnectionId::new_unchecked(0), @@ -423,14 +391,13 @@ fn block_and_allow_inbound_connection() { fn assign_non_connected_peer_raises_dial_event() { // Create a new peer manager let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); - // Create a mock peer - let (mut peer, _) = create_mock_peer(config.blacklist_timeout, false, None); - peer.expect_is_blocked().times(1).return_const(false); - peer.expect_multiaddr().return_const(Multiaddr::empty()); + // Create a peer + let peer_id = PeerId::random(); + let peer = Peer::new(peer_id, Multiaddr::empty()); - // Add the mock peer to the peer manager + // Add the peer to the peer manager peer_manager.add_peer(peer); // Create a session @@ -449,15 +416,13 @@ fn assign_non_connected_peer_raises_dial_event() { async fn flow_test_assign_non_connected_peer() { // Create a new peer manager let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); - // Create a mock peer - let (mut peer, peer_id) = create_mock_peer(config.blacklist_timeout, false, None); - peer.expect_is_blocked().times(1).return_const(false); - peer.expect_multiaddr().return_const(Multiaddr::empty()); - peer.expect_add_connection_id().times(1).return_const(()); + // Create a peer + let peer_id = PeerId::random(); + let peer = Peer::new(peer_id, Multiaddr::empty()); - // Add the mock peer to the peer manager + // Add the peer to the peer manager peer_manager.add_peer(peer); // Create a session @@ -495,7 +460,7 @@ async fn flow_test_assign_non_connected_peer() { fn identify_on_unknown_peer_is_added_to_peer_manager() { // Create a new peer manager let config = PeerManagerConfig::default(); - let mut peer_manager: PeerManager = PeerManager::new(config.clone()); + let mut peer_manager: PeerManager = PeerManager::new(config.clone()); // Send Identify event let peer_id = PeerId::random(); diff --git a/crates/papyrus_node/Cargo.toml b/crates/papyrus_node/Cargo.toml index d6400191d6..8c5d55a744 100644 --- a/crates/papyrus_node/Cargo.toml +++ b/crates/papyrus_node/Cargo.toml @@ -29,6 +29,7 @@ papyrus_base_layer.workspace = true papyrus_common.workspace = true papyrus_config.workspace = true papyrus_consensus.workspace = true +papyrus_consensus_orchestrator.workspace = true papyrus_monitoring_gateway.workspace = true papyrus_network.workspace = true papyrus_p2p_sync.workspace = true diff --git a/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap b/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap index 96d2b2d9e7..dc72d69c4d 100644 --- a/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap +++ b/crates/papyrus_node/src/config/snapshots/papyrus_node__config__config_test__dump_default_config.snap @@ -209,6 +209,16 @@ expression: dumped_default_config "value": true, "privacy": "TemporaryValue" }, + "network.advertised_multiaddr": { + "description": "The external address other peers see this node. If this is set, the node will not try to find out which addresses it has and will write this address as external instead", + "value": "", + "privacy": "Public" + }, + "network.advertised_multiaddr.#is_none": { + "description": "Flag for an optional field.", + "value": true, + "privacy": "TemporaryValue" + }, "network.bootstrap_peer_multiaddr": { "description": "The multiaddress of the peer node. It should include the peer's id. For more info: https://docs.libp2p.io/concepts/fundamentals/peers/", "value": "", @@ -224,16 +234,6 @@ expression: dumped_default_config "value": "SN_MAIN", "privacy": "Public" }, - "network.hardcoded_external_multiaddr": { - "description": "The external address other peers see this node. If this is set, the node will not try to find out which addresses it has and will write this address as external instead", - "value": "", - "privacy": "Public" - }, - "network.hardcoded_external_multiaddr.#is_none": { - "description": "Flag for an optional field.", - "value": true, - "privacy": "TemporaryValue" - }, "network.idle_connection_timeout": { "description": "Amount of time in seconds that a connection with no active sessions will stay alive.", "value": { diff --git a/crates/papyrus_node/src/main.rs b/crates/papyrus_node/src/main.rs index 7bf3fef898..8fc96ed77a 100644 --- a/crates/papyrus_node/src/main.rs +++ b/crates/papyrus_node/src/main.rs @@ -17,12 +17,11 @@ use papyrus_config::presentation::get_config_presentation; use papyrus_config::validators::config_validate; use papyrus_config::ConfigError; use papyrus_consensus::config::ConsensusConfig; -use papyrus_consensus::papyrus_consensus_context::PapyrusConsensusContext; -use papyrus_consensus::simulation_network_receiver::NetworkReceiver; use papyrus_consensus::types::ConsensusError; +use papyrus_consensus_orchestrator::papyrus_consensus_context::PapyrusConsensusContext; use papyrus_monitoring_gateway::MonitoringServer; use papyrus_network::gossipsub_impl::Topic; -use papyrus_network::network_manager::NetworkManager; +use papyrus_network::network_manager::{BroadcastTopicChannels, NetworkManager}; use papyrus_network::{network_manager, NetworkConfig}; use papyrus_node::config::NodeConfig; use papyrus_node::version::VERSION_FULL; @@ -108,25 +107,20 @@ fn run_consensus( let network_channels = network_manager .register_broadcast_topic(Topic::new(config.network_topic.clone()), BUFFER_SIZE)?; + let BroadcastTopicChannels { messages_to_broadcast_sender, broadcast_client_channels } = + network_channels; // TODO(matan): connect this to an actual channel. if let Some(test_config) = config.test.as_ref() { let sync_channels = network_manager .register_broadcast_topic(Topic::new(test_config.sync_topic.clone()), BUFFER_SIZE)?; let context = PapyrusConsensusContext::new( storage_reader.clone(), - network_channels.messages_to_broadcast_sender, + messages_to_broadcast_sender, config.num_validators, Some(sync_channels.messages_to_broadcast_sender), ); - let network_receiver = NetworkReceiver::new( - network_channels.broadcasted_messages_receiver, - test_config.cache_size, - test_config.random_seed, - test_config.drop_probability, - test_config.invalid_probability, - ); let sync_receiver = - sync_channels.broadcasted_messages_receiver.map(|(vote, _report_sender)| { + sync_channels.broadcast_client_channels.map(|(vote, _report_sender)| { BlockNumber(vote.expect("Sync channel should never have errors").height) }); Ok(tokio::spawn(papyrus_consensus::run_consensus( @@ -135,13 +129,13 @@ fn run_consensus( config.validator_id, config.consensus_delay, config.timeouts.clone(), - network_receiver, + broadcast_client_channels, sync_receiver, ))) } else { let context = PapyrusConsensusContext::new( storage_reader.clone(), - network_channels.messages_to_broadcast_sender, + messages_to_broadcast_sender, config.num_validators, None, ); @@ -151,7 +145,7 @@ fn run_consensus( config.validator_id, config.consensus_delay, config.timeouts.clone(), - network_channels.broadcasted_messages_receiver, + broadcast_client_channels, futures::stream::pending(), ))) } @@ -363,10 +357,13 @@ fn register_to_network(network_config: Option) -> anyhow::Result< network_manager.register_sqmr_protocol_client(Protocol::StateDiff.into(), BUFFER_SIZE); let transaction_client_sender = network_manager.register_sqmr_protocol_client(Protocol::Transaction.into(), BUFFER_SIZE); + let class_client_sender = + network_manager.register_sqmr_protocol_client(Protocol::Class.into(), BUFFER_SIZE); let p2p_sync_client_channels = P2PSyncClientChannels::new( header_client_sender, state_diff_client_sender, transaction_client_sender, + class_client_sender, ); let header_server_receiver = network_manager diff --git a/crates/papyrus_p2p_sync/src/client/header_test.rs b/crates/papyrus_p2p_sync/src/client/header_test.rs index 668a8e601d..caf01a0e68 100644 --- a/crates/papyrus_p2p_sync/src/client/header_test.rs +++ b/crates/papyrus_p2p_sync/src/client/header_test.rs @@ -28,10 +28,11 @@ async fn signed_headers_basic_flow() { let TestArgs { p2p_sync, storage_reader, - mut header_receiver, + mut mock_header_response_manager, // The test will fail if we drop these - state_diff_receiver: _state_diff_query_receiver, - transaction_receiver: _transaction_query_receiver, + mock_state_diff_response_manager: _mock_state_diff_response_manager, + mock_transaction_response_manager: _mock_transaction_response_manager, + mock_class_response_manager: _mock_class_response_manager, .. } = setup(); let block_hashes_and_signatures = @@ -44,7 +45,8 @@ async fn signed_headers_basic_flow() { let end_block_number = (query_index + 1) * HEADER_QUERY_LENGTH; // Receive query and validate it. - let mut mock_header_responses_manager = header_receiver.next().await.unwrap(); + let mut mock_header_responses_manager = + mock_header_response_manager.next().await.unwrap(); assert_eq!( *mock_header_responses_manager.query(), Ok(HeaderQuery(Query { @@ -110,17 +112,18 @@ async fn sync_sends_new_header_query_if_it_got_partial_responses() { let TestArgs { p2p_sync, - mut header_receiver, + mut mock_header_response_manager, // The test will fail if we drop these - state_diff_receiver: _state_diff_query_receiver, - transaction_receiver: _transaction_query_receiver, + mock_state_diff_response_manager: _state_diff_receiver, + mock_transaction_response_manager: _transaction_receiver, + mock_class_response_manager: _class_receiver, .. } = setup(); let block_hashes_and_signatures = create_block_hashes_and_signatures(NUM_ACTUAL_RESPONSES); // Create a future that will receive a query, send partial responses and receive the next query. let parse_queries_future = async move { - let mut mock_header_responses_manager = header_receiver.next().await.unwrap(); + let mut mock_header_responses_manager = mock_header_response_manager.next().await.unwrap(); for (i, (block_hash, signature)) in block_hashes_and_signatures.into_iter().enumerate() { mock_header_responses_manager @@ -146,11 +149,13 @@ async fn sync_sends_new_header_query_if_it_got_partial_responses() { tokio::time::resume(); // First unwrap is for the timeout. Second unwrap is for the Option returned from Stream. - let mock_header_responses_manager = - timeout(TIMEOUT_FOR_NEW_QUERY_AFTER_PARTIAL_RESPONSE, header_receiver.next()) - .await - .unwrap() - .unwrap(); + let mock_header_responses_manager = timeout( + TIMEOUT_FOR_NEW_QUERY_AFTER_PARTIAL_RESPONSE, + mock_header_response_manager.next(), + ) + .await + .unwrap() + .unwrap(); assert_eq!( *mock_header_responses_manager.query(), diff --git a/crates/papyrus_p2p_sync/src/client/mod.rs b/crates/papyrus_p2p_sync/src/client/mod.rs index 06b3ecdf7f..8cab726cd2 100644 --- a/crates/papyrus_p2p_sync/src/client/mod.rs +++ b/crates/papyrus_p2p_sync/src/client/mod.rs @@ -15,12 +15,14 @@ use std::time::Duration; use futures::channel::mpsc::SendError; use futures::Stream; use header::HeaderStreamBuilder; +use papyrus_common::pending_classes::ApiContractClass; use papyrus_config::converters::deserialize_seconds_to_duration; use papyrus_config::dumping::{ser_optional_param, ser_param, SerializeConfig}; use papyrus_config::{ParamPath, ParamPrivacyInput, SerializedParam}; use papyrus_network::network_manager::SqmrClientSender; use papyrus_protobuf::converters::ProtobufConversionError; use papyrus_protobuf::sync::{ + ClassQuery, DataOrFin, HeaderQuery, SignedBlockHeader, @@ -31,6 +33,7 @@ use papyrus_protobuf::sync::{ use papyrus_storage::{StorageError, StorageReader, StorageWriter}; use serde::{Deserialize, Serialize}; use starknet_api::block::{BlockNumber, BlockSignature}; +use starknet_api::core::ClassHash; use starknet_api::transaction::FullTransaction; use state_diff::StateDiffStreamBuilder; use stream_builder::{DataStreamBuilder, DataStreamResult}; @@ -175,11 +178,14 @@ pub enum P2PSyncClientError { type HeaderSqmrSender = SqmrClientSender>; type StateSqmrDiffSender = SqmrClientSender>; type TransactionSqmrSender = SqmrClientSender>; +type ClassSqmrSender = SqmrClientSender>; pub struct P2PSyncClientChannels { header_sender: HeaderSqmrSender, state_diff_sender: StateSqmrDiffSender, transaction_sender: TransactionSqmrSender, + #[allow(dead_code)] + class_sender: ClassSqmrSender, } impl P2PSyncClientChannels { @@ -187,8 +193,9 @@ impl P2PSyncClientChannels { header_sender: HeaderSqmrSender, state_diff_sender: StateSqmrDiffSender, transaction_sender: TransactionSqmrSender, + class_sender: ClassSqmrSender, ) -> Self { - Self { header_sender, state_diff_sender, transaction_sender } + Self { header_sender, state_diff_sender, transaction_sender, class_sender } } pub(crate) fn create_stream( self, diff --git a/crates/papyrus_p2p_sync/src/client/state_diff_test.rs b/crates/papyrus_p2p_sync/src/client/state_diff_test.rs index acc76333cb..fdc8c82b1d 100644 --- a/crates/papyrus_p2p_sync/src/client/state_diff_test.rs +++ b/crates/papyrus_p2p_sync/src/client/state_diff_test.rs @@ -47,10 +47,11 @@ async fn state_diff_basic_flow() { let TestArgs { p2p_sync, storage_reader, - mut state_diff_receiver, - mut header_receiver, + mut mock_state_diff_response_manager, + mut mock_header_response_manager, // The test will fail if we drop these - transaction_receiver: _mock_transaction_responses_manager, + mock_transaction_response_manager: _mock_transaction_responses_manager, + mock_class_response_manager: _mock_class_responses_manager, .. } = setup(); @@ -69,8 +70,8 @@ async fn state_diff_basic_flow() { tokio::time::sleep(SLEEP_DURATION_TO_LET_SYNC_ADVANCE).await; // Check that before we send headers there is no state diff query. - assert!(state_diff_receiver.next().now_or_never().is_none()); - let mut mock_header_responses_manager = header_receiver.next().await.unwrap(); + assert!(mock_state_diff_response_manager.next().now_or_never().is_none()); + let mut mock_header_responses_manager = mock_header_response_manager.next().await.unwrap(); // Send headers for entire query. for (i, ((block_hash, block_signature), state_diff)) in @@ -105,7 +106,8 @@ async fn state_diff_basic_flow() { (STATE_DIFF_QUERY_LENGTH, HEADER_QUERY_LENGTH - STATE_DIFF_QUERY_LENGTH), ] { // Get a state diff query and validate it - let mut mock_state_diff_responses_manager = state_diff_receiver.next().await.unwrap(); + let mut mock_state_diff_responses_manager = + mock_state_diff_response_manager.next().await.unwrap(); assert_eq!( *mock_state_diff_responses_manager.query(), Ok(StateDiffQuery(Query { @@ -318,10 +320,11 @@ async fn validate_state_diff_fails( let TestArgs { p2p_sync, storage_reader, - mut state_diff_receiver, - mut header_receiver, + mut mock_state_diff_response_manager, + mut mock_header_response_manager, // The test will fail if we drop these - transaction_receiver: _mock_transaction_responses_manager, + mock_transaction_response_manager: _mock_transaction_responses_manager, + mock_class_response_manager: _mock_class_responses_manager, .. } = setup(); @@ -330,7 +333,7 @@ async fn validate_state_diff_fails( // Create a future that will receive queries, send responses and validate the results. let parse_queries_future = async move { // Send a single header. There's no need to fill the entire query. - let mut mock_header_responses_manager = header_receiver.next().await.unwrap(); + let mut mock_header_responses_manager = mock_header_response_manager.next().await.unwrap(); mock_header_responses_manager .send_response(DataOrFin(Some(SignedBlockHeader { block_header: BlockHeader { @@ -354,7 +357,8 @@ async fn validate_state_diff_fails( tokio::time::resume(); // Get a state diff query and validate it - let mut mock_state_diff_responses_manager = state_diff_receiver.next().await.unwrap(); + let mut mock_state_diff_responses_manager = + mock_state_diff_response_manager.next().await.unwrap(); assert_eq!( *mock_state_diff_responses_manager.query(), Ok(StateDiffQuery(Query { diff --git a/crates/papyrus_p2p_sync/src/client/test_utils.rs b/crates/papyrus_p2p_sync/src/client/test_utils.rs index 74a0c98317..ea5a777d28 100644 --- a/crates/papyrus_p2p_sync/src/client/test_utils.rs +++ b/crates/papyrus_p2p_sync/src/client/test_utils.rs @@ -1,12 +1,14 @@ use std::time::Duration; use lazy_static::lazy_static; +use papyrus_common::pending_classes::ApiContractClass; use papyrus_network::network_manager::test_utils::{ mock_register_sqmr_protocol_client, MockClientResponsesManager, }; use papyrus_network::network_manager::GenericReceiver; use papyrus_protobuf::sync::{ + ClassQuery, DataOrFin, HeaderQuery, SignedBlockHeader, @@ -17,6 +19,7 @@ use papyrus_protobuf::sync::{ use papyrus_storage::test_utils::get_test_storage; use papyrus_storage::StorageReader; use starknet_api::block::{BlockHash, BlockSignature}; +use starknet_api::core::ClassHash; use starknet_api::crypto::utils::Signature; use starknet_api::hash::StarkHash; use starknet_api::transaction::FullTransaction; @@ -47,28 +50,40 @@ type HeaderTestPayload = MockClientResponsesManager>; type TransactionTestPayload = MockClientResponsesManager>; +type ClassTestPayload = + MockClientResponsesManager>; // TODO(Eitan): Use SqmrSubscriberChannels once there is a utility function for testing pub struct TestArgs { #[allow(clippy::type_complexity)] pub p2p_sync: P2PSyncClient, pub storage_reader: StorageReader, - pub header_receiver: GenericReceiver, - pub state_diff_receiver: GenericReceiver, + pub mock_header_response_manager: GenericReceiver, + pub mock_state_diff_response_manager: GenericReceiver, #[allow(dead_code)] - pub transaction_receiver: GenericReceiver, + pub mock_transaction_response_manager: GenericReceiver, + #[allow(dead_code)] + pub mock_class_response_manager: GenericReceiver, } pub fn setup() -> TestArgs { let p2p_sync_config = *TEST_CONFIG; let buffer_size = p2p_sync_config.buffer_size; let ((storage_reader, storage_writer), _temp_dir) = get_test_storage(); - let (header_sender, header_receiver) = mock_register_sqmr_protocol_client(buffer_size); - let (state_diff_sender, state_diff_receiver) = mock_register_sqmr_protocol_client(buffer_size); - let (transaction_sender, transaction_receiver) = + let (header_sender, mock_header_response_manager) = + mock_register_sqmr_protocol_client(buffer_size); + let (state_diff_sender, mock_state_diff_response_manager) = + mock_register_sqmr_protocol_client(buffer_size); + let (transaction_sender, mock_transaction_response_manager) = mock_register_sqmr_protocol_client(buffer_size); - let p2p_sync_channels = - P2PSyncClientChannels { header_sender, state_diff_sender, transaction_sender }; + let (class_sender, mock_class_response_manager) = + mock_register_sqmr_protocol_client(buffer_size); + let p2p_sync_channels = P2PSyncClientChannels { + header_sender, + state_diff_sender, + transaction_sender, + class_sender, + }; let p2p_sync = P2PSyncClient::new( p2p_sync_config, storage_reader.clone(), @@ -78,9 +93,10 @@ pub fn setup() -> TestArgs { TestArgs { p2p_sync, storage_reader, - header_receiver, - state_diff_receiver, - transaction_receiver, + mock_header_response_manager, + mock_state_diff_response_manager, + mock_transaction_response_manager, + mock_class_response_manager, } } diff --git a/crates/papyrus_proc_macros/Cargo.toml b/crates/papyrus_proc_macros/Cargo.toml index f6f42cc891..80b42fe681 100644 --- a/crates/papyrus_proc_macros/Cargo.toml +++ b/crates/papyrus_proc_macros/Cargo.toml @@ -7,8 +7,8 @@ license-file.workspace = true description = "Procedural macros for the Papyrus node" [dependencies] -quote = "1.0.26" -syn = { version = "2.0.39", features = ["full"] } +quote.workspace = true +syn = { workspace = true, features = ["full"] } tracing.workspace = true [dev-dependencies] diff --git a/crates/papyrus_proc_macros/src/lib.rs b/crates/papyrus_proc_macros/src/lib.rs index b04ef485fa..e063285f45 100644 --- a/crates/papyrus_proc_macros/src/lib.rs +++ b/crates/papyrus_proc_macros/src/lib.rs @@ -112,6 +112,7 @@ pub fn versioned_rpc(attr: TokenStream, input: TokenStream) -> TokenStream { } /// This macro will emit a histogram metric with the given name and the latency of the function. +/// /// In addition, also a debug log with the metric name and the execution time will be emitted. /// The macro also receives a boolean for whether it will be emitted only when /// profiling is activated or at all times. diff --git a/crates/papyrus_protobuf/Cargo.toml b/crates/papyrus_protobuf/Cargo.toml index dc25349a9f..86e1722cbc 100644 --- a/crates/papyrus_protobuf/Cargo.toml +++ b/crates/papyrus_protobuf/Cargo.toml @@ -9,6 +9,8 @@ license-file.workspace = true testing = ["papyrus_test_utils", "rand", "rand_chacha"] [dependencies] +# TODO(Guy): Remove after implementing broadcast streams. +futures.workspace = true indexmap.workspace = true lazy_static.workspace = true primitive-types.workspace = true @@ -28,6 +30,7 @@ papyrus_test_utils.workspace = true [build-dependencies] prost-build.workspace = true +protoc-prebuilt.workspace = true [package.metadata.cargo-machete] # The `rand` and `rand_chacha` crates are used in the `testing` feature, which is optional. diff --git a/crates/papyrus_protobuf/build.rs b/crates/papyrus_protobuf/build.rs index 91475765f3..12960d5605 100644 --- a/crates/papyrus_protobuf/build.rs +++ b/crates/papyrus_protobuf/build.rs @@ -1,41 +1,21 @@ use std::env; -use std::io::{Error, ErrorKind, Result}; -use std::process::Command; +use std::io::Result; fn main() -> Result<()> { println!("Building"); - let protoc = env::var("PROTOC").unwrap_or("protoc".to_string()); - - let protoc_version = String::from_utf8_lossy( - &Command::new(protoc).arg("--version").output().expect("Protoc is not installed.").stdout, - ) - .to_string(); - - let parts: Vec<&str> = protoc_version.split_whitespace().collect(); - let protoc_version_str = parts.get(1).expect("Failed to determine protoc version"); - let mut protoc_version_parts = protoc_version_str - .split('.') - .map(|part| part.parse::().expect("Error parsing protoc version")); - let major = protoc_version_parts.next().expect("Protoc version did not have a major number"); - let minor = protoc_version_parts.next().unwrap_or_default(); - - if major < 3 || (major == 3 && minor < 15) { - Err(Error::new( - ErrorKind::Other, - "protoc version is too old. version 3.15.x or greater is needed.", - )) - } else { - prost_build::compile_protos( - &[ - "src/proto/p2p/proto/class.proto", - "src/proto/p2p/proto/event.proto", - "src/proto/p2p/proto/header.proto", - "src/proto/p2p/proto/state.proto", - "src/proto/p2p/proto/transaction.proto", - "src/proto/p2p/proto/consensus.proto", - ], - &["src/proto/"], - )?; - Ok(()) - } + let (protoc_bin, _) = protoc_prebuilt::init("27.0").unwrap(); + env::set_var("PROTOC", protoc_bin); + prost_build::compile_protos( + &[ + "src/proto/p2p/proto/rpc_transaction.proto", + "src/proto/p2p/proto/class.proto", + "src/proto/p2p/proto/event.proto", + "src/proto/p2p/proto/header.proto", + "src/proto/p2p/proto/state.proto", + "src/proto/p2p/proto/transaction.proto", + "src/proto/p2p/proto/consensus.proto", + ], + &["src/proto/"], + )?; + Ok(()) } diff --git a/crates/papyrus_protobuf/src/consensus.rs b/crates/papyrus_protobuf/src/consensus.rs index ac168536a6..2b462e8d10 100644 --- a/crates/papyrus_protobuf/src/consensus.rs +++ b/crates/papyrus_protobuf/src/consensus.rs @@ -1,7 +1,10 @@ -use starknet_api::block::BlockHash; +use futures::channel::{mpsc, oneshot}; +use starknet_api::block::{BlockHash, BlockNumber}; use starknet_api::core::ContractAddress; use starknet_api::transaction::Transaction; +use crate::converters::ProtobufConversionError; + #[derive(Debug, Default, Hash, Clone, Eq, PartialEq)] pub struct Proposal { pub height: u64, @@ -41,3 +44,37 @@ impl ConsensusMessage { } } } +#[derive(Debug, Default, Clone, Hash, Eq, PartialEq)] +pub struct StreamMessage> + TryFrom, Error = ProtobufConversionError>> { + pub message: T, + pub stream_id: u64, + pub chunk_id: u64, + pub fin: bool, +} + +// TODO(Guy): Remove after implementing broadcast streams. +#[allow(missing_docs)] +pub struct ProposalWrapper(pub Proposal); + +impl From + for ( + (BlockNumber, u32, ContractAddress), + mpsc::Receiver, + oneshot::Receiver, + ) +{ + fn from(val: ProposalWrapper) -> Self { + let transactions: Vec = val.0.transactions.into_iter().collect(); + let proposal_init = (BlockNumber(val.0.height), val.0.round, val.0.proposer); + let (mut content_sender, content_receiver) = mpsc::channel(transactions.len()); + for tx in transactions { + content_sender.try_send(tx).expect("Send should succeed"); + } + content_sender.close_channel(); + + let (fin_sender, fin_receiver) = oneshot::channel(); + fin_sender.send(val.0.block_hash).expect("Send should succeed"); + + (proposal_init, content_receiver, fin_receiver) + } +} diff --git a/crates/papyrus_protobuf/src/converters/consensus.rs b/crates/papyrus_protobuf/src/converters/consensus.rs index ec185e2505..f01a569b31 100644 --- a/crates/papyrus_protobuf/src/converters/consensus.rs +++ b/crates/papyrus_protobuf/src/converters/consensus.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +#[path = "consensus_test.rs"] +mod consensus_test; use std::convert::{TryFrom, TryInto}; use prost::Message; @@ -5,7 +8,7 @@ use starknet_api::block::BlockHash; use starknet_api::hash::StarkHash; use starknet_api::transaction::Transaction; -use crate::consensus::{ConsensusMessage, Proposal, Vote, VoteType}; +use crate::consensus::{ConsensusMessage, Proposal, StreamMessage, Vote, VoteType}; use crate::converters::ProtobufConversionError; use crate::{auto_impl_into_and_try_from_vec_u8, protobuf}; @@ -107,6 +110,59 @@ impl From for protobuf::Vote { auto_impl_into_and_try_from_vec_u8!(Vote, protobuf::Vote); +impl> + TryFrom, Error = ProtobufConversionError>> + TryFrom for StreamMessage +{ + type Error = ProtobufConversionError; + + fn try_from(value: protobuf::StreamMessage) -> Result { + Ok(Self { + message: T::try_from(value.message)?, + stream_id: value.stream_id, + chunk_id: value.chunk_id, + fin: value.fin, + }) + } +} + +impl> + TryFrom, Error = ProtobufConversionError>> From> + for protobuf::StreamMessage +{ + fn from(value: StreamMessage) -> Self { + Self { + message: value.message.into(), + stream_id: value.stream_id, + chunk_id: value.chunk_id, + fin: value.fin, + } + } +} + +// Can't use auto_impl_into_and_try_from_vec_u8!(StreamMessage, protobuf::StreamMessage); +// because it doesn't seem to work with generics +// TODO(guyn): consider expanding the macro to support generics +impl> + TryFrom, Error = ProtobufConversionError>> From> + for Vec +{ + fn from(value: StreamMessage) -> Self { + let protobuf_value = ::from(value); + protobuf_value.encode_to_vec() + } +} + +impl> + TryFrom, Error = ProtobufConversionError>> TryFrom> + for StreamMessage +{ + type Error = ProtobufConversionError; + fn try_from(value: Vec) -> Result { + let protobuf_value = ::decode(&value[..])?; + match Self::try_from(protobuf_value) { + Ok(value) => Ok(value), + Err(e) => Err(e), + } + } +} + impl TryFrom for ConsensusMessage { type Error = ProtobufConversionError; diff --git a/crates/papyrus_protobuf/src/converters/consensus_test.rs b/crates/papyrus_protobuf/src/converters/consensus_test.rs new file mode 100644 index 0000000000..dd5911916e --- /dev/null +++ b/crates/papyrus_protobuf/src/converters/consensus_test.rs @@ -0,0 +1,31 @@ +use papyrus_test_utils::{get_rng, GetTestInstance}; +use rand::Rng; + +use crate::consensus::{ConsensusMessage, Proposal, StreamMessage}; + +// TODO(guyn): add tests for other serializable objects in consensus + +// TODO(guyn): try to make the macro work with generics +impl GetTestInstance for StreamMessage { + fn get_test_instance(rng: &mut rand_chacha::ChaCha8Rng) -> Self { + Self { + message: ConsensusMessage::Proposal(Proposal::default()), + stream_id: rng.gen_range(0..100), + chunk_id: rng.gen_range(0..1000), + fin: rng.gen_bool(0.5), + } + } +} + +#[test] +fn convert_stream_message_to_vec_u8_and_back() { + let mut rng = get_rng(); + + // test that we can convert a StreamMessage with a ConsensusMessage message to bytes and back + let stream_message: StreamMessage = + StreamMessage::get_test_instance(&mut rng); + + let bytes_data: Vec = stream_message.clone().into(); + let res_data = StreamMessage::try_from(bytes_data).unwrap(); + assert_eq!(stream_message, res_data); +} diff --git a/crates/papyrus_protobuf/src/converters/event_test.rs b/crates/papyrus_protobuf/src/converters/event_test.rs index 4a0a3cce58..c9dcdeadf0 100644 --- a/crates/papyrus_protobuf/src/converters/event_test.rs +++ b/crates/papyrus_protobuf/src/converters/event_test.rs @@ -11,8 +11,7 @@ fn convert_event_to_vec_u8_and_back() { let transaction_hash = TransactionHash::get_test_instance(&mut rng); let data = DataOrFin(Some((event, transaction_hash))); - let bytes_data = Vec::::from(data.clone()); - let res_data = DataOrFin::try_from(bytes_data).unwrap(); + let res_data = DataOrFin::try_from(data.clone()).unwrap(); assert_eq!(data, res_data); } diff --git a/crates/papyrus_protobuf/src/converters/mod.rs b/crates/papyrus_protobuf/src/converters/mod.rs index a4fbf14a31..0c3ab815dd 100644 --- a/crates/papyrus_protobuf/src/converters/mod.rs +++ b/crates/papyrus_protobuf/src/converters/mod.rs @@ -1,12 +1,12 @@ -// TODO(shahak): Internalize this once network doesn't depend on protobuf. mod class; -pub mod common; +mod common; +// TODO(matan): Internalize once we remove the dependency on the protobuf crate. pub mod consensus; mod event; mod header; mod receipt; -// TODO(shahak): Internalize this once network doesn't depend on protobuf. -pub mod state_diff; +mod rpc_transaction; +mod state_diff; mod transaction; use prost::DecodeError; diff --git a/crates/papyrus_protobuf/src/converters/rpc_transaction.rs b/crates/papyrus_protobuf/src/converters/rpc_transaction.rs new file mode 100644 index 0000000000..292e706736 --- /dev/null +++ b/crates/papyrus_protobuf/src/converters/rpc_transaction.rs @@ -0,0 +1,393 @@ +#[cfg(test)] +#[path = "rpc_transaction_test.rs"] +mod rpc_transaction_test; + +use prost::Message; +use starknet_api::rpc_transaction::{ + ContractClass, + EntryPointByType, + RpcDeclareTransaction, + RpcDeclareTransactionV3, + RpcDeployAccountTransaction, + RpcDeployAccountTransactionV3, + RpcInvokeTransaction, + RpcInvokeTransactionV3, + RpcTransaction, +}; +use starknet_api::state::EntryPoint; +use starknet_api::transaction::{ + AllResourceBounds, + DeclareTransactionV3, + DeployAccountTransactionV3, + InvokeTransactionV3, + ValidResourceBounds, +}; +use starknet_types_core::felt::Felt; + +use super::ProtobufConversionError; +use crate::auto_impl_into_and_try_from_vec_u8; +use crate::mempool::RpcTransactionWrapper; +use crate::protobuf::{self, Felt252}; + +auto_impl_into_and_try_from_vec_u8!(RpcTransactionWrapper, protobuf::RpcTransaction); + +impl TryFrom for RpcTransactionWrapper { + type Error = ProtobufConversionError; + fn try_from(value: protobuf::RpcTransaction) -> Result { + Ok(RpcTransactionWrapper(RpcTransaction::try_from(value)?)) + } +} +impl From for protobuf::RpcTransaction { + fn from(value: RpcTransactionWrapper) -> Self { + protobuf::RpcTransaction::from(value.0) + } +} + +impl TryFrom for RpcTransaction { + type Error = ProtobufConversionError; + fn try_from(value: protobuf::RpcTransaction) -> Result { + let txn = value.txn.ok_or(ProtobufConversionError::MissingField { + field_description: "RpcTransaction::txn", + })?; + Ok(match txn { + protobuf::rpc_transaction::Txn::DeclareV3(txn) => { + RpcTransaction::Declare(RpcDeclareTransaction::V3(txn.try_into()?)) + } + protobuf::rpc_transaction::Txn::DeployAccountV3(txn) => { + RpcTransaction::DeployAccount(RpcDeployAccountTransaction::V3(txn.try_into()?)) + } + protobuf::rpc_transaction::Txn::InvokeV3(txn) => { + RpcTransaction::Invoke(RpcInvokeTransaction::V3(txn.try_into()?)) + } + }) + } +} + +impl From for protobuf::RpcTransaction { + fn from(value: RpcTransaction) -> Self { + match value { + RpcTransaction::Declare(RpcDeclareTransaction::V3(txn)) => protobuf::RpcTransaction { + txn: Some(protobuf::rpc_transaction::Txn::DeclareV3(txn.into())), + }, + RpcTransaction::DeployAccount(RpcDeployAccountTransaction::V3(txn)) => { + protobuf::RpcTransaction { + txn: Some(protobuf::rpc_transaction::Txn::DeployAccountV3(txn.into())), + } + } + RpcTransaction::Invoke(RpcInvokeTransaction::V3(txn)) => protobuf::RpcTransaction { + txn: Some(protobuf::rpc_transaction::Txn::InvokeV3(txn.into())), + }, + } + } +} + +impl TryFrom for RpcDeclareTransactionV3 { + type Error = ProtobufConversionError; + fn try_from(value: protobuf::rpc_transaction::DeclareV3) -> Result { + let declare_v3 = value.declare_v3.ok_or(ProtobufConversionError::MissingField { + field_description: "DeclareV3::declare_v3", + })?; + let contract_class = value + .contract_class + .ok_or(ProtobufConversionError::MissingField { + field_description: "DeclareV3::contract_class", + })? + .try_into()?; + let DeclareTransactionV3 { + sender_address, + compiled_class_hash, + signature, + nonce, + resource_bounds, + class_hash: _, + tip, + paymaster_data, + account_deployment_data, + nonce_data_availability_mode, + fee_data_availability_mode, + } = declare_v3.try_into()?; + + let resource_bounds = match resource_bounds { + ValidResourceBounds::AllResources(resource_bounds) => resource_bounds, + ValidResourceBounds::L1Gas(resource_bounds) => AllResourceBounds { + l1_gas: resource_bounds, + l2_gas: Default::default(), + l1_data_gas: Default::default(), + }, + }; + + Ok(Self { + sender_address, + compiled_class_hash, + signature, + nonce, + contract_class, + resource_bounds, + tip, + paymaster_data, + account_deployment_data, + nonce_data_availability_mode, + fee_data_availability_mode, + }) + } +} + +impl From for protobuf::rpc_transaction::DeclareV3 { + fn from(value: RpcDeclareTransactionV3) -> Self { + let RpcDeclareTransactionV3 { + sender_address, + compiled_class_hash, + signature, + nonce, + contract_class, + resource_bounds, + tip, + paymaster_data, + account_deployment_data, + nonce_data_availability_mode, + fee_data_availability_mode, + } = value; + let declare_v3 = DeclareTransactionV3 { + resource_bounds: ValidResourceBounds::AllResources(resource_bounds), + tip, + signature, + nonce, + // TODO(Eitan): refactor the protobuf transaction to not have class_hash + class_hash: Default::default(), + compiled_class_hash, + sender_address, + nonce_data_availability_mode, + fee_data_availability_mode, + paymaster_data, + account_deployment_data, + }; + Self { contract_class: Some(contract_class.into()), declare_v3: Some(declare_v3.into()) } + } +} + +impl TryFrom for RpcDeployAccountTransactionV3 { + type Error = ProtobufConversionError; + fn try_from(value: protobuf::transaction::DeployAccountV3) -> Result { + let resource_bounds = value + .resource_bounds + .clone() + .ok_or(ProtobufConversionError::MissingField { + field_description: "DeployAccountV3::resource_bounds", + })? + .try_into()?; + let DeployAccountTransactionV3 { + resource_bounds: _, + tip, + signature, + nonce, + class_hash, + contract_address_salt, + constructor_calldata, + nonce_data_availability_mode, + fee_data_availability_mode, + paymaster_data, + } = value.try_into()?; + + Ok(Self { + resource_bounds, + tip, + signature, + nonce, + class_hash, + contract_address_salt, + constructor_calldata, + nonce_data_availability_mode, + fee_data_availability_mode, + paymaster_data, + }) + } +} + +impl From for protobuf::transaction::DeployAccountV3 { + fn from(value: RpcDeployAccountTransactionV3) -> Self { + let RpcDeployAccountTransactionV3 { + resource_bounds, + tip, + signature, + nonce, + class_hash, + contract_address_salt, + constructor_calldata, + nonce_data_availability_mode, + fee_data_availability_mode, + paymaster_data, + } = value; + DeployAccountTransactionV3 { + resource_bounds: ValidResourceBounds::AllResources(resource_bounds), + tip, + signature, + nonce, + class_hash, + contract_address_salt, + constructor_calldata, + nonce_data_availability_mode, + fee_data_availability_mode, + paymaster_data, + } + .into() + } +} + +impl TryFrom for RpcInvokeTransactionV3 { + type Error = ProtobufConversionError; + fn try_from(value: protobuf::transaction::InvokeV3) -> Result { + let resource_bounds = value + .resource_bounds + .clone() + .ok_or(ProtobufConversionError::MissingField { + field_description: "InvokeV3::resource_bounds", + })? + .try_into()?; + let InvokeTransactionV3 { + resource_bounds: _, + tip, + signature, + nonce, + sender_address, + calldata, + nonce_data_availability_mode, + fee_data_availability_mode, + paymaster_data, + account_deployment_data, + } = value.try_into()?; + Ok(Self { + resource_bounds, + tip, + signature, + nonce, + sender_address, + calldata, + nonce_data_availability_mode, + fee_data_availability_mode, + paymaster_data, + account_deployment_data, + }) + } +} + +impl From for protobuf::transaction::InvokeV3 { + fn from(value: RpcInvokeTransactionV3) -> Self { + let RpcInvokeTransactionV3 { + resource_bounds, + tip, + signature, + nonce, + sender_address, + calldata, + nonce_data_availability_mode, + fee_data_availability_mode, + paymaster_data, + account_deployment_data, + } = value; + InvokeTransactionV3 { + resource_bounds: ValidResourceBounds::AllResources(resource_bounds), + tip, + signature, + nonce, + sender_address, + calldata, + nonce_data_availability_mode, + fee_data_availability_mode, + paymaster_data, + account_deployment_data, + } + .into() + } +} + +impl TryFrom for AllResourceBounds { + type Error = ProtobufConversionError; + fn try_from(value: protobuf::ResourceBounds) -> Result { + Ok(Self { + l1_gas: value + .l1_gas + .ok_or(ProtobufConversionError::MissingField { + field_description: "ResourceBounds::l1_gas", + })? + .try_into()?, + l2_gas: value + .l2_gas + .ok_or(ProtobufConversionError::MissingField { + field_description: "ResourceBounds::l2_gas", + })? + .try_into()?, + l1_data_gas: value + .l1_data_gas + .ok_or(ProtobufConversionError::MissingField { + field_description: "ResourceBounds::l1_data_gas", + })? + .try_into()?, + }) + } +} + +impl From for protobuf::ResourceBounds { + fn from(value: AllResourceBounds) -> Self { + ValidResourceBounds::AllResources(value).into() + } +} + +impl TryFrom for ContractClass { + type Error = ProtobufConversionError; + fn try_from(value: protobuf::Cairo1Class) -> Result { + let sierra_program = + value.program.into_iter().map(Felt::try_from).collect::, _>>()?; + let contract_class_version = value.contract_class_version; + let entry_points = value.entry_points.ok_or(ProtobufConversionError::MissingField { + field_description: "Cairo1Class::entry_points_by_type", + })?; + let entry_points_by_type = EntryPointByType { + constructor: entry_points + .constructors + .into_iter() + .map(EntryPoint::try_from) + .collect::, _>>()?, + external: entry_points + .externals + .into_iter() + .map(EntryPoint::try_from) + .collect::, _>>()?, + l1handler: entry_points + .l1_handlers + .into_iter() + .map(EntryPoint::try_from) + .collect::, _>>()?, + }; + let abi = value.abi; + Ok(Self { sierra_program, contract_class_version, entry_points_by_type, abi }) + } +} + +impl From for protobuf::Cairo1Class { + fn from(value: ContractClass) -> Self { + let program = value.sierra_program.into_iter().map(Felt252::from).collect(); + let contract_class_version = value.contract_class_version; + let entry_points = protobuf::Cairo1EntryPoints { + constructors: value + .entry_points_by_type + .constructor + .into_iter() + .map(protobuf::SierraEntryPoint::from) + .collect(), + externals: value + .entry_points_by_type + .external + .into_iter() + .map(protobuf::SierraEntryPoint::from) + .collect(), + l1_handlers: value + .entry_points_by_type + .l1handler + .into_iter() + .map(protobuf::SierraEntryPoint::from) + .collect(), + }; + let abi = value.abi; + Self { program, contract_class_version, entry_points: Some(entry_points), abi } + } +} diff --git a/crates/papyrus_protobuf/src/converters/rpc_transaction_test.rs b/crates/papyrus_protobuf/src/converters/rpc_transaction_test.rs new file mode 100644 index 0000000000..337861cf13 --- /dev/null +++ b/crates/papyrus_protobuf/src/converters/rpc_transaction_test.rs @@ -0,0 +1,61 @@ +use lazy_static::lazy_static; +use papyrus_test_utils::{get_rng, GetTestInstance}; +use starknet_api::rpc_transaction::{ + RpcDeclareTransaction, + RpcDeclareTransactionV3, + RpcDeployAccountTransaction, + RpcDeployAccountTransactionV3, + RpcInvokeTransaction, + RpcInvokeTransactionV3, + RpcTransaction, +}; +use starknet_api::transaction::{AllResourceBounds, ResourceBounds}; + +use crate::mempool::RpcTransactionWrapper; + +#[test] +fn convert_declare_transaction_v3_to_vec_u8_and_back() { + let mut rng = get_rng(); + let mut rpc_transaction = RpcDeclareTransactionV3::get_test_instance(&mut rng); + rpc_transaction.resource_bounds = RESOURCE_BOUNDS_MAPPING.clone(); + let rpc_transaction = RpcTransaction::Declare(RpcDeclareTransaction::V3(rpc_transaction)); + + assert_transaction_to_vec_u8_and_back(rpc_transaction); +} + +#[test] +fn convert_invoke_transaction_v3_to_vec_u8_and_back() { + let mut rng = get_rng(); + let mut rpc_transaction = RpcInvokeTransactionV3::get_test_instance(&mut rng); + + rpc_transaction.resource_bounds = RESOURCE_BOUNDS_MAPPING.clone(); + let rpc_transaction = RpcTransaction::Invoke(RpcInvokeTransaction::V3(rpc_transaction)); + + assert_transaction_to_vec_u8_and_back(rpc_transaction); +} + +#[test] +fn convert_deploy_account_transaction_v3_to_vec_u8_and_back() { + let mut rng = get_rng(); + let mut rpc_transaction = RpcDeployAccountTransactionV3::get_test_instance(&mut rng); + rpc_transaction.resource_bounds = RESOURCE_BOUNDS_MAPPING.clone(); + let rpc_transaction = + RpcTransaction::DeployAccount(RpcDeployAccountTransaction::V3(rpc_transaction)); + + assert_transaction_to_vec_u8_and_back(rpc_transaction); +} + +fn assert_transaction_to_vec_u8_and_back(transaction: RpcTransaction) { + let data = RpcTransactionWrapper(transaction.clone()); + let bytes_data = Vec::::from(data); + let res_data = RpcTransactionWrapper::try_from(bytes_data).unwrap(); + assert_eq!(RpcTransactionWrapper(transaction), res_data); +} + +lazy_static! { + static ref RESOURCE_BOUNDS_MAPPING: AllResourceBounds = AllResourceBounds { + l1_gas: ResourceBounds { max_amount: 0x5, max_price_per_unit: 0x6 }, + l2_gas: ResourceBounds { max_amount: 0x6, max_price_per_unit: 0x7 }, + l1_data_gas: ResourceBounds { max_amount: 0x7, max_price_per_unit: 0x8 }, + }; +} diff --git a/crates/papyrus_protobuf/src/converters/transaction.rs b/crates/papyrus_protobuf/src/converters/transaction.rs index a929942c1a..3179088ce6 100644 --- a/crates/papyrus_protobuf/src/converters/transaction.rs +++ b/crates/papyrus_protobuf/src/converters/transaction.rs @@ -7,6 +7,7 @@ use prost::Message; use starknet_api::core::{ClassHash, CompiledClassHash, EntryPointSelector, Nonce}; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeclareTransaction, @@ -17,7 +18,6 @@ use starknet_api::transaction::{ DeployAccountTransactionV1, DeployAccountTransactionV3, DeployTransaction, - DeprecatedResourceBoundsMapping, Fee, FullTransaction, InvokeTransaction, @@ -26,7 +26,6 @@ use starknet_api::transaction::{ InvokeTransactionV3, L1HandlerTransaction, PaymasterData, - Resource, ResourceBounds, Tip, Transaction, @@ -34,6 +33,7 @@ use starknet_api::transaction::{ TransactionOutput, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; @@ -440,11 +440,11 @@ impl From for protobuf::transaction::DeployAccountV1 impl TryFrom for DeployAccountTransactionV3 { type Error = ProtobufConversionError; fn try_from(value: protobuf::transaction::DeployAccountV3) -> Result { - let resource_bounds = DeprecatedResourceBoundsMapping::try_from( - value.resource_bounds.ok_or(ProtobufConversionError::MissingField { + let resource_bounds = ValidResourceBounds::try_from(value.resource_bounds.ok_or( + ProtobufConversionError::MissingField { field_description: "DeployAccountV3::resource_bounds", - })?, - )?; + }, + )?)?; let tip = Tip(value.tip); @@ -550,41 +550,39 @@ impl From for protobuf::transaction::DeployAccountV3 } } -impl TryFrom for DeprecatedResourceBoundsMapping { +impl TryFrom for ValidResourceBounds { type Error = ProtobufConversionError; fn try_from(value: protobuf::ResourceBounds) -> Result { - let mut resource_bounds = DeprecatedResourceBoundsMapping::default(); let Some(l1_gas) = value.l1_gas else { return Err(ProtobufConversionError::MissingField { field_description: "ResourceBounds::l1_gas", }); }; - let max_amount = l1_gas.max_amount; - let max_price_per_unit_felt = Felt::try_from(l1_gas.max_price_per_unit.ok_or( - ProtobufConversionError::MissingField { - field_description: "ResourceBounds::l1_gas::max_price_per_unit", - }, - )?)?; - let max_price_per_unit = - try_from_starkfelt_to_u128(max_price_per_unit_felt).map_err(|_| { - ProtobufConversionError::OutOfRangeValue { - type_description: "u128", - value_as_str: format!("{max_price_per_unit_felt:?}"), - } - })?; - - resource_bounds - .0 - .insert(Resource::L1Gas, ResourceBounds { max_amount, max_price_per_unit }); let Some(l2_gas) = value.l2_gas else { return Err(ProtobufConversionError::MissingField { field_description: "ResourceBounds::l2_gas", }); }; - let max_amount = l2_gas.max_amount; - let max_price_per_unit_felt = Felt::try_from(l2_gas.max_price_per_unit.ok_or( + // TODO(Shahak): Assert data gas is not none once we remove support for 0.13.2. + let l1_data_gas = value.l1_data_gas.unwrap_or_default(); + let l1_gas: ResourceBounds = l1_gas.try_into()?; + let l2_gas: ResourceBounds = l2_gas.try_into()?; + let l1_data_gas: ResourceBounds = l1_data_gas.try_into()?; + Ok(if l1_data_gas.is_zero() && l2_gas.is_zero() { + ValidResourceBounds::L1Gas(l1_gas) + } else { + ValidResourceBounds::AllResources(AllResourceBounds { l1_gas, l2_gas, l1_data_gas }) + }) + } +} + +impl TryFrom for ResourceBounds { + type Error = ProtobufConversionError; + fn try_from(value: protobuf::ResourceLimits) -> Result { + let max_amount = value.max_amount; + let max_price_per_unit_felt = Felt::try_from(value.max_price_per_unit.ok_or( ProtobufConversionError::MissingField { - field_description: "ResourceBounds::l2_gas::max_price_per_unit", + field_description: "ResourceBounds::ResourceLimits::max_price_per_unit", }, )?)?; let max_price_per_unit = @@ -594,36 +592,37 @@ impl TryFrom for DeprecatedResourceBoundsMapping { value_as_str: format!("{max_price_per_unit_felt:?}"), } })?; - resource_bounds - .0 - .insert(Resource::L2Gas, ResourceBounds { max_amount, max_price_per_unit }); - Ok(resource_bounds) + Ok(ResourceBounds { max_amount, max_price_per_unit }) } } -impl From for protobuf::ResourceBounds { - fn from(value: DeprecatedResourceBoundsMapping) -> Self { - let mut res = protobuf::ResourceBounds::default(); - - let resource_bounds_default = ResourceBounds::default(); - let resource_bounds_l1 = value.0.get(&Resource::L1Gas).unwrap_or(&resource_bounds_default); - - let resource_limits_l1 = protobuf::ResourceLimits { - max_amount: resource_bounds_l1.max_amount, - max_price_per_unit: Some(Felt::from(resource_bounds_l1.max_price_per_unit).into()), - }; - res.l1_gas = Some(resource_limits_l1); - - let resource_bounds_default = ResourceBounds::default(); - let resource_bounds_l2 = value.0.get(&Resource::L2Gas).unwrap_or(&resource_bounds_default); - - let resource_limits_l2 = protobuf::ResourceLimits { - max_amount: resource_bounds_l2.max_amount, - max_price_per_unit: Some(Felt::from(resource_bounds_l2.max_price_per_unit).into()), - }; - res.l2_gas = Some(resource_limits_l2); +impl From for protobuf::ResourceLimits { + fn from(value: ResourceBounds) -> Self { + protobuf::ResourceLimits { + max_amount: value.max_amount, + max_price_per_unit: Some(Felt::from(value.max_price_per_unit).into()), + } + } +} - res +impl From for protobuf::ResourceBounds { + fn from(value: ValidResourceBounds) -> Self { + match value { + ValidResourceBounds::L1Gas(l1_gas) => protobuf::ResourceBounds { + l1_gas: Some(l1_gas.into()), + l2_gas: Some(value.get_l2_bounds().into()), + l1_data_gas: Some(ResourceBounds::default().into()), + }, + ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas, + l2_gas, + l1_data_gas, + }) => protobuf::ResourceBounds { + l1_gas: Some(l1_gas.into()), + l2_gas: Some(l2_gas.into()), + l1_data_gas: Some(l1_data_gas.into()), + }, + } } } @@ -756,11 +755,11 @@ impl From for protobuf::transaction::InvokeV1 { impl TryFrom for InvokeTransactionV3 { type Error = ProtobufConversionError; fn try_from(value: protobuf::transaction::InvokeV3) -> Result { - let resource_bounds = DeprecatedResourceBoundsMapping::try_from( - value.resource_bounds.ok_or(ProtobufConversionError::MissingField { + let resource_bounds = ValidResourceBounds::try_from(value.resource_bounds.ok_or( + ProtobufConversionError::MissingField { field_description: "InvokeV3::resource_bounds", - })?, - )?; + }, + )?)?; let tip = Tip(value.tip); @@ -1074,11 +1073,11 @@ impl From for protobuf::transaction::DeclareV2 { impl TryFrom for DeclareTransactionV3 { type Error = ProtobufConversionError; fn try_from(value: protobuf::transaction::DeclareV3) -> Result { - let resource_bounds = DeprecatedResourceBoundsMapping::try_from( - value.resource_bounds.ok_or(ProtobufConversionError::MissingField { + let resource_bounds = ValidResourceBounds::try_from(value.resource_bounds.ok_or( + ProtobufConversionError::MissingField { field_description: "DeclareV3::resource_bounds", - })?, - )?; + }, + )?)?; let tip = Tip(value.tip); diff --git a/crates/papyrus_protobuf/src/converters/transaction_test.rs b/crates/papyrus_protobuf/src/converters/transaction_test.rs index 82387f1539..88b3c4d639 100644 --- a/crates/papyrus_protobuf/src/converters/transaction_test.rs +++ b/crates/papyrus_protobuf/src/converters/transaction_test.rs @@ -3,21 +3,21 @@ use papyrus_test_utils::{get_rng, GetTestInstance}; use rand::random; use starknet_api::execution_resources::{Builtin, ExecutionResources, GasVector}; use starknet_api::transaction::{ + AllResourceBounds, DeclareTransaction, DeclareTransactionOutput, DeployAccountTransaction, DeployAccountTransactionOutput, DeployTransactionOutput, - DeprecatedResourceBoundsMapping, FullTransaction, InvokeTransaction, InvokeTransactionOutput, L1HandlerTransactionOutput, - Resource, ResourceBounds, Transaction as StarknetApiTransaction, TransactionHash, TransactionOutput, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; @@ -40,7 +40,7 @@ fn convert_l1_handler_transaction_to_vec_u8_and_back() { let transaction = StarknetApiTransaction::L1Handler(transaction); let transaction_output = create_transaction_output!(L1HandlerTransactionOutput, L1Handler); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -50,7 +50,7 @@ fn convert_deploy_transaction_to_vec_u8_and_back() { let transaction = StarknetApiTransaction::Deploy(transaction); let transaction_output = create_transaction_output!(DeployTransactionOutput, Deploy); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -61,7 +61,7 @@ fn convert_declare_transaction_v0_to_vec_u8_and_back() { let transaction = StarknetApiTransaction::Declare(DeclareTransaction::V0(transaction)); let transaction_output = create_transaction_output!(DeclareTransactionOutput, Declare); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -72,7 +72,7 @@ fn convert_declare_transaction_v1_to_vec_u8_and_back() { let transaction = StarknetApiTransaction::Declare(DeclareTransaction::V1(transaction)); let transaction_output = create_transaction_output!(DeclareTransactionOutput, Declare); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -82,7 +82,7 @@ fn convert_declare_transaction_v2_to_vec_u8_and_back() { let transaction = StarknetApiTransaction::Declare(DeclareTransaction::V2(transaction)); let transaction_output = create_transaction_output!(DeclareTransactionOutput, Declare); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -94,7 +94,7 @@ fn convert_declare_transaction_v3_to_vec_u8_and_back() { let transaction = StarknetApiTransaction::Declare(DeclareTransaction::V3(transaction)); let transaction_output = create_transaction_output!(DeclareTransactionOutput, Declare); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -104,7 +104,7 @@ fn convert_invoke_transaction_v0_to_vec_u8_and_back() { let transaction = StarknetApiTransaction::Invoke(InvokeTransaction::V0(transaction)); let transaction_output = create_transaction_output!(InvokeTransactionOutput, Invoke); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -114,7 +114,7 @@ fn convert_invoke_transaction_v1_to_vec_u8_and_back() { let transaction = StarknetApiTransaction::Invoke(InvokeTransaction::V1(transaction)); let transaction_output = create_transaction_output!(InvokeTransactionOutput, Invoke); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -126,7 +126,7 @@ fn convert_invoke_transaction_v3_to_vec_u8_and_back() { let transaction = StarknetApiTransaction::Invoke(InvokeTransaction::V3(transaction)); let transaction_output = create_transaction_output!(InvokeTransactionOutput, Invoke); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -139,7 +139,7 @@ fn convert_deploy_account_transaction_v1_to_vec_u8_and_back() { let transaction_output = create_transaction_output!(DeployAccountTransactionOutput, DeployAccount); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -153,7 +153,7 @@ fn convert_deploy_account_transaction_v3_to_vec_u8_and_back() { let transaction_output = create_transaction_output!(DeployAccountTransactionOutput, DeployAccount); - convert_transaction_to_vec_u8_and_back(transaction, transaction_output); + assert_transaction_to_vec_u8_and_back(transaction, transaction_output); } #[test] @@ -164,7 +164,7 @@ fn fin_transaction_to_bytes_and_back() { assert!(res_data.0.is_none()); } -fn convert_transaction_to_vec_u8_and_back( +fn assert_transaction_to_vec_u8_and_back( transaction: StarknetApiTransaction, transaction_output: TransactionOutput, ) { @@ -196,13 +196,10 @@ lazy_static! { da_gas_consumed: GasVector::default(), gas_consumed: GasVector::default(), }; - static ref RESOURCE_BOUNDS_MAPPING: DeprecatedResourceBoundsMapping = - DeprecatedResourceBoundsMapping( - [ - (Resource::L1Gas, ResourceBounds { max_amount: 0x5, max_price_per_unit: 0x6 }), - (Resource::L2Gas, ResourceBounds { max_amount: 0x5, max_price_per_unit: 0x6 }), - ] - .into_iter() - .collect(), - ); + static ref RESOURCE_BOUNDS_MAPPING: ValidResourceBounds = + ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas: ResourceBounds { max_amount: 0x5, max_price_per_unit: 0x6 }, + l2_gas: ResourceBounds { max_amount: 0x500, max_price_per_unit: 0x600 }, + l1_data_gas: ResourceBounds { max_amount: 0x30, max_price_per_unit: 0x30 } + }); } diff --git a/crates/papyrus_protobuf/src/lib.rs b/crates/papyrus_protobuf/src/lib.rs index 05003d81ca..1ead9a2a16 100644 --- a/crates/papyrus_protobuf/src/lib.rs +++ b/crates/papyrus_protobuf/src/lib.rs @@ -2,5 +2,6 @@ pub mod converters; // TODO(shahak): Internalize this once network doesn't depend on protobuf. pub mod consensus; +pub mod mempool; pub mod protobuf; pub mod sync; diff --git a/crates/papyrus_protobuf/src/mempool.rs b/crates/papyrus_protobuf/src/mempool.rs new file mode 100644 index 0000000000..aec5c8ba37 --- /dev/null +++ b/crates/papyrus_protobuf/src/mempool.rs @@ -0,0 +1,4 @@ +use starknet_api::rpc_transaction::RpcTransaction; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct RpcTransactionWrapper(pub RpcTransaction); diff --git a/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto b/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto index 47d0538f08..20f0f85385 100644 --- a/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto +++ b/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto @@ -32,4 +32,11 @@ message ConsensusMessage { Proposal proposal = 1; Vote vote = 2; } -} \ No newline at end of file +} + +message StreamMessage { + bytes message = 1; + uint64 stream_id = 2; + uint64 chunk_id = 3; + bool fin = 4; +} diff --git a/crates/papyrus_protobuf/src/proto/p2p/proto/rpc_transaction.proto b/crates/papyrus_protobuf/src/proto/p2p/proto/rpc_transaction.proto new file mode 100644 index 0000000000..672ad3dc08 --- /dev/null +++ b/crates/papyrus_protobuf/src/proto/p2p/proto/rpc_transaction.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +import "p2p/proto/class.proto"; +import "p2p/proto/common.proto"; +import "p2p/proto/transaction.proto"; + +message RpcTransaction +{ + message DeclareV3 { + Transaction.DeclareV3 declare_v3 = 1; + Cairo1Class contract_class = 2; + } + + oneof txn { + DeclareV3 declare_v3 = 1; + Transaction.DeployAccountV3 deploy_account_v3 = 2; + Transaction.InvokeV3 invoke_v3 = 3; + } +} diff --git a/crates/papyrus_protobuf/src/proto/p2p/proto/transaction.proto b/crates/papyrus_protobuf/src/proto/p2p/proto/transaction.proto index 9ab1244cf5..33065edd51 100644 --- a/crates/papyrus_protobuf/src/proto/p2p/proto/transaction.proto +++ b/crates/papyrus_protobuf/src/proto/p2p/proto/transaction.proto @@ -10,6 +10,7 @@ message ResourceLimits { message ResourceBounds { ResourceLimits l1_gas = 1; ResourceLimits l2_gas = 2; + ResourceLimits l1_data_gas = 3; } message AccountSignature { diff --git a/crates/papyrus_rpc/src/v0_6/api/mod.rs b/crates/papyrus_rpc/src/v0_6/api/mod.rs index 6c20c3db50..eb44f5eb63 100644 --- a/crates/papyrus_rpc/src/v0_6/api/mod.rs +++ b/crates/papyrus_rpc/src/v0_6/api/mod.rs @@ -334,8 +334,10 @@ impl TryFrom for ExecutableTransactionInput { // TODO(yair): pass the right value for only_query field. match value { BroadcastedTransaction::Declare(tx) => Ok(tx.try_into()?), - BroadcastedTransaction::DeployAccount(tx) => Ok(Self::DeployAccount(tx.into(), false)), - BroadcastedTransaction::Invoke(tx) => Ok(Self::Invoke(tx.into(), false)), + BroadcastedTransaction::DeployAccount(tx) => { + Ok(Self::DeployAccount(tx.try_into()?, false)) + } + BroadcastedTransaction::Invoke(tx) => Ok(Self::Invoke(tx.try_into()?, false)), } } } @@ -522,9 +524,10 @@ fn user_deprecated_contract_class_to_sn_api( }) } -impl From for starknet_api::transaction::DeployAccountTransaction { - fn from(tx: DeployAccountTransaction) -> Self { - match tx { +impl TryFrom for starknet_api::transaction::DeployAccountTransaction { + type Error = ErrorObjectOwned; + fn try_from(tx: DeployAccountTransaction) -> Result { + Ok(match tx { DeployAccountTransaction::Version1(DeployAccountTransactionV1 { max_fee, signature, @@ -554,7 +557,7 @@ impl From for starknet_api::transaction::DeployAccount nonce_data_availability_mode, fee_data_availability_mode, }) => Self::V3(starknet_api::transaction::DeployAccountTransactionV3 { - resource_bounds: resource_bounds.into(), + resource_bounds: resource_bounds.try_into()?, tip, signature, nonce, @@ -565,13 +568,14 @@ impl From for starknet_api::transaction::DeployAccount fee_data_availability_mode, paymaster_data, }), - } + }) } } -impl From for starknet_api::transaction::InvokeTransaction { - fn from(value: InvokeTransaction) -> Self { - match value { +impl TryFrom for starknet_api::transaction::InvokeTransaction { + type Error = ErrorObjectOwned; + fn try_from(value: InvokeTransaction) -> Result { + Ok(match value { InvokeTransaction::Version0(InvokeTransactionV0 { max_fee, version: _, @@ -613,7 +617,7 @@ impl From for starknet_api::transaction::InvokeTransaction { nonce_data_availability_mode, fee_data_availability_mode, }) => Self::V3(starknet_api::transaction::InvokeTransactionV3 { - resource_bounds: resource_bounds.into(), + resource_bounds: resource_bounds.try_into()?, tip, signature, nonce, @@ -624,7 +628,7 @@ impl From for starknet_api::transaction::InvokeTransaction { paymaster_data, account_deployment_data, }), - } + }) } } diff --git a/crates/papyrus_rpc/src/v0_6/execution_test.rs b/crates/papyrus_rpc/src/v0_6/execution_test.rs index 5129d2d866..f0f775cf09 100644 --- a/crates/papyrus_rpc/src/v0_6/execution_test.rs +++ b/crates/papyrus_rpc/src/v0_6/execution_test.rs @@ -155,16 +155,16 @@ lazy_static! { // TODO(yair): verify this is the correct fee, got this value by printing the result of the // call. pub static ref EXPECTED_FEE_ESTIMATE: FeeEstimate = FeeEstimate { - gas_consumed: felt!("0x680"), + gas_consumed: felt!("0x681"), gas_price: GAS_PRICE.price_in_wei, - overall_fee: Fee(166400000000000,), + overall_fee: Fee(166500000000000,), unit: PriceUnit::Wei, }; pub static ref EXPECTED_FEE_ESTIMATE_SKIP_VALIDATE: FeeEstimate = FeeEstimate { - gas_consumed: felt!("0x680"), + gas_consumed: felt!("0x681"), gas_price: GAS_PRICE.price_in_wei, - overall_fee: Fee(166400000000000,), + overall_fee: Fee(166500000000000,), unit: PriceUnit::Wei, }; diff --git a/crates/papyrus_rpc/src/v0_6/transaction.rs b/crates/papyrus_rpc/src/v0_6/transaction.rs index 9bed607338..d2c4133220 100644 --- a/crates/papyrus_rpc/src/v0_6/transaction.rs +++ b/crates/papyrus_rpc/src/v0_6/transaction.rs @@ -27,6 +27,7 @@ use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::serde_utils::bytes_from_hex_str; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeployTransaction, @@ -157,6 +158,32 @@ impl From for starknet_api::transaction::DeprecatedResour } } +impl TryFrom for starknet_api::transaction::ValidResourceBounds { + type Error = ErrorObjectOwned; + fn try_from(value: ResourceBoundsMapping) -> Result { + if !value.l2_gas.is_zero() { + Err(internal_server_error("Got a transaction with non zero l2 gas.")) + } else { + Ok(Self::L1Gas(value.l1_gas)) + } + } +} + +impl From for ResourceBoundsMapping { + fn from(value: starknet_api::transaction::ValidResourceBounds) -> Self { + match value { + starknet_api::transaction::ValidResourceBounds::L1Gas(l1_gas) => { + Self { l1_gas, l2_gas: ResourceBounds::default() } + } + starknet_api::transaction::ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas, + l2_gas, + .. + }) => Self { l1_gas, l2_gas }, + } + } +} + impl From for ResourceBoundsMapping { fn from(value: starknet_api::transaction::DeprecatedResourceBoundsMapping) -> Self { Self { diff --git a/crates/papyrus_rpc/src/v0_7/api/mod.rs b/crates/papyrus_rpc/src/v0_7/api/mod.rs index a19000eaf0..0c1492bc42 100644 --- a/crates/papyrus_rpc/src/v0_7/api/mod.rs +++ b/crates/papyrus_rpc/src/v0_7/api/mod.rs @@ -331,8 +331,10 @@ impl TryFrom for ExecutableTransactionInput { // TODO(yair): pass the right value for only_query field. match value { BroadcastedTransaction::Declare(tx) => Ok(tx.try_into()?), - BroadcastedTransaction::DeployAccount(tx) => Ok(Self::DeployAccount(tx.into(), false)), - BroadcastedTransaction::Invoke(tx) => Ok(Self::Invoke(tx.into(), false)), + BroadcastedTransaction::DeployAccount(tx) => { + Ok(Self::DeployAccount(tx.try_into()?, false)) + } + BroadcastedTransaction::Invoke(tx) => Ok(Self::Invoke(tx.try_into()?, false)), } } } @@ -519,9 +521,10 @@ fn user_deprecated_contract_class_to_sn_api( }) } -impl From for starknet_api::transaction::DeployAccountTransaction { - fn from(tx: DeployAccountTransaction) -> Self { - match tx { +impl TryFrom for starknet_api::transaction::DeployAccountTransaction { + type Error = ErrorObjectOwned; + fn try_from(tx: DeployAccountTransaction) -> Result { + Ok(match tx { DeployAccountTransaction::Version1(DeployAccountTransactionV1 { max_fee, signature, @@ -551,7 +554,7 @@ impl From for starknet_api::transaction::DeployAccount nonce_data_availability_mode, fee_data_availability_mode, }) => Self::V3(starknet_api::transaction::DeployAccountTransactionV3 { - resource_bounds: resource_bounds.into(), + resource_bounds: resource_bounds.try_into()?, tip, signature, nonce, @@ -562,13 +565,14 @@ impl From for starknet_api::transaction::DeployAccount fee_data_availability_mode, paymaster_data, }), - } + }) } } -impl From for starknet_api::transaction::InvokeTransaction { - fn from(value: InvokeTransaction) -> Self { - match value { +impl TryFrom for starknet_api::transaction::InvokeTransaction { + type Error = ErrorObjectOwned; + fn try_from(value: InvokeTransaction) -> Result { + Ok(match value { InvokeTransaction::Version0(InvokeTransactionV0 { max_fee, version: _, @@ -610,7 +614,7 @@ impl From for starknet_api::transaction::InvokeTransaction { nonce_data_availability_mode, fee_data_availability_mode, }) => Self::V3(starknet_api::transaction::InvokeTransactionV3 { - resource_bounds: resource_bounds.into(), + resource_bounds: resource_bounds.try_into()?, tip, signature, nonce, @@ -621,7 +625,7 @@ impl From for starknet_api::transaction::InvokeTransaction { paymaster_data, account_deployment_data, }), - } + }) } } diff --git a/crates/papyrus_rpc/src/v0_7/execution_test.rs b/crates/papyrus_rpc/src/v0_7/execution_test.rs index 107af2f353..438d7b081b 100644 --- a/crates/papyrus_rpc/src/v0_7/execution_test.rs +++ b/crates/papyrus_rpc/src/v0_7/execution_test.rs @@ -171,20 +171,20 @@ lazy_static! { // TODO(yair): verify this is the correct fee, got this value by printing the result of the // call. pub static ref EXPECTED_FEE_ESTIMATE: FeeEstimation = FeeEstimation { - gas_consumed: felt!("0x680"), + gas_consumed: felt!("0x681"), gas_price: GAS_PRICE.price_in_wei, data_gas_consumed: Felt::ZERO, data_gas_price: DATA_GAS_PRICE.price_in_wei, - overall_fee: Fee(166400000000000,), + overall_fee: Fee(166500000000000,), unit: PriceUnit::Wei, }; pub static ref EXPECTED_FEE_ESTIMATE_SKIP_VALIDATE: FeeEstimation = FeeEstimation { - gas_consumed: felt!("0x680"), + gas_consumed: felt!("0x681"), gas_price: GAS_PRICE.price_in_wei, data_gas_consumed: Felt::ZERO, data_gas_price: DATA_GAS_PRICE.price_in_wei, - overall_fee: Fee(166400000000000,), + overall_fee: Fee(166500000000000,), unit: PriceUnit::Wei, }; diff --git a/crates/papyrus_rpc/src/v0_7/transaction.rs b/crates/papyrus_rpc/src/v0_7/transaction.rs index 8f4596b664..c246ad5bb7 100644 --- a/crates/papyrus_rpc/src/v0_7/transaction.rs +++ b/crates/papyrus_rpc/src/v0_7/transaction.rs @@ -29,6 +29,7 @@ use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::serde_utils::bytes_from_hex_str; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeployTransaction, @@ -169,6 +170,32 @@ impl From for Resour } } +impl TryFrom for starknet_api::transaction::ValidResourceBounds { + type Error = ErrorObjectOwned; + fn try_from(value: ResourceBoundsMapping) -> Result { + if !value.l2_gas.is_zero() { + Err(internal_server_error("Got a transaction with non zero l2 gas.")) + } else { + Ok(Self::L1Gas(value.l1_gas)) + } + } +} + +impl From for ResourceBoundsMapping { + fn from(value: starknet_api::transaction::ValidResourceBounds) -> Self { + match value { + starknet_api::transaction::ValidResourceBounds::L1Gas(l1_gas) => { + Self { l1_gas, l2_gas: ResourceBounds::default() } + } + starknet_api::transaction::ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas, + l2_gas, + .. + }) => Self { l1_gas, l2_gas }, + } + } +} + #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] pub struct DeclareTransactionV3 { pub resource_bounds: ResourceBoundsMapping, diff --git a/crates/papyrus_rpc/tests/gateway_integration_test.rs b/crates/papyrus_rpc/tests/gateway_integration_test.rs index 2b8e238cc0..3d01d547a4 100644 --- a/crates/papyrus_rpc/tests/gateway_integration_test.rs +++ b/crates/papyrus_rpc/tests/gateway_integration_test.rs @@ -102,7 +102,9 @@ async fn test_gw_integration_testnet() { // Update the signature. let hash = get_transaction_hash( - &Transaction::Invoke(InvokeTransactionRPC0_6::Version1(invoke_tx.clone()).into()), + &Transaction::Invoke( + InvokeTransactionRPC0_6::Version1(invoke_tx.clone()).try_into().unwrap(), + ), &ChainId::Sepolia, &TransactionOptions::default(), ) diff --git a/crates/papyrus_storage/src/serialization/serializers.rs b/crates/papyrus_storage/src/serialization/serializers.rs index 2b19e9b01b..f707da82ac 100644 --- a/crates/papyrus_storage/src/serialization/serializers.rs +++ b/crates/papyrus_storage/src/serialization/serializers.rs @@ -76,6 +76,7 @@ use starknet_api::state::{ }; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeclareTransaction, @@ -89,7 +90,6 @@ use starknet_api::transaction::{ DeployAccountTransactionV3, DeployTransaction, DeployTransactionOutput, - DeprecatedResourceBoundsMapping, Event, EventContent, EventData, @@ -119,6 +119,7 @@ use starknet_api::transaction::{ TransactionOutput, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; use tracing::warn; @@ -147,6 +148,11 @@ const COMPRESSION_THRESHOLD_BYTES: usize = 384; auto_storage_serde! { pub struct AccountDeploymentData(pub Vec); + pub struct AllResourceBounds { + pub l1_gas: ResourceBounds, + pub l2_gas: ResourceBounds, + pub l1_data_gas: ResourceBounds, + } pub struct BlockHash(pub StarkHash); pub struct StorageBlockHeader { pub block_hash: BlockHash, @@ -211,7 +217,7 @@ auto_storage_serde! { pub sender_address: ContractAddress, } pub struct DeclareTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -361,7 +367,6 @@ auto_storage_serde! { pub max_amount: u64, pub max_price_per_unit: u128, } - pub struct DeprecatedResourceBoundsMapping(pub BTreeMap); pub struct SequencerContractAddress(pub ContractAddress); pub struct Signature { pub r: Felt, @@ -419,6 +424,10 @@ auto_storage_serde! { } pub struct TransactionSignature(pub Vec); pub struct TransactionVersion(pub Felt); + pub enum ValidResourceBounds { + L1Gas(ResourceBounds) = 0, + AllResources(AllResourceBounds) = 1, + } pub struct Version{ pub major: u32, pub minor: u32, @@ -1162,7 +1171,7 @@ auto_storage_serde_conditionally_compressed! { } pub struct DeployAccountTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -1198,7 +1207,7 @@ auto_storage_serde_conditionally_compressed! { } pub struct InvokeTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, diff --git a/crates/papyrus_test_utils/src/lib.rs b/crates/papyrus_test_utils/src/lib.rs index 20c39d27ee..012f2331c2 100644 --- a/crates/papyrus_test_utils/src/lib.rs +++ b/crates/papyrus_test_utils/src/lib.rs @@ -88,6 +88,17 @@ use starknet_api::deprecated_contract_class::{ use starknet_api::execution_resources::{Builtin, ExecutionResources, GasVector}; use starknet_api::felt; use starknet_api::hash::{PoseidonHash, StarkHash}; +use starknet_api::rpc_transaction::{ + ContractClass as RpcContractClass, + EntryPointByType as RpcEntryPointByType, + RpcDeclareTransaction, + RpcDeclareTransactionV3, + RpcDeployAccountTransaction, + RpcDeployAccountTransactionV3, + RpcInvokeTransaction, + RpcInvokeTransactionV3, + RpcTransaction, +}; use starknet_api::state::{ ContractClass, EntryPoint, @@ -99,6 +110,7 @@ use starknet_api::state::{ }; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeclareTransaction, @@ -112,7 +124,6 @@ use starknet_api::transaction::{ DeployAccountTransactionV3, DeployTransaction, DeployTransactionOutput, - DeprecatedResourceBoundsMapping, Event, EventContent, EventData, @@ -142,6 +153,7 @@ use starknet_api::transaction::{ TransactionOutput, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; @@ -420,6 +432,11 @@ pub trait GetTestInstance: Sized { auto_impl_get_test_instance! { pub struct AccountDeploymentData(pub Vec); + pub struct AllResourceBounds { + pub l1_gas: ResourceBounds, + pub l2_gas: ResourceBounds, + pub l1_data_gas: ResourceBounds, + } pub struct BlockHash(pub StarkHash); pub struct BlockHeader { pub block_hash: BlockHash, @@ -517,7 +534,7 @@ auto_impl_get_test_instance! { pub sender_address: ContractAddress, } pub struct DeclareTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -550,7 +567,7 @@ auto_impl_get_test_instance! { pub constructor_calldata: Calldata, } pub struct DeployAccountTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -657,7 +674,7 @@ auto_impl_get_test_instance! { pub calldata: Calldata, } pub struct InvokeTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -722,7 +739,68 @@ auto_impl_get_test_instance! { pub max_amount: u64, pub max_price_per_unit: u128, } - pub struct DeprecatedResourceBoundsMapping(pub BTreeMap); + pub struct RpcContractClass { + pub sierra_program: Vec, + pub contract_class_version: String, + pub entry_points_by_type: RpcEntryPointByType, + pub abi: String, + } + pub enum RpcTransaction { + Declare(RpcDeclareTransaction) = 0, + DeployAccount(RpcDeployAccountTransaction) = 1, + Invoke(RpcInvokeTransaction) = 2, + } + pub enum RpcDeclareTransaction { + V3(RpcDeclareTransactionV3) = 0, + } + pub struct RpcDeclareTransactionV3 { + pub resource_bounds: AllResourceBounds, + pub tip: Tip, + pub signature: TransactionSignature, + pub nonce: Nonce, + pub contract_class: RpcContractClass, + pub compiled_class_hash: CompiledClassHash, + pub sender_address: ContractAddress, + pub nonce_data_availability_mode: DataAvailabilityMode, + pub fee_data_availability_mode: DataAvailabilityMode, + pub paymaster_data: PaymasterData, + pub account_deployment_data: AccountDeploymentData, + } + pub enum RpcDeployAccountTransaction { + V3(RpcDeployAccountTransactionV3) = 0, + } + pub struct RpcDeployAccountTransactionV3 { + pub resource_bounds: AllResourceBounds, + pub tip: Tip, + pub signature: TransactionSignature, + pub nonce: Nonce, + pub class_hash: ClassHash, + pub contract_address_salt: ContractAddressSalt, + pub constructor_calldata: Calldata, + pub nonce_data_availability_mode: DataAvailabilityMode, + pub fee_data_availability_mode: DataAvailabilityMode, + pub paymaster_data: PaymasterData, + } + pub struct RpcEntryPointByType { + pub constructor: Vec, + pub external: Vec, + pub l1handler: Vec, + } + pub enum RpcInvokeTransaction { + V3(RpcInvokeTransactionV3) = 0, + } + pub struct RpcInvokeTransactionV3 { + pub resource_bounds: AllResourceBounds, + pub tip: Tip, + pub signature: TransactionSignature, + pub nonce: Nonce, + pub sender_address: ContractAddress, + pub calldata: Calldata, + pub nonce_data_availability_mode: DataAvailabilityMode, + pub fee_data_availability_mode: DataAvailabilityMode, + pub paymaster_data: PaymasterData, + pub account_deployment_data: AccountDeploymentData, + } pub struct SequencerContractAddress(pub ContractAddress); pub struct Signature { pub r: Felt, @@ -784,6 +862,11 @@ auto_impl_get_test_instance! { pub r#type: String, } + pub enum ValidResourceBounds { + L1Gas(ResourceBounds) = 0, + AllResources(AllResourceBounds) = 1, + } + pub struct CasmContractClass { pub prime: BigUint, pub compiler_version: String, diff --git a/crates/sequencing/papyrus_block_builder/Cargo.toml b/crates/sequencing/papyrus_block_builder/Cargo.toml deleted file mode 100644 index 07eee6d113..0000000000 --- a/crates/sequencing/papyrus_block_builder/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "papyrus_block_builder" -version.workspace = true -edition.workspace = true -repository.workspace = true -license-file.workspace = true -description = "A block-builder for Starknet blocks" - -[dependencies] -papyrus_storage = { workspace = true, features = ["testing"] } -starknet_api.workspace = true -thiserror.workspace = true -tracing.workspace = true - -[dev-dependencies] -papyrus_test_utils.workspace = true -pretty_assertions.workspace = true diff --git a/crates/sequencing/papyrus_block_builder/src/lib.rs b/crates/sequencing/papyrus_block_builder/src/lib.rs deleted file mode 100644 index 7725bc48e8..0000000000 --- a/crates/sequencing/papyrus_block_builder/src/lib.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! This crate contains a mock block-builder that echoes [`Starknet`] blocks. -//! -//! -//! [`Starknet`]: https://starknet.io/ - -use std::sync::mpsc::{self, Receiver}; - -use papyrus_storage::body::BodyStorageReader; -use papyrus_storage::StorageReader; -use starknet_api::block::BlockNumber; -use starknet_api::transaction::Transaction; -use tracing::instrument; - -#[cfg(test)] -mod test; - -/// A block builder. -struct BlockBuilder { - // A storage reader to read blocks from. Will be replaced with mempool. - #[allow(unused)] - storage_reader: StorageReader, -} - -pub trait BlockBuilderTrait { - fn build(&self, block_number: BlockNumber) -> BlockBuilderResult>; -} - -type BlockBuilderResult = Result; - -#[derive(thiserror::Error, Debug)] -pub enum BlockBuilderError { - #[error("Could not find a block with block number {}.", block_number)] - BlockNotFound { block_number: BlockNumber }, -} - -impl BlockBuilder { - /// Create a new block builder. - #[allow(unused)] - pub fn new(storage_reader: StorageReader) -> Self { - Self { storage_reader } - } -} - -impl BlockBuilderTrait for BlockBuilder { - // The block must already be in storage. - #[instrument(skip(self), level = "debug")] - fn build(&self, block_number: BlockNumber) -> BlockBuilderResult> { - let (sender, receiver) = mpsc::channel(); - - // TODO: spawn a task to send the transactions and return the receiver immediately. - let block = self - .storage_reader - .begin_ro_txn() - .expect("Failed to read storage") - .get_block_transactions(block_number) - .expect("Block should be in storage"); - - match block { - Some(block) => { - for txn in block { - sender.send(txn).expect("Failed to send transaction"); - } - Ok(receiver) - } - None => Err(BlockBuilderError::BlockNotFound { block_number }), - } - } -} diff --git a/crates/sequencing/papyrus_block_builder/src/test.rs b/crates/sequencing/papyrus_block_builder/src/test.rs deleted file mode 100644 index b4319778e4..0000000000 --- a/crates/sequencing/papyrus_block_builder/src/test.rs +++ /dev/null @@ -1,32 +0,0 @@ -use papyrus_storage::body::BodyStorageWriter; -use papyrus_storage::test_utils::get_test_storage_by_scope; -use papyrus_storage::StorageScope; -use papyrus_test_utils::get_test_block; -use pretty_assertions::assert_eq; -use starknet_api::block::BlockNumber; - -use crate::{BlockBuilder, BlockBuilderTrait}; - -#[test] -fn block_proposer() { - let storage_scope = StorageScope::FullArchive; - let ((storage_reader, mut storage_writer), _temp_dir) = - get_test_storage_by_scope(storage_scope); - let block_body = get_test_block(2, Some(1), None, None).body; - storage_writer - .begin_rw_txn() - .unwrap() - .append_body(BlockNumber(0), block_body.clone()) - .unwrap() - .commit() - .unwrap(); - - let proposer = BlockBuilder::new(storage_reader); - let block_number = BlockNumber(0); - let proposal_receiver = proposer.build(block_number).unwrap(); - let proposal = proposal_receiver.iter().collect::>(); - assert_eq!(proposal, block_body.transactions.as_slice()); -} - -// TODO: add test for non-existing block. -// TODO: add test for sending info and dropping the sender before receiving. diff --git a/crates/sequencing/papyrus_consensus/Cargo.toml b/crates/sequencing/papyrus_consensus/Cargo.toml index 226df68bc4..db9db48bea 100644 --- a/crates/sequencing/papyrus_consensus/Cargo.toml +++ b/crates/sequencing/papyrus_consensus/Cargo.toml @@ -8,6 +8,8 @@ description = "Reach consensus for Starknet" [dependencies] async-trait.workspace = true +clap = { workspace = true, features = ["derive"] } +fs2 = "0.4" futures.workspace = true lazy_static.workspace = true lru.workspace = true @@ -16,7 +18,6 @@ papyrus_common.workspace = true papyrus_config.workspace = true papyrus_network.workspace = true papyrus_protobuf.workspace = true -papyrus_storage.workspace = true serde = { workspace = true, features = ["derive"] } starknet-types-core.workspace = true starknet_api.workspace = true diff --git a/crates/sequencing/papyrus_consensus/run_consensus.py b/crates/sequencing/papyrus_consensus/run_consensus.py deleted file mode 100644 index cfe496d62c..0000000000 --- a/crates/sequencing/papyrus_consensus/run_consensus.py +++ /dev/null @@ -1,352 +0,0 @@ -import subprocess -import time -import os -import signal -import argparse -import tempfile -import socket -from contextlib import closing -import fcntl - -# The SECRET_KEY is used for building the BOOT_NODE_PEER_ID, so they are coupled and must be used together. -SECRET_KEY = "0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd" -BOOT_NODE_PEER_ID = "12D3KooWDFYi71juk6dYWo3UDvqs5gAzGDc124LSvcR5d187Tdvi" - -MONITORING_PERIOD = 10 - - -class Node: - def __init__(self, validator_id, monitoring_gateway_server_port, cmd): - self.validator_id = validator_id - self.monitoring_gateway_server_port = monitoring_gateway_server_port - self.cmd = cmd - self.process = None - self.height_and_timestamp = (None, None) # (height, timestamp) - self.sync_count = None - - def start(self): - self.process = subprocess.Popen(self.cmd, shell=True, preexec_fn=os.setsid) - - def stop(self): - if self.process: - os.killpg(os.getpgid(self.process.pid), signal.SIGINT) - self.process.wait() - - def get_metric(self, metric: str): - port = self.monitoring_gateway_server_port - command = f"curl -s -X GET http://localhost:{port}/monitoring/metrics | grep -oP '{metric} \\K\\d+'" - result = subprocess.run(command, shell=True, capture_output=True, text=True) - return int(result.stdout) if result.stdout else None - - # Check the node's metrics and return the height and timestamp. - def check_node(self): - self.sync_count = self.get_metric("papyrus_consensus_sync_count") - - height = self.get_metric("papyrus_consensus_height") - if self.height_and_timestamp[0] != height: - if self.height_and_timestamp[0] is not None and height is not None: - assert height > self.height_and_timestamp[0], "Height should be increasing." - self.height_and_timestamp = (height, time.time()) - - return self.height_and_timestamp - - -class LockDir: - def __init__(self, db_dir): - self.db_dir = db_dir - self.file_path = os.path.join(db_dir, "lockfile") - self.file = None - - def __enter__(self): - self.file = open(self.file_path, "w") - try: - fcntl.flock(self.file, fcntl.LOCK_EX | fcntl.LOCK_NB) - except IOError: - print( - f"Could not acquire lock for {self.file_path}, {self.db_dir} is in use by another simulation." - ) - exit(1) - return self.file - - def __exit__(self, exc_type, exc_value, traceback): - if self.file: - fcntl.flock(self.file, fcntl.LOCK_UN) - self.file.close() - - -def find_free_port(): - with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: - s.bind(("", 0)) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - return s.getsockname()[1] - - -BOOTNODE_TCP_PORT = find_free_port() - - -# Returns if the simulation should exit. -def monitor_simulation(nodes, start_time, duration, stagnation_timeout): - curr_time = time.time() - if duration is not None and duration < (curr_time - start_time): - return True - stagnated_nodes = [] - for node in nodes: - (height, last_update) = node.check_node() - print(f"Node: {node.validator_id}, height: {height}, sync_count: {node.sync_count}") - if height is not None and (curr_time - last_update) > stagnation_timeout: - stagnated_nodes.append(node.validator_id) - if stagnated_nodes: - print(f"Nodes {stagnated_nodes} have stagnated. Exiting simulation.") - return True - return False - - -def run_simulation(nodes, duration, stagnation_timeout): - for node in nodes: - node.start() - - start_time = time.time() - try: - while True: - time.sleep(MONITORING_PERIOD) - elapsed = round(time.time() - start_time) - print(f"\nTime elapsed: {elapsed}s") - should_exit = monitor_simulation(nodes, start_time, duration, stagnation_timeout) - if should_exit: - break - except KeyboardInterrupt: - print("\nTerminating subprocesses...") - finally: - for node in nodes: - node.stop() - - -def build_node(data_dir, logs_dir, i, papryus_args): - is_bootstrap = i == 1 - tcp_port = BOOTNODE_TCP_PORT if is_bootstrap else find_free_port() - monitoring_gateway_server_port = find_free_port() - data_dir = os.path.join(data_dir, f"data{i}") - - cmd = ( - f"RUST_LOG=papyrus_consensus=debug,papyrus=info " - f"target/release/papyrus_node --network.#is_none false " - f"--base_layer.node_url {papryus_args.base_layer_node_url} " - f"--storage.db_config.path_prefix {data_dir} " - f"--consensus.#is_none false --consensus.validator_id 0x{i} " - f"--consensus.num_validators {papryus_args.num_validators} " - f"--network.tcp_port {tcp_port} " - f"--rpc.server_address 127.0.0.1:{find_free_port()} " - f"--monitoring_gateway.server_address 127.0.0.1:{monitoring_gateway_server_port} " - f"--consensus.test.#is_none false " - f"--collect_metrics true " - ) - - conditional_params = { - "timeouts.proposal_timeout": papryus_args.proposal_timeout, - "timeouts.prevote_timeout": papryus_args.prevote_timeout, - "timeouts.precommit_timeout": papryus_args.precommit_timeout, - "test.cache_size": papryus_args.cache_size, - "test.random_seed": papryus_args.random_seed, - "test.drop_probability": papryus_args.drop_probability, - "test.invalid_probability": papryus_args.invalid_probability, - } - for key, value in conditional_params.items(): - if value is not None: - cmd += f"--consensus.{key} {value} " - - if is_bootstrap: - cmd += ( - f"--network.secret_key {SECRET_KEY} " - + f"2>&1 | sed -r 's/\\x1B\\[[0-9;]*[mK]//g' > {logs_dir}/validator{i}.txt" - ) - else: - cmd += ( - f"--network.bootstrap_peer_multiaddr.#is_none false " - f"--network.bootstrap_peer_multiaddr /ip4/127.0.0.1/tcp/{BOOTNODE_TCP_PORT}/p2p/{BOOT_NODE_PEER_ID} " - + f"2>&1 | sed -r 's/\\x1B\\[[0-9;]*[mK]//g' > {logs_dir}/validator{i}.txt" - ) - - return Node( - validator_id=i, - monitoring_gateway_server_port=monitoring_gateway_server_port, - cmd=cmd, - ) - - -def build_all_nodes(data_dir, logs_dir, papryus_args): - # Validators are started in a specific order to ensure proper network formation: - # 1. The bootnode (validator 1) is started first for network peering. - # 2. Validators 2+ are started next to join the network through the bootnode. - # 3. Validator 0, which is the proposer, is started last so the validators don't miss the proposals. - - nodes = [] - - nodes.append(build_node(data_dir, logs_dir, 1, papryus_args)) # Bootstrap - - for i in range(2, papryus_args.num_validators): - nodes.append(build_node(data_dir, logs_dir, i, papryus_args)) - - nodes.append(build_node(data_dir, logs_dir, 0, papryus_args)) # Proposer - - return nodes - - -# Args passed to the test script that are forwarded to the node. -class PapyrusArgs: - def __init__( - self, - base_layer_node_url, - num_validators, - db_dir, - proposal_timeout, - prevote_timeout, - precommit_timeout, - cache_size, - random_seed, - drop_probability, - invalid_probability, - ): - self.base_layer_node_url = base_layer_node_url - self.num_validators = num_validators - self.db_dir = db_dir - self.proposal_timeout = proposal_timeout - self.prevote_timeout = prevote_timeout - self.precommit_timeout = precommit_timeout - self.cache_size = cache_size - self.random_seed = random_seed - self.drop_probability = drop_probability - self.invalid_probability = invalid_probability - - -# Args passed to the script that are not forwarded to the node. -class RunConsensusArgs: - def __init__(self, stagnation_threshold, duration): - self.stagnation_threshold = stagnation_threshold - self.duration = duration - - -def main(papyrus_args, run_consensus_args): - assert ( - papyrus_args.num_validators >= 2 - ), "At least 2 validators are required for the simulation." - - logs_dir = tempfile.mkdtemp() - db_dir = papyrus_args.db_dir - if db_dir is not None: - actual_dirs = {d for d in os.listdir(db_dir) if os.path.isdir(os.path.join(db_dir, d))} - expected_dirs = {f"data{i}" for i in range(papyrus_args.num_validators)} - assert expected_dirs.issubset( - actual_dirs - ), f"{db_dir} must contain: {', '.join(expected_dirs)}." - else: - db_dir = logs_dir - for i in range(papyrus_args.num_validators): - os.makedirs(os.path.join(db_dir, f"data{i}")) - - # Acquire lock on the db_dir - with LockDir(db_dir): - print("Running cargo build...") - subprocess.run("cargo build --release --package papyrus_node", shell=True, check=True) - - print(f"DB files will be stored in: {db_dir}") - print(f"Logs will be stored in: {logs_dir}") - - nodes = build_all_nodes(db_dir, logs_dir, papyrus_args) - - print("Running validators...") - run_simulation(nodes, run_consensus_args.duration, run_consensus_args.stagnation_threshold) - - print(f"DB files were stored in: {db_dir}") - print(f"Logs were stored in: {logs_dir}") - print("Simulation complete.") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Run Papyrus Node simulation.") - parser.add_argument("--base_layer_node_url", required=True) - parser.add_argument("--num_validators", type=int, required=True) - parser.add_argument( - "--db_dir", - required=False, - default=None, - help="Directory with existing DBs that this simulation can reuse.", - ) - parser.add_argument( - "--stagnation_threshold", - type=int, - required=False, - default=60, - help="Time in seconds to check for height stagnation.", - ) - parser.add_argument("--duration", type=int, required=False, default=None) - parser.add_argument( - "--proposal_timeout", - type=float, - required=False, - default=None, - help="The timeout (seconds) for a proposal.", - ) - parser.add_argument( - "--prevote_timeout", - type=float, - required=False, - default=None, - help="The timeout (seconds) for a prevote.", - ) - parser.add_argument( - "--precommit_timeout", - type=float, - required=False, - default=None, - help="The timeout (seconds) for a precommit.", - ) - parser.add_argument( - "--cache_size", - type=int, - required=False, - default=None, - help="Cache size for the test simulation.", - ) - parser.add_argument( - "--random_seed", - type=int, - required=False, - default=None, - help="Random seed for test simulation.", - ) - parser.add_argument( - "--drop_probability", - type=float, - required=False, - default=None, - help="Probability of dropping a message for test simulation.", - ) - parser.add_argument( - "--invalid_probability", - type=float, - required=False, - default=None, - help="Probability of sending an invalid message for test simulation.", - ) - args = parser.parse_args() - - papyrus_args = PapyrusArgs( - base_layer_node_url=args.base_layer_node_url, - num_validators=args.num_validators, - db_dir=args.db_dir, - proposal_timeout=args.proposal_timeout, - prevote_timeout=args.prevote_timeout, - precommit_timeout=args.precommit_timeout, - cache_size=args.cache_size, - random_seed=args.random_seed, - drop_probability=args.drop_probability, - invalid_probability=args.invalid_probability, - ) - - run_consensus_args = RunConsensusArgs( - stagnation_threshold=args.stagnation_threshold, - duration=args.duration, - ) - - main(papyrus_args, run_consensus_args) diff --git a/crates/sequencing/papyrus_consensus/src/bin/run_consensus.rs b/crates/sequencing/papyrus_consensus/src/bin/run_consensus.rs new file mode 100644 index 0000000000..b226ef3c68 --- /dev/null +++ b/crates/sequencing/papyrus_consensus/src/bin/run_consensus.rs @@ -0,0 +1,390 @@ +use std::collections::HashSet; +use std::fs::{self, File}; +use std::net::TcpListener; +use std::process::Command; +use std::str::FromStr; +use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; + +use clap::Parser; +use fs2::FileExt; +use lazy_static::lazy_static; +use tokio::process::Command as TokioCommand; + +lazy_static! { + static ref BOOTNODE_TCP_PORT: u16 = find_free_port(); +} +// The SECRET_KEY is used for building the BOOT_NODE_PEER_ID, so they are coupled and must be used +// together. +const SECRET_KEY: &str = "0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"; +const BOOT_NODE_PEER_ID: &str = "12D3KooWDFYi71juk6dYWo3UDvqs5gAzGDc124LSvcR5d187Tdvi"; + +const MONITORING_PERIOD_SECONDS: u64 = 10; + +struct Node { + validator_id: usize, + monitoring_gateway_server_port: u16, + cmd: String, + process: Option, + // Nodes current height and the timestamp it was updated. + height_and_timestamp: (Option, Option), //(height, timestamp) + // Number of times the nodes height was updated due to sync, instead of reaching a decision. + sync_count: Option, +} + +impl Node { + fn new(validator_id: usize, monitoring_gateway_server_port: u16, cmd: String) -> Self { + Node { + validator_id, + monitoring_gateway_server_port, + cmd, + process: None, + height_and_timestamp: (None, None), + sync_count: None, + } + } + + fn start(&mut self) { + self.process = Some( + TokioCommand::new("sh") + .arg("-c") + .arg(&self.cmd) + .spawn() + .expect("Failed to start process"), + ); + } + + async fn stop(&mut self) { + if let Some(process) = self.process.as_mut() { + process.kill().await.expect("Failed to kill process"); + } + } + + async fn get_metric(&self, metric: &str) -> Option { + let command = format!( + "curl -s -X GET http://localhost:{}/monitoring/metrics | grep -oP '{} \\K\\d+'", + self.monitoring_gateway_server_port, metric + ); + + let output = + Command::new("sh").arg("-c").arg(command).output().expect("Failed to execute command"); + + if !output.stdout.is_empty() { + let metric_value = String::from_utf8_lossy(&output.stdout); + metric_value.trim().parse().ok() + } else { + None + } + } + + // Check the node's metrics and return the height and timestamp. + async fn check_node(&mut self) -> (Option, Option) { + self.sync_count = self.get_metric("papyrus_consensus_sync_count").await; + let height = self.get_metric("papyrus_consensus_height").await; + + if self.height_and_timestamp.0 == height { + return self.height_and_timestamp; + } + if let (Some(old_height), Some(new_height)) = (self.height_and_timestamp.0, height) { + assert!(new_height > old_height, "Height should be increasing."); + } + self.height_and_timestamp = (height, Some(Instant::now())); + + self.height_and_timestamp + } +} + +#[derive(Parser)] +#[command(name = "Papyrus CLI")] +struct Cli { + #[command(flatten)] + papyrus_args: PapyrusArgs, + #[command(flatten)] + run_consensus_args: RunConsensusArgs, +} + +#[derive(Parser)] +// Args passed to the test script that are forwarded to the node. +struct PapyrusArgs { + #[arg(long = "base_layer_node_url")] + base_layer_node_url: String, + #[arg(long = "num_validators")] + num_validators: usize, + #[arg(long = "db_dir", help = "Directory with existing DBs that this simulation can reuse.")] + db_dir: Option, + #[arg(long = "proposal_timeout", help = "The timeout (seconds) for a proposal.")] + proposal_timeout: Option, + #[arg(long = "prevote_timeout", help = "The timeout (seconds) for a prevote.")] + prevote_timeout: Option, + #[arg(long = "precommit_timeout", help = "The timeout (seconds) for a precommit.")] + precommit_timeout: Option, + #[arg(long = "cache_size", help = "Cache size for the test simulation.")] + cache_size: Option, + #[arg(long = "random_seed", help = "Random seed for test simulation.")] + random_seed: Option, + #[arg( + long = "drop_probability", + help = "Probability of dropping a message for test simulation." + )] + drop_probability: Option, + #[arg( + long = "invalid_probability", + help = "Probability of sending an invalid message for test simulation." + )] + invalid_probability: Option, +} + +#[derive(Parser)] +// Args passed to the script that are not forwarded to the node. +struct RunConsensusArgs { + #[arg( + long = "stagnation_threshold", + help = "Time in seconds to check for height stagnation.", + default_value = "60", value_parser = parse_duration + )] + stagnation_threshold: Duration, + #[arg(long = "duration", help = "Maximum test duration in seconds.", + default_value = "123456789123456789", + value_parser = parse_duration)] + max_test_duration: Duration, +} + +struct LockDir { + file: File, +} + +impl LockDir { + pub fn new(db_dir: &str) -> std::io::Result { + let lockfile_path = format!("{}/lockfile", db_dir); + let file = File::create(&lockfile_path)?; + + match file.try_lock_exclusive() { + Ok(_) => Ok(LockDir { file }), + Err(e) => Err(e), + } + } +} + +impl Drop for LockDir { + fn drop(&mut self) { + let _ = self.file.unlock(); + } +} + +fn parse_duration(s: &str) -> Result { + let secs = u64::from_str(s)?; + Ok(Duration::from_secs(secs)) +} + +fn find_free_port() -> u16 { + // The socket is automatically closed when the function exits. + // The port may still be available when accessed, but this is not guaranteed. + // TODO(Asmaa): find a reliable way to ensure the port stays free. + let listener = TcpListener::bind("0.0.0.0:0").expect("Failed to bind"); + listener.local_addr().expect("Failed to get local address").port() +} + +// Returns if the simulation should exit. +async fn monitor_simulation( + nodes: &mut Vec, + start_time: Instant, + max_test_duration: Duration, + stagnation_timeout: Duration, +) -> bool { + if start_time.elapsed() > max_test_duration { + return true; + } + + let mut stagnated_nodes = Vec::new(); + for node in nodes { + let (height, last_update) = node.check_node().await; + println!( + "Node: {}, height: {:?}, sync_count: {:?}", + node.validator_id, height, node.sync_count + ); + // height is None when consensus has not been started yet. + let elapsed = match height { + Some(_) => last_update.expect("Must be set if height is set").elapsed(), + None => start_time.elapsed(), + }; + if elapsed > stagnation_timeout { + stagnated_nodes.push(node.validator_id); + } + } + + if !stagnated_nodes.is_empty() { + println!("Nodes {stagnated_nodes:?} have stagnated. Exiting simulation."); + return true; + } + false +} + +async fn run_simulation( + mut nodes: Vec, + max_test_duration: Duration, + stagnation_timeout: Duration, +) { + for node in nodes.iter_mut() { + node.start(); + } + + let start_time = Instant::now(); + + loop { + tokio::select! { + should_break = async { + tokio::time::sleep(Duration::from_secs(MONITORING_PERIOD_SECONDS)).await; + let elapsed = start_time.elapsed().as_secs(); + println!("\nTime elapsed: {}s", elapsed); + + monitor_simulation(&mut nodes, start_time, max_test_duration, stagnation_timeout).await + } => { + if should_break { + break; + } + } + _ = tokio::signal::ctrl_c() => { + println!("\nTerminating subprocesses..."); + break; + } + } + } + + for mut node in nodes { + node.stop().await; + } +} + +async fn build_node(data_dir: &str, logs_dir: &str, i: usize, papyrus_args: &PapyrusArgs) -> Node { + let is_bootstrap = i == 1; + let tcp_port = if is_bootstrap { *BOOTNODE_TCP_PORT } else { find_free_port() }; + let monitoring_gateway_server_port = find_free_port(); + let data_dir = format!("{}/data{}", data_dir, i); + + let mut cmd = format!( + "RUST_LOG=papyrus_consensus=debug,papyrus=info target/release/papyrus_node \ + --network.#is_none false --base_layer.node_url {} --storage.db_config.path_prefix {} \ + --consensus.#is_none false --consensus.validator_id 0x{} --consensus.num_validators {} \ + --network.tcp_port {} --rpc.server_address 127.0.0.1:{} \ + --monitoring_gateway.server_address 127.0.0.1:{} --consensus.test.#is_none false \ + --collect_metrics true ", + papyrus_args.base_layer_node_url, + data_dir, + i, + papyrus_args.num_validators, + tcp_port, + find_free_port(), + monitoring_gateway_server_port + ); + + let conditional_params = [ + ("timeouts.proposal_timeout", papyrus_args.proposal_timeout), + ("timeouts.prevote_timeout", papyrus_args.prevote_timeout), + ("timeouts.precommit_timeout", papyrus_args.precommit_timeout), + ("test.drop_probability", papyrus_args.drop_probability), + ("test.invalid_probability", papyrus_args.invalid_probability), + // Convert optional parameters to f64 for consistency in the vector, + // types were validated during parsing. + ("test.cache_size", papyrus_args.cache_size.map(|v| v as f64)), + ("test.random_seed", papyrus_args.random_seed.map(|v| v as f64)), + ]; + for (key, value) in conditional_params.iter() { + if let Some(v) = value { + cmd.push_str(&format!("--consensus.{} {} ", key, v)); + } + } + + if is_bootstrap { + cmd.push_str(&format!( + "--network.secret_key {} 2>&1 | sed -r 's/\\x1B\\[[0-9;]*[mK]//g' > {}/validator{}.txt", + SECRET_KEY, logs_dir, i + )); + } else { + cmd.push_str(&format!( + "--network.bootstrap_peer_multiaddr.#is_none false --network.bootstrap_peer_multiaddr \ + /ip4/127.0.0.1/tcp/{}/p2p/{} 2>&1 | sed -r 's/\\x1B\\[[0-9;]*[mK]//g' > \ + {}/validator{}.txt", + *BOOTNODE_TCP_PORT, BOOT_NODE_PEER_ID, logs_dir, i + )); + } + + Node::new(i, monitoring_gateway_server_port, cmd) +} + +async fn build_all_nodes(data_dir: &str, logs_dir: &str, papyrus_args: &PapyrusArgs) -> Vec { + // Validators are started in a specific order to ensure proper network formation: + // 1. The bootnode (validator 1) is started first for network peering. + // 2. Validators 2+ are started next to join the network through the bootnode. + // 3. Validator 0, which is the proposer, is started last so the validators don't miss the + // proposals. + + let mut nodes = Vec::new(); + + nodes.push(build_node(data_dir, logs_dir, 1, papyrus_args).await); // Bootstrap + + for i in 2..papyrus_args.num_validators { + nodes.push(build_node(data_dir, logs_dir, i, papyrus_args).await); + } + + nodes.push(build_node(data_dir, logs_dir, 0, papyrus_args).await); // Proposer + + nodes +} + +#[tokio::main] +async fn main() { + let Cli { papyrus_args, run_consensus_args } = Cli::parse(); + assert!( + papyrus_args.num_validators >= 2, + "At least 2 validators are required for the simulation." + ); + + let now_ns = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos(); + let mut tmpdir = std::env::temp_dir(); + tmpdir.push(format!("run_consensus_{now_ns}")); + + let logs_dir = tmpdir.to_str().unwrap().to_string(); + let db_dir = papyrus_args.db_dir.clone().unwrap_or_else(|| logs_dir.clone()); + fs::create_dir(&logs_dir).unwrap(); + + if db_dir != logs_dir { + let actual_dirs = fs::read_dir(&db_dir) + .unwrap() + .filter_map(Result::ok) + .filter(|d| d.file_type().unwrap().is_dir()) + .map(|d| d.file_name().into_string().unwrap()) + .collect(); + let expected_dirs: HashSet<_> = + (0..papyrus_args.num_validators).map(|i| format!("data{}", i)).collect(); + assert!(expected_dirs.is_subset(&actual_dirs), "{db_dir} must contain: {expected_dirs:?}"); + } else { + for i in 0..papyrus_args.num_validators { + fs::create_dir_all(format!("{}/data{}", db_dir, i)).unwrap(); + } + } + + // Acquire lock on the db_dir + let _lock = LockDir::new(&db_dir).unwrap(); + + println!("Running cargo build..."); + Command::new("cargo") + .args(["build", "--release", "--package", "papyrus_node"]) + .status() + .unwrap(); + + println!("DB files will be stored in: {db_dir}"); + println!("Logs will be stored in: {logs_dir}"); + + let nodes = build_all_nodes(&db_dir, &logs_dir, &papyrus_args).await; + + println!("Running validators..."); + run_simulation( + nodes, + run_consensus_args.max_test_duration, + run_consensus_args.stagnation_threshold, + ) + .await; + + println!("DB files were stored in: {}", db_dir); + println!("Logs were stored in: {}", logs_dir); + println!("Simulation complete."); +} diff --git a/crates/sequencing/papyrus_consensus/src/lib.rs b/crates/sequencing/papyrus_consensus/src/lib.rs index cc077c83b3..5ecc1e6eec 100644 --- a/crates/sequencing/papyrus_consensus/src/lib.rs +++ b/crates/sequencing/papyrus_consensus/src/lib.rs @@ -6,8 +6,6 @@ pub mod config; pub mod manager; #[allow(missing_docs)] -pub mod papyrus_consensus_context; -#[allow(missing_docs)] pub mod simulation_network_receiver; #[allow(missing_docs)] pub mod single_height_consensus; @@ -18,4 +16,4 @@ pub(crate) mod test_utils; #[allow(missing_docs)] pub mod types; -pub use manager::{run_consensus, ProposalWrapper}; +pub use manager::run_consensus; diff --git a/crates/sequencing/papyrus_consensus/src/manager.rs b/crates/sequencing/papyrus_consensus/src/manager.rs index 90e643f043..63fbd03841 100644 --- a/crates/sequencing/papyrus_consensus/src/manager.rs +++ b/crates/sequencing/papyrus_consensus/src/manager.rs @@ -11,44 +11,38 @@ use futures::channel::{mpsc, oneshot}; use futures::stream::FuturesUnordered; use futures::{Stream, StreamExt}; use papyrus_common::metrics::{PAPYRUS_CONSENSUS_HEIGHT, PAPYRUS_CONSENSUS_SYNC_COUNT}; -use papyrus_network::network_manager::BroadcastedMessageManager; -use papyrus_protobuf::consensus::{ConsensusMessage, Proposal}; -use papyrus_protobuf::converters::ProtobufConversionError; +use papyrus_network::network_manager::BroadcastClientTrait; +use papyrus_protobuf::consensus::{ConsensusMessage, ProposalWrapper}; use starknet_api::block::{BlockHash, BlockNumber}; +use starknet_api::core::ContractAddress; use tracing::{debug, info, instrument}; use crate::config::TimeoutsConfig; use crate::single_height_consensus::{ShcReturn, ShcTask, SingleHeightConsensus}; -use crate::types::{ - ConsensusBlock, - ConsensusContext, - ConsensusError, - Decision, - ProposalInit, - ValidatorId, -}; +use crate::types::{ConsensusBlock, ConsensusContext, ConsensusError, Decision, ValidatorId}; // TODO(dvir): add test for this. #[instrument(skip_all, level = "info")] #[allow(missing_docs)] -pub async fn run_consensus( +pub async fn run_consensus( mut context: ContextT, start_height: BlockNumber, validator_id: ValidatorId, consensus_delay: Duration, timeouts: TimeoutsConfig, - mut network_receiver: NetworkReceiverT, + mut broadcast_client: BroadcastClientT, mut sync_receiver: SyncReceiverT, ) -> Result<(), ConsensusError> where BlockT: ConsensusBlock, ContextT: ConsensusContext, - NetworkReceiverT: Stream< - Item = (Result, BroadcastedMessageManager), - > + Unpin, + BroadcastClientT: BroadcastClientTrait, SyncReceiverT: Stream + Unpin, - ProposalWrapper: - Into<(ProposalInit, mpsc::Receiver, oneshot::Receiver)>, + ProposalWrapper: Into<( + (BlockNumber, u32, ContractAddress), + mpsc::Receiver, + oneshot::Receiver, + )>, { info!( "Running consensus, start_height={}, validator_id={}, consensus_delay={}, timeouts={:?}", @@ -65,7 +59,7 @@ where loop { metrics::gauge!(PAPYRUS_CONSENSUS_HEIGHT, current_height.0 as f64); - let run_height = manager.run_height(&mut context, current_height, &mut network_receiver); + let run_height = manager.run_height(&mut context, current_height, &mut broadcast_client); // `run_height` is not cancel safe. Our implementation doesn't enable us to start and stop // it. We also cannot restart the height; when we dropped the future we dropped the state it @@ -85,11 +79,6 @@ where } } -// `Proposal` is defined in the protobuf crate so we can't implement `Into` for it because of the -// orphan rule. This wrapper enables us to implement `Into` for the inner `Proposal`. -#[allow(missing_docs)] -pub struct ProposalWrapper(pub Proposal); - /// Runs Tendermint repeatedly across different heights. Handles issues which are not explicitly /// part of the single height consensus algorithm (e.g. messages from future heights). #[derive(Debug, Default)] @@ -109,29 +98,25 @@ impl MultiHeightManager { /// /// Assumes that `height` is monotonically increasing across calls for the sake of filtering /// `cached_messaged`. - #[instrument(skip(self, context, network_receiver), level = "info")] - pub async fn run_height( + #[instrument(skip(self, context, broadcast_client), level = "info")] + pub async fn run_height( &mut self, context: &mut ContextT, height: BlockNumber, - network_receiver: &mut NetworkReceiverT, + broadcast_client: &mut BroadcastClientT, ) -> Result, ConsensusError> where BlockT: ConsensusBlock, ContextT: ConsensusContext, - NetworkReceiverT: Stream< - Item = ( - Result, - BroadcastedMessageManager, - ), - > + Unpin, + BroadcastClientT: BroadcastClientTrait, ProposalWrapper: Into<( - ProposalInit, + (BlockNumber, u32, ContractAddress), mpsc::Receiver, oneshot::Receiver, )>, { let validators = context.validators(height).await; + info!("running consensus for height {height:?} with validator set {validators:?}"); let mut shc = SingleHeightConsensus::new( height, self.validator_id, @@ -152,11 +137,11 @@ impl MultiHeightManager { let mut current_height_messages = self.get_current_height_messages(height); loop { let shc_return = tokio::select! { - message = next_message(&mut current_height_messages, network_receiver) => { + message = next_message(&mut current_height_messages, broadcast_client) => { self.handle_message(context, height, &mut shc, message?).await? }, Some(shc_task) = shc_tasks.next() => { - shc.handle_task(context, shc_task).await? + shc.handle_event(context, shc_task.event).await? }, }; @@ -183,7 +168,7 @@ impl MultiHeightManager { BlockT: ConsensusBlock, ContextT: ConsensusContext, ProposalWrapper: Into<( - ProposalInit, + (BlockNumber, u32, ContractAddress), mpsc::Receiver, oneshot::Receiver, )>, @@ -197,7 +182,7 @@ impl MultiHeightManager { if message.height() > height.0 { self.cached_messages.entry(message.height()).or_default().push(message); } - return Ok(ShcReturn::Tasks(vec![])); + return Ok(ShcReturn::Tasks(Vec::new())); } match message { ConsensusMessage::Proposal(proposal) => { @@ -205,7 +190,7 @@ impl MultiHeightManager { let (proposal_init, content_receiver, fin_receiver) = ProposalWrapper(proposal).into(); let res = shc - .handle_proposal(context, proposal_init, content_receiver, fin_receiver) + .handle_proposal(context, proposal_init.into(), content_receiver, fin_receiver) .await?; Ok(res) } @@ -237,34 +222,29 @@ impl MultiHeightManager { } } -async fn next_message( +async fn next_message( cached_messages: &mut Vec, - network_receiver: &mut NetworkReceiverT, + broadcast_client: &mut BroadcastClientT, ) -> Result where - NetworkReceiverT: Stream< - Item = (Result, BroadcastedMessageManager), - > + Unpin, + BroadcastClientT: BroadcastClientTrait, { if let Some(msg) = cached_messages.pop() { return Ok(msg); } - let (msg, mut broadcasted_message_manager) = - network_receiver.next().await.ok_or_else(|| { - ConsensusError::InternalNetworkError( - "NetworkReceiver should never be closed".to_string(), - ) - })?; + let (msg, broadcasted_message_manager) = broadcast_client.next().await.ok_or_else(|| { + ConsensusError::InternalNetworkError("NetworkReceiver should never be closed".to_string()) + })?; match msg { // TODO(matan): Return report_sender for use in later errors by SHC. Ok(msg) => { - broadcasted_message_manager.continue_propogation(); + broadcast_client.continue_propagation(&broadcasted_message_manager).await; Ok(msg) } Err(e) => { // Failed to parse consensus message - broadcasted_message_manager.report_peer(); + broadcast_client.report_message(broadcasted_message_manager).await; Err(e.into()) } } diff --git a/crates/sequencing/papyrus_consensus/src/manager_test.rs b/crates/sequencing/papyrus_consensus/src/manager_test.rs index 5a5337b0b8..597366c5f2 100644 --- a/crates/sequencing/papyrus_consensus/src/manager_test.rs +++ b/crates/sequencing/papyrus_consensus/src/manager_test.rs @@ -7,10 +7,12 @@ use futures::SinkExt; use lazy_static::lazy_static; use mockall::mock; use mockall::predicate::eq; -use papyrus_network::network_manager::test_utils::create_test_broadcasted_message_manager; +use papyrus_network::network_manager::test_utils::{ + create_test_broadcast_client_channels, + create_test_broadcasted_message_manager, +}; use papyrus_network::network_manager::BroadcastedMessageManager; use papyrus_protobuf::consensus::{ConsensusMessage, Vote}; -use papyrus_protobuf::converters::ProtobufConversionError; use starknet_api::block::{BlockHash, BlockNumber}; use starknet_api::transaction::Transaction; use starknet_types_core::felt::Felt; @@ -95,22 +97,17 @@ mock! { } } -type Sender = mpsc::UnboundedSender<( - Result, - BroadcastedMessageManager, -)>; - -async fn send(sender: &mut Sender, msg: ConsensusMessage) { +async fn send( + sender: &mut futures::channel::mpsc::Sender<(Vec, BroadcastedMessageManager)>, + msg: ConsensusMessage, +) { let broadcasted_message_manager = create_test_broadcasted_message_manager(); - sender - .send((Ok(msg.clone()), broadcasted_message_manager)) - .await - .unwrap_or_else(|_| panic!("Failed to send message: {msg:?}")); + sender.send((msg.into(), broadcasted_message_manager)).await.unwrap(); } #[tokio::test] async fn manager_multiple_heights_unordered() { - let (mut sender, mut receiver) = mpsc::unbounded(); + let (mut sender, mut broadcast_client_channels) = create_test_broadcast_client_channels(); // Send messages for height 2 followed by those for height 1. send(&mut sender, proposal(Felt::TWO, 2, 0, *PROPOSER_ID)).await; send(&mut sender, prevote(Some(Felt::TWO), 2, 0, *PROPOSER_ID)).await; @@ -125,7 +122,7 @@ async fn manager_multiple_heights_unordered() { .expect_validate_proposal() .return_once(move |_, _| { let (block_sender, block_receiver) = oneshot::channel(); - block_sender.send(TestBlock { content: vec![], id: BlockHash(Felt::ONE) }).unwrap(); + block_sender.send(TestBlock { content: Vec::new(), id: BlockHash(Felt::ONE) }).unwrap(); block_receiver }) .times(1); @@ -134,7 +131,10 @@ async fn manager_multiple_heights_unordered() { context.expect_broadcast().returning(move |_| Ok(())); let mut manager = MultiHeightManager::new(*VALIDATOR_ID, TIMEOUTS.clone()); - let decision = manager.run_height(&mut context, BlockNumber(1), &mut receiver).await.unwrap(); + let decision = manager + .run_height(&mut context, BlockNumber(1), &mut broadcast_client_channels) + .await + .unwrap(); assert_eq!(decision.block.id(), BlockHash(Felt::ONE)); // Run the manager for height 2. @@ -142,11 +142,14 @@ async fn manager_multiple_heights_unordered() { .expect_validate_proposal() .return_once(move |_, _| { let (block_sender, block_receiver) = oneshot::channel(); - block_sender.send(TestBlock { content: vec![], id: BlockHash(Felt::TWO) }).unwrap(); + block_sender.send(TestBlock { content: Vec::new(), id: BlockHash(Felt::TWO) }).unwrap(); block_receiver }) .times(1); - let decision = manager.run_height(&mut context, BlockNumber(2), &mut receiver).await.unwrap(); + let decision = manager + .run_height(&mut context, BlockNumber(2), &mut broadcast_client_channels) + .await + .unwrap(); assert_eq!(decision.block.id(), BlockHash(Felt::TWO)); } @@ -158,7 +161,7 @@ async fn run_consensus_sync() { context.expect_validate_proposal().return_once(move |_, _| { let (block_sender, block_receiver) = oneshot::channel(); - block_sender.send(TestBlock { content: vec![], id: BlockHash(Felt::TWO) }).unwrap(); + block_sender.send(TestBlock { content: Vec::new(), id: BlockHash(Felt::TWO) }).unwrap(); block_receiver }); context.expect_validators().returning(move |_| vec![*PROPOSER_ID, *VALIDATOR_ID]); @@ -172,7 +175,7 @@ async fn run_consensus_sync() { }); // Send messages for height 2. - let (mut network_sender, mut network_receiver) = mpsc::unbounded(); + let (mut network_sender, broadcast_client) = create_test_broadcast_client_channels(); send(&mut network_sender, proposal(Felt::TWO, 2, 0, *PROPOSER_ID)).await; send(&mut network_sender, prevote(Some(Felt::TWO), 2, 0, *PROPOSER_ID)).await; send(&mut network_sender, precommit(Some(Felt::TWO), 2, 0, *PROPOSER_ID)).await; @@ -186,7 +189,7 @@ async fn run_consensus_sync() { *VALIDATOR_ID, Duration::ZERO, TIMEOUTS.clone(), - &mut network_receiver, + broadcast_client, &mut sync_receiver, ) .await @@ -215,7 +218,7 @@ async fn run_consensus_sync_cancellation_safety() { context.expect_validate_proposal().return_once(move |_, _| { let (block_sender, block_receiver) = oneshot::channel(); - block_sender.send(TestBlock { content: vec![], id: BlockHash(Felt::ONE) }).unwrap(); + block_sender.send(TestBlock { content: Vec::new(), id: BlockHash(Felt::ONE) }).unwrap(); block_receiver }); context.expect_validators().returning(move |_| vec![*PROPOSER_ID, *VALIDATOR_ID]); @@ -234,7 +237,7 @@ async fn run_consensus_sync_cancellation_safety() { Ok(()) }); - let (mut network_sender, mut network_receiver) = mpsc::unbounded(); + let (mut network_sender, broadcast_client) = create_test_broadcast_client_channels(); let (mut sync_sender, mut sync_receiver) = mpsc::unbounded(); let consensus_handle = tokio::spawn(async move { @@ -244,7 +247,7 @@ async fn run_consensus_sync_cancellation_safety() { *VALIDATOR_ID, Duration::ZERO, TIMEOUTS.clone(), - &mut network_receiver, + broadcast_client, &mut sync_receiver, ) .await @@ -271,7 +274,7 @@ async fn run_consensus_sync_cancellation_safety() { #[tokio::test] async fn test_timeouts() { - let (mut sender, mut receiver) = mpsc::unbounded(); + let (mut sender, mut broadcast_client) = create_test_broadcast_client_channels(); send(&mut sender, proposal(Felt::ONE, 1, 0, *PROPOSER_ID)).await; send(&mut sender, prevote(None, 1, 0, *VALIDATOR_ID_2)).await; send(&mut sender, prevote(None, 1, 0, *VALIDATOR_ID_3)).await; @@ -281,7 +284,7 @@ async fn test_timeouts() { let mut context = MockTestContext::new(); context.expect_validate_proposal().returning(move |_, _| { let (block_sender, block_receiver) = oneshot::channel(); - block_sender.send(TestBlock { content: vec![], id: BlockHash(Felt::ONE) }).unwrap(); + block_sender.send(TestBlock { content: Vec::new(), id: BlockHash(Felt::ONE) }).unwrap(); block_receiver }); context @@ -304,7 +307,7 @@ async fn test_timeouts() { let mut manager = MultiHeightManager::new(*VALIDATOR_ID, TIMEOUTS.clone()); let manager_handle = tokio::spawn(async move { let decision = - manager.run_height(&mut context, BlockNumber(1), &mut receiver).await.unwrap(); + manager.run_height(&mut context, BlockNumber(1), &mut broadcast_client).await.unwrap(); assert_eq!(decision.block.id(), BlockHash(Felt::ONE)); }); diff --git a/crates/sequencing/papyrus_consensus/src/simulation_network_receiver.rs b/crates/sequencing/papyrus_consensus/src/simulation_network_receiver.rs index 45adffb652..1eb882ffbc 100644 --- a/crates/sequencing/papyrus_consensus/src/simulation_network_receiver.rs +++ b/crates/sequencing/papyrus_consensus/src/simulation_network_receiver.rs @@ -13,6 +13,7 @@ use papyrus_network::network_manager::BroadcastedMessageManager; use papyrus_protobuf::consensus::ConsensusMessage; use papyrus_protobuf::converters::ProtobufConversionError; use starknet_api::block::BlockHash; +use starknet_api::core::{ContractAddress, PatriciaKey}; use tracing::{debug, instrument}; /// Receiver used to help run simulations of consensus. It has 2 goals in mind: @@ -70,21 +71,15 @@ where /// Applies `drop_probability` followed by `invalid_probability`. So the probability of an /// invalid message is `(1- drop_probability) * invalid_probability`. #[instrument(skip(self), level = "debug")] - pub fn filter_msg(&mut self, mut msg: ConsensusMessage) -> Option { - if !matches!(msg, ConsensusMessage::Proposal(_)) { - // TODO(matan): Add support for dropping/invalidating votes. - return Some(msg); - } + pub fn filter_msg(&mut self, msg: ConsensusMessage) -> Option { + let msg_hash = self.calculate_msg_hash(&msg); - if self.should_drop_msg(&msg) { + if self.should_drop_msg(msg_hash) { debug!("Dropping message"); return None; } - if self.should_invalidate_msg(&msg) { - self.invalidate_msg(&mut msg); - } - Some(msg) + Some(self.maybe_invalidate_msg(msg, msg_hash)) } fn calculate_msg_hash(&mut self, msg: &ConsensusMessage) -> u64 { @@ -103,22 +98,30 @@ where hasher.finish() } - fn should_drop_msg(&mut self, msg: &ConsensusMessage) -> bool { - let prob = (self.calculate_msg_hash(msg) as f64) / (u64::MAX as f64); + fn should_drop_msg(&self, msg_hash: u64) -> bool { + let prob = (msg_hash as f64) / (u64::MAX as f64); prob <= self.drop_probability } - fn should_invalidate_msg(&mut self, msg: &ConsensusMessage) -> bool { - let prob = (self.calculate_msg_hash(msg) as f64) / (u64::MAX as f64); - prob <= self.invalid_probability - } - - fn invalidate_msg(&mut self, msg: &mut ConsensusMessage) { + fn maybe_invalidate_msg( + &mut self, + mut msg: ConsensusMessage, + msg_hash: u64, + ) -> ConsensusMessage { + if (msg_hash as f64) / (u64::MAX as f64) > self.invalid_probability { + return msg; + } debug!("Invalidating message"); - // TODO(matan): Allow for invalid votes based on signature/sender_id. - if let ConsensusMessage::Proposal(ref mut proposal) = msg { - proposal.block_hash = BlockHash(proposal.block_hash.0 + 1); + // TODO(matan): Allow for invalid votes based on signature. + match msg { + ConsensusMessage::Proposal(ref mut proposal) => { + proposal.block_hash = BlockHash(proposal.block_hash.0 + 1); + } + ConsensusMessage::Vote(ref mut vote) => { + vote.voter = ContractAddress(PatriciaKey::from(msg_hash)); + } } + msg } } diff --git a/crates/sequencing/papyrus_consensus/src/simulation_network_receiver_test.rs b/crates/sequencing/papyrus_consensus/src/simulation_network_receiver_test.rs index 3de20093c2..b95cc15b51 100644 --- a/crates/sequencing/papyrus_consensus/src/simulation_network_receiver_test.rs +++ b/crates/sequencing/papyrus_consensus/src/simulation_network_receiver_test.rs @@ -10,20 +10,19 @@ const SEED: u64 = 123; const DROP_PROBABILITY: f64 = 0.5; const INVALID_PROBABILITY: f64 = 0.5; -#[test_case(true; "distinct_messages")] -#[test_case(false; "repeat_messages")] +#[test_case(true, true; "distinct_vote")] +#[test_case(false, true; "repeat_vote")] +#[test_case(true, false; "distinct_proposal")] +#[test_case(false, false; "repeat_proposal")] #[tokio::test] -async fn test_invalid(distinct_messages: bool) { +async fn test_invalid(distinct_messages: bool, is_vote: bool) { let (mut sender, receiver) = futures::channel::mpsc::unbounded(); let mut receiver = NetworkReceiver::new(receiver, CACHE_SIZE, SEED, 0.0, INVALID_PROBABILITY); let mut invalid_messages = 0; + for height in 0..1000 { - let mut proposal = papyrus_protobuf::consensus::Proposal::default(); - if distinct_messages { - proposal.height = height; - } + let msg = create_consensus_msg(if distinct_messages { height } else { 0 }, is_vote); let broadcasted_message_manager = create_test_broadcasted_message_manager(); - let msg = ConsensusMessage::Proposal(proposal.clone()); sender.send((Ok(msg.clone()), broadcasted_message_manager)).await.unwrap(); if receiver.next().await.unwrap().0.unwrap() != msg { invalid_messages += 1; @@ -32,20 +31,19 @@ async fn test_invalid(distinct_messages: bool) { assert!((400..=600).contains(&invalid_messages), "num_invalid={invalid_messages}"); } -#[test_case(true; "distinct_messages")] -#[test_case(false; "repeat_messages")] +#[test_case(true, true; "distinct_vote")] +#[test_case(false, true; "repeat_vote")] +#[test_case(true, false; "distinct_proposal")] +#[test_case(false, false; "repeat_proposal")] #[tokio::test] -async fn test_drops(distinct_messages: bool) { +async fn test_drops(distinct_messages: bool, is_vote: bool) { let (mut sender, receiver) = futures::channel::mpsc::unbounded(); let mut receiver = NetworkReceiver::new(receiver, CACHE_SIZE, SEED, DROP_PROBABILITY, 0.0); let mut num_received = 0; + for height in 0..1000 { - let mut proposal = papyrus_protobuf::consensus::Proposal::default(); - if distinct_messages { - proposal.height = height; - } + let msg = create_consensus_msg(if distinct_messages { height } else { 0 }, is_vote); let broadcasted_message_manager = create_test_broadcasted_message_manager(); - let msg = ConsensusMessage::Proposal(proposal.clone()); sender.send((Ok(msg.clone()), broadcasted_message_manager)).await.unwrap(); } drop(sender); @@ -55,3 +53,14 @@ async fn test_drops(distinct_messages: bool) { } assert!((400..=600).contains(&num_received), "num_received={num_received}"); } + +fn create_consensus_msg(height: u64, is_vote: bool) -> ConsensusMessage { + if is_vote { + ConsensusMessage::Vote(papyrus_protobuf::consensus::Vote { height, ..Default::default() }) + } else { + ConsensusMessage::Proposal(papyrus_protobuf::consensus::Proposal { + height, + ..Default::default() + }) + } +} diff --git a/crates/sequencing/papyrus_consensus/src/single_height_consensus.rs b/crates/sequencing/papyrus_consensus/src/single_height_consensus.rs index 2524b0a2d8..e99b01b177 100644 --- a/crates/sequencing/papyrus_consensus/src/single_height_consensus.rs +++ b/crates/sequencing/papyrus_consensus/src/single_height_consensus.rs @@ -48,6 +48,8 @@ pub(crate) struct SingleHeightConsensus { proposals: HashMap>, prevotes: HashMap<(Round, ValidatorId), Vote>, precommits: HashMap<(Round, ValidatorId), Vote>, + last_prevote: Option, + last_precommit: Option, } impl SingleHeightConsensus { @@ -68,6 +70,8 @@ impl SingleHeightConsensus { proposals: HashMap::new(), prevotes: HashMap::new(), precommits: HashMap::new(), + last_prevote: None, + last_precommit: None, } } @@ -112,7 +116,7 @@ impl SingleHeightConsensus { } let Entry::Vacant(proposal_entry) = self.proposals.entry(init.round) else { warn!("Round {} already has a proposal, ignoring", init.round); - return Ok(ShcReturn::Tasks(vec![])); + return Ok(ShcReturn::Tasks(Vec::new())); }; let block_receiver = context.validate_proposal(self.height, p2p_messages_receiver).await; @@ -172,22 +176,48 @@ impl SingleHeightConsensus { } } - pub async fn handle_task>( + pub async fn handle_event>( &mut self, context: &mut ContextT, - task: ShcTask, + event: StateMachineEvent, ) -> Result, ConsensusError> { - debug!("Received task: {:?}", task); - match task.event { + debug!("Received Event: {:?}", event); + match event { StateMachineEvent::TimeoutPropose(_) | StateMachineEvent::TimeoutPrevote(_) | StateMachineEvent::TimeoutPrecommit(_) => { let leader_fn = |round: Round| -> ValidatorId { context.proposer(self.height, round) }; - let sm_events = self.state_machine.handle_event(task.event, &leader_fn); + let sm_events = self.state_machine.handle_event(event, &leader_fn); self.handle_state_machine_events(context, sm_events).await } - _ => unimplemented!("Unexpected task: {:?}", task), + StateMachineEvent::Prevote(block_hash, round) => { + let Some(last_vote) = &self.last_prevote else { + return Err(ConsensusError::InvalidEvent("No prevote to send".to_string())); + }; + if last_vote.round > round { + return Ok(ShcReturn::Tasks(Vec::new())); + } + context.broadcast(ConsensusMessage::Vote(last_vote.clone())).await?; + Ok(ShcReturn::Tasks(vec![ShcTask { + duration: self.timeouts.prevote_timeout, + event: StateMachineEvent::Prevote(block_hash, round), + }])) + } + StateMachineEvent::Precommit(block_hash, round) => { + let Some(last_vote) = &self.last_precommit else { + return Err(ConsensusError::InvalidEvent("No precommit to send".to_string())); + }; + if last_vote.round > round { + return Ok(ShcReturn::Tasks(Vec::new())); + } + context.broadcast(ConsensusMessage::Vote(last_vote.clone())).await?; + Ok(ShcReturn::Tasks(vec![ShcTask { + duration: self.timeouts.precommit_timeout, + event: StateMachineEvent::Precommit(block_hash, round), + }])) + } + _ => unimplemented!("Unexpected event: {:?}", event), } } @@ -198,10 +228,8 @@ impl SingleHeightConsensus { vote: Vote, ) -> Result, ConsensusError> { if !self.validators.contains(&vote.voter) { - return Err(ConsensusError::InvalidVote( - vote.clone(), - format!("voter {:?} not in validators {:?}", vote.voter, self.validators), - )); + debug!("Ignoring vote from voter not in validators: vote={:?}", vote); + return Ok(ShcReturn::Tasks(Vec::new())); } let (votes, sm_vote) = match vote.vote_type { @@ -227,7 +255,7 @@ impl SingleHeightConsensus { )); } else { // Replay, ignore. - return Ok(ShcReturn::Tasks(vec![])); + return Ok(ShcReturn::Tasks(Vec::new())); } } } @@ -243,7 +271,7 @@ impl SingleHeightConsensus { context: &mut ContextT, mut events: VecDeque, ) -> Result, ConsensusError> { - let mut ret_val = vec![]; + let mut ret_val = Vec::new(); while let Some(event) = events.pop_front() { trace!("Handling event: {:?}", event); match event { @@ -263,12 +291,26 @@ impl SingleHeightConsensus { return self.handle_state_machine_decision(block_hash, round).await; } StateMachineEvent::Prevote(block_hash, round) => { - self.handle_state_machine_vote(context, block_hash, round, VoteType::Prevote) - .await?; + ret_val.extend( + self.handle_state_machine_vote( + context, + block_hash, + round, + VoteType::Prevote, + ) + .await?, + ); } StateMachineEvent::Precommit(block_hash, round) => { - self.handle_state_machine_vote(context, block_hash, round, VoteType::Precommit) - .await?; + ret_val.extend( + self.handle_state_machine_vote( + context, + block_hash, + round, + VoteType::Precommit, + ) + .await?, + ); } StateMachineEvent::TimeoutPropose(_) => { ret_val.push(ShcTask { duration: self.timeouts.proposal_timeout, event }); @@ -326,18 +368,32 @@ impl SingleHeightConsensus { block_hash: Option, round: Round, vote_type: VoteType, - ) -> Result, ConsensusError> { - let votes = match vote_type { - VoteType::Prevote => &mut self.prevotes, - VoteType::Precommit => &mut self.precommits, + ) -> Result, ConsensusError> { + let (votes, last_vote, duration, event) = match vote_type { + VoteType::Prevote => ( + &mut self.prevotes, + &mut self.last_prevote, + self.timeouts.prevote_timeout, + StateMachineEvent::Prevote(block_hash, round), + ), + VoteType::Precommit => ( + &mut self.precommits, + &mut self.last_precommit, + self.timeouts.precommit_timeout, + StateMachineEvent::Precommit(block_hash, round), + ), }; let vote = Vote { vote_type, height: self.height.0, round, block_hash, voter: self.id }; if let Some(old) = votes.insert((round, self.id), vote.clone()) { // TODO(matan): Consider refactoring not to panic, rather log and return the error. panic!("State machine should not send repeat votes: old={:?}, new={:?}", old, vote); } - context.broadcast(ConsensusMessage::Vote(vote)).await?; - Ok(ShcReturn::Tasks(vec![])) + context.broadcast(ConsensusMessage::Vote(vote.clone())).await?; + if last_vote.as_ref().map_or(false, |last| round < last.round) { + return Ok(Vec::new()); + } + *last_vote = Some(vote); + Ok(vec![ShcTask { duration, event }]) } #[instrument(skip_all)] diff --git a/crates/sequencing/papyrus_consensus/src/single_height_consensus_test.rs b/crates/sequencing/papyrus_consensus/src/single_height_consensus_test.rs index ecccbe3dc5..8b83d466f1 100644 --- a/crates/sequencing/papyrus_consensus/src/single_height_consensus_test.rs +++ b/crates/sequencing/papyrus_consensus/src/single_height_consensus_test.rs @@ -28,18 +28,43 @@ lazy_static! { static ref TIMEOUTS: TimeoutsConfig = TimeoutsConfig::default(); } +fn prevote_task(block_felt: Option, round: u32) -> ShcTask { + ShcTask { + duration: TIMEOUTS.prevote_timeout, + event: StateMachineEvent::Prevote(block_felt.map(BlockHash), round), + } +} + +fn precommit_task(block_felt: Option, round: u32) -> ShcTask { + ShcTask { + duration: TIMEOUTS.precommit_timeout, + event: StateMachineEvent::Precommit(block_felt.map(BlockHash), round), + } +} + +fn timeout_prevote_task(round: u32) -> ShcTask { + ShcTask { duration: TIMEOUTS.prevote_timeout, event: StateMachineEvent::TimeoutPrevote(round) } +} + +fn timeout_precommit_task(round: u32) -> ShcTask { + ShcTask { + duration: TIMEOUTS.precommit_timeout, + event: StateMachineEvent::TimeoutPrecommit(round), + } +} + #[tokio::test] async fn proposer() { let mut context = MockTestContext::new(); let mut shc = SingleHeightConsensus::new( BlockNumber(0), - *VALIDATOR_ID_1, + *PROPOSER_ID, VALIDATORS.to_vec(), TIMEOUTS.clone(), ); - context.expect_proposer().times(1).returning(move |_, _| *VALIDATOR_ID_1); + context.expect_proposer().times(1).returning(move |_, _| *PROPOSER_ID); context.expect_build_proposal().times(1).returning(move |_| { let (_, content_receiver) = mpsc::channel(1); let (block_sender, block_receiver) = oneshot::channel(); @@ -51,7 +76,7 @@ async fn proposer() { context.expect_propose().times(1).return_once(move |init, _, fin_receiver| { // Ignore content receiver, since this is the context's responsibility. assert_eq!(init.height, BlockNumber(0)); - assert_eq!(init.proposer, *VALIDATOR_ID_1); + assert_eq!(init.proposer, *PROPOSER_ID); // This is done so that we can return immediately without dropping the receiver. fin_receiver_clone.set(fin_receiver).unwrap(); Ok(()) @@ -60,50 +85,47 @@ async fn proposer() { .expect_broadcast() .times(1) .withf(move |msg: &ConsensusMessage| { - msg == &prevote(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_1) + msg == &prevote(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID) }) .returning(move |_| Ok(())); // Sends proposal and prevote. - assert_eq!(shc.start(&mut context).await, Ok(ShcReturn::Tasks(vec![]))); assert_eq!( - shc.handle_message(&mut context, prevote(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID)).await, - Ok(ShcReturn::Tasks(vec![])) + shc.start(&mut context).await, + Ok(ShcReturn::Tasks(vec![prevote_task(Some(BLOCK.id().0), 0)])) + ); + assert_eq!( + shc.handle_message(&mut context, prevote(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_1)).await, + Ok(ShcReturn::Tasks(Vec::new())) ); // 3 of 4 Prevotes is enough to send a Precommit. context .expect_broadcast() .times(1) .withf(move |msg: &ConsensusMessage| { - msg == &precommit(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_1) + msg == &precommit(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID) }) .returning(move |_| Ok(())); // The Node got a Prevote quorum. assert_eq!( shc.handle_message(&mut context, prevote(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_2)).await, - Ok(ShcReturn::Tasks(vec![ShcTask { - duration: TIMEOUTS.prevote_timeout, - event: StateMachineEvent::TimeoutPrevote(0) - }])) + Ok(ShcReturn::Tasks(vec![timeout_prevote_task(0), precommit_task(Some(BLOCK.id().0), 0),])) ); let precommits = vec![ - precommit(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID), + precommit(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_1), precommit(Some(Felt::TWO), 0, 0, *VALIDATOR_ID_3), precommit(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_2), - precommit(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_1), + precommit(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID), ]; assert_eq!( shc.handle_message(&mut context, precommits[0].clone()).await, - Ok(ShcReturn::Tasks(vec![])) + Ok(ShcReturn::Tasks(Vec::new())) ); // The disagreeing vote counts towards the timeout, which uses a heterogeneous quorum, but not // the decision, which uses a homogenous quorum. assert_eq!( shc.handle_message(&mut context, precommits[1].clone()).await, - Ok(ShcReturn::Tasks(vec![ShcTask { - duration: TIMEOUTS.precommit_timeout, - event: StateMachineEvent::TimeoutPrecommit(0) - }])) + Ok(ShcReturn::Tasks(vec![timeout_precommit_task(0),])) ); let ShcReturn::Decision(decision) = shc.handle_message(&mut context, precommits[2].clone()).await.unwrap() @@ -158,7 +180,7 @@ async fn validator(repeat_proposal: bool) { fin_receiver, ) .await; - assert_eq!(res, Ok(ShcReturn::Tasks(vec![]))); + assert_eq!(res, Ok(ShcReturn::Tasks(vec![prevote_task(Some(BLOCK.id().0), 0),]))); if repeat_proposal { // Send the same proposal again, which should be ignored (no expectations). let (fin_sender, fin_receiver) = oneshot::channel(); @@ -172,11 +194,11 @@ async fn validator(repeat_proposal: bool) { fin_receiver, ) .await; - assert_eq!(res, Ok(ShcReturn::Tasks(vec![]))); + assert_eq!(res, Ok(ShcReturn::Tasks(Vec::new()))); } assert_eq!( shc.handle_message(&mut context, prevote(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID)).await, - Ok(ShcReturn::Tasks(vec![])) + Ok(ShcReturn::Tasks(Vec::new())) ); // 3 of 4 Prevotes is enough to send a Precommit. context @@ -189,10 +211,7 @@ async fn validator(repeat_proposal: bool) { // The Node got a Prevote quorum. assert_eq!( shc.handle_message(&mut context, prevote(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_2)).await, - Ok(ShcReturn::Tasks(vec![ShcTask { - duration: TIMEOUTS.prevote_timeout, - event: StateMachineEvent::TimeoutPrevote(0) - }])) + Ok(ShcReturn::Tasks(vec![timeout_prevote_task(0), precommit_task(Some(BLOCK.id().0), 0)])) ); let precommits = vec![ @@ -202,7 +221,7 @@ async fn validator(repeat_proposal: bool) { ]; assert_eq!( shc.handle_message(&mut context, precommits[0].clone()).await, - Ok(ShcReturn::Tasks(vec![])) + Ok(ShcReturn::Tasks(Vec::new())) ); let ShcReturn::Decision(decision) = shc.handle_message(&mut context, precommits[1].clone()).await.unwrap() @@ -253,11 +272,11 @@ async fn vote_twice(same_vote: bool) { fin_receiver, ) .await; - assert_eq!(res, Ok(ShcReturn::Tasks(vec![]))); + assert_eq!(res, Ok(ShcReturn::Tasks(vec![prevote_task(Some(BLOCK.id().0), 0),]))); let res = shc.handle_message(&mut context, prevote(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID)).await; - assert_eq!(res, Ok(ShcReturn::Tasks(vec![]))); + assert_eq!(res, Ok(ShcReturn::Tasks(Vec::new()))); context .expect_broadcast() @@ -269,21 +288,18 @@ async fn vote_twice(same_vote: bool) { // The Node got a Prevote quorum. assert_eq!( res, - Ok(ShcReturn::Tasks(vec![ShcTask { - duration: TIMEOUTS.prevote_timeout, - event: StateMachineEvent::TimeoutPrevote(0) - }])) + Ok(ShcReturn::Tasks(vec![timeout_prevote_task(0), precommit_task(Some(BLOCK.id().0), 0),])) ); let first_vote = precommit(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID); let res = shc.handle_message(&mut context, first_vote.clone()).await; - assert_eq!(res, Ok(ShcReturn::Tasks(vec![]))); + assert_eq!(res, Ok(ShcReturn::Tasks(Vec::new()))); let second_vote = if same_vote { first_vote.clone() } else { precommit(Some(Felt::TWO), 0, 0, *PROPOSER_ID) }; let res = shc.handle_message(&mut context, second_vote.clone()).await; if same_vote { - assert_eq!(res, Ok(ShcReturn::Tasks(vec![]))); + assert_eq!(res, Ok(ShcReturn::Tasks(Vec::new()))); } else { assert!(matches!(res, Err(ConsensusError::Equivocation(_, _, _)))); } @@ -297,3 +313,67 @@ async fn vote_twice(same_vote: bool) { }; assert_eq!(decision.block, *BLOCK); } + +#[tokio::test] +async fn rebroadcast_votes() { + let mut context = MockTestContext::new(); + + let mut shc = SingleHeightConsensus::new( + BlockNumber(0), + *PROPOSER_ID, + VALIDATORS.to_vec(), + TIMEOUTS.clone(), + ); + + context.expect_proposer().times(1).returning(move |_, _| *PROPOSER_ID); + context.expect_build_proposal().times(1).returning(move |_| { + let (_, content_receiver) = mpsc::channel(1); + let (block_sender, block_receiver) = oneshot::channel(); + block_sender.send(BLOCK.clone()).unwrap(); + (content_receiver, block_receiver) + }); + let fin_receiver = Arc::new(OnceLock::new()); + let fin_receiver_clone = Arc::clone(&fin_receiver); + context.expect_propose().times(1).return_once(move |init, _, fin_receiver| { + // Ignore content receiver, since this is the context's responsibility. + assert_eq!(init.height, BlockNumber(0)); + assert_eq!(init.proposer, *PROPOSER_ID); + // This is done so that we can return immediately without dropping the receiver. + fin_receiver_clone.set(fin_receiver).unwrap(); + Ok(()) + }); + context + .expect_broadcast() + .times(1) + .withf(move |msg: &ConsensusMessage| { + msg == &prevote(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID) + }) + .returning(move |_| Ok(())); + // Sends proposal and prevote. + assert_eq!( + shc.start(&mut context).await, + Ok(ShcReturn::Tasks(vec![prevote_task(Some(BLOCK.id().0), 0),])) + ); + assert_eq!( + shc.handle_message(&mut context, prevote(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_1)).await, + Ok(ShcReturn::Tasks(Vec::new())) + ); + // 3 of 4 Prevotes is enough to send a Precommit. + context + .expect_broadcast() + .times(2) // vote rebroadcast + .withf(move |msg: &ConsensusMessage| { + msg == &precommit(Some(BLOCK.id().0), 0, 0, *PROPOSER_ID) + }) + .returning(move |_| Ok(())); + // The Node got a Prevote quorum. + assert_eq!( + shc.handle_message(&mut context, prevote(Some(BLOCK.id().0), 0, 0, *VALIDATOR_ID_2)).await, + Ok(ShcReturn::Tasks(vec![timeout_prevote_task(0), precommit_task(Some(BLOCK.id().0), 0),])) + ); + // Re-broadcast vote. + assert_eq!( + shc.handle_event(&mut context, StateMachineEvent::Precommit(Some(BLOCK.id()), 0),).await, + Ok(ShcReturn::Tasks(vec![precommit_task(Some(BLOCK.id().0), 0),])) + ); +} diff --git a/crates/sequencing/papyrus_consensus/src/state_machine.rs b/crates/sequencing/papyrus_consensus/src/state_machine.rs index aec0084b17..d8c06b2b20 100644 --- a/crates/sequencing/papyrus_consensus/src/state_machine.rs +++ b/crates/sequencing/papyrus_consensus/src/state_machine.rs @@ -130,34 +130,38 @@ impl StateMachine { self.events_queue.push_back(event); } - // The events queue only maintains state while we are waiting for a proposal. - let events_queue = std::mem::take(&mut self.events_queue); - self.handle_enqueued_events(events_queue, leader_fn) + self.handle_enqueued_events(leader_fn) } fn handle_enqueued_events( &mut self, - mut events_queue: VecDeque, leader_fn: &LeaderFn, ) -> VecDeque where LeaderFn: Fn(Round) -> ValidatorId, { let mut output_events = VecDeque::new(); - while let Some(event) = events_queue.pop_front() { + while let Some(event) = self.events_queue.pop_front() { // Handle a specific event and then decide which of the output events should also be // sent to self. - for e in self.handle_event_internal(event, leader_fn) { + let mut resultant_events = self.handle_event_internal(event, leader_fn); + while let Some(e) = resultant_events.pop_front() { match e { StateMachineEvent::Proposal(_, _) | StateMachineEvent::Prevote(_, _) | StateMachineEvent::Precommit(_, _) => { - events_queue.push_back(e.clone()); + self.events_queue.push_back(e.clone()); } StateMachineEvent::Decision(_, _) => { output_events.push_back(e); return output_events; } + StateMachineEvent::GetProposal(_, _) => { + // LOC 18. + debug_assert!(resultant_events.is_empty()); + output_events.push_back(e); + return output_events; + } _ => {} } output_events.push_back(e); @@ -174,6 +178,10 @@ impl StateMachine { where LeaderFn: Fn(Round) -> ValidatorId, { + if self.awaiting_get_proposal { + debug_assert!(matches!(event, StateMachineEvent::GetProposal(_, _)), "{:?}", event); + } + match event { StateMachineEvent::GetProposal(block_hash, round) => { self.handle_get_proposal(block_hash, round) diff --git a/crates/sequencing/papyrus_consensus/src/state_machine_test.rs b/crates/sequencing/papyrus_consensus/src/state_machine_test.rs index 3f9b2a9417..24783789f2 100644 --- a/crates/sequencing/papyrus_consensus/src/state_machine_test.rs +++ b/crates/sequencing/papyrus_consensus/src/state_machine_test.rs @@ -303,3 +303,41 @@ fn mixed_quorum(send_prposal: bool) { wrapper.send_timeout_precommit(ROUND); assert_eq!(wrapper.next_event().unwrap(), StateMachineEvent::TimeoutPropose(ROUND + 1)); } + +#[test] +fn dont_handle_enqueued_while_awaiting_get_proposal() { + let mut wrapper = TestWrapper::new(*PROPOSER_ID, 4, |_: Round| *PROPOSER_ID); + + wrapper.start(); + assert_eq!(wrapper.next_event().unwrap(), StateMachineEvent::GetProposal(None, ROUND)); + assert!(wrapper.next_event().is_none()); + + // We simulate that this node is always the proposer, but it lagged, so the peers kept voting + // NIL and progressing rounds. + wrapper.send_prevote(None, ROUND); + wrapper.send_prevote(None, ROUND); + wrapper.send_prevote(None, ROUND); + wrapper.send_precommit(None, ROUND); + wrapper.send_precommit(None, ROUND); + wrapper.send_precommit(None, ROUND); + wrapper.send_prevote(None, ROUND + 1); + wrapper.send_prevote(None, ROUND + 1); + wrapper.send_prevote(None, ROUND + 1); + wrapper.send_precommit(None, ROUND + 1); + wrapper.send_precommit(None, ROUND + 1); + wrapper.send_precommit(None, ROUND + 1); + + // It now receives the proposal. + wrapper.send_get_proposal(BLOCK_HASH, ROUND); + assert_eq!(wrapper.next_event().unwrap(), StateMachineEvent::Proposal(BLOCK_HASH, ROUND)); + assert_eq!(wrapper.next_event().unwrap(), StateMachineEvent::TimeoutPrecommit(ROUND)); + assert_eq!(wrapper.next_event().unwrap(), StateMachineEvent::GetProposal(None, ROUND + 1)); + assert!(wrapper.next_event().is_none()); + + // The other votes are only handled after the next GetProposal is received. + wrapper.send_get_proposal(BLOCK_HASH, ROUND + 1); + assert_eq!(wrapper.next_event().unwrap(), StateMachineEvent::Proposal(BLOCK_HASH, ROUND + 1)); + assert_eq!(wrapper.next_event().unwrap(), StateMachineEvent::TimeoutPrecommit(ROUND + 1)); + assert_eq!(wrapper.next_event().unwrap(), StateMachineEvent::GetProposal(None, ROUND + 2)); + assert!(wrapper.next_event().is_none()); +} diff --git a/crates/sequencing/papyrus_consensus/src/test_utils.rs b/crates/sequencing/papyrus_consensus/src/test_utils.rs index 1bee8e405b..4582161f69 100644 --- a/crates/sequencing/papyrus_consensus/src/test_utils.rs +++ b/crates/sequencing/papyrus_consensus/src/test_utils.rs @@ -112,6 +112,6 @@ pub fn proposal( block_hash, round, proposer, - transactions: vec![], + transactions: Vec::new(), }) } diff --git a/crates/sequencing/papyrus_consensus/src/types.rs b/crates/sequencing/papyrus_consensus/src/types.rs index b69de86150..ba6e59d0bf 100644 --- a/crates/sequencing/papyrus_consensus/src/types.rs +++ b/crates/sequencing/papyrus_consensus/src/types.rs @@ -169,16 +169,24 @@ pub struct ProposalInit { pub proposer: ValidatorId, } +// TODO(Guy): Remove after implementing broadcast streams. +impl From<(BlockNumber, u32, ContractAddress)> for ProposalInit { + fn from(val: (BlockNumber, u32, ContractAddress)) -> Self { + ProposalInit { height: val.0, round: val.1, proposer: val.2 } + } +} + #[derive(thiserror::Error, PartialEq, Debug)] pub enum ConsensusError { #[error(transparent)] Canceled(#[from] oneshot::Canceled), #[error(transparent)] ProtobufConversionError(#[from] ProtobufConversionError), + /// This should never occur, since events are internally generated. + #[error("Invalid event: {0}")] + InvalidEvent(String), #[error("Invalid proposal sent by peer {0:?} at height {1}: {2}")] InvalidProposal(ValidatorId, BlockNumber, String), - #[error("Invalid vote {0:?}. {1}")] - InvalidVote(Vote, String), #[error(transparent)] SendError(#[from] mpsc::SendError), #[error("Conflicting messages for block {0}. Old: {1:?}, New: {2:?}")] diff --git a/crates/sequencing/papyrus_consensus_orchestrator/Cargo.toml b/crates/sequencing/papyrus_consensus_orchestrator/Cargo.toml new file mode 100644 index 0000000000..a053495dc3 --- /dev/null +++ b/crates/sequencing/papyrus_consensus_orchestrator/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "papyrus_consensus_orchestrator" +version.workspace = true +edition.workspace = true +repository.workspace = true +license-file.workspace = true +description = "Implements the consensus context and orchestrates the node's components accordingly" + +[dependencies] +async-trait.workspace = true +futures.workspace = true +papyrus_consensus.workspace = true +papyrus_network.workspace = true +papyrus_protobuf.workspace = true +papyrus_storage.workspace = true +starknet_api.workspace = true +tokio = { workspace = true, features = ["full"] } +tracing.workspace = true + +[dev-dependencies] +mockall.workspace = true +papyrus_network = { workspace = true, features = ["testing"] } +papyrus_storage = { workspace = true, features = ["testing"] } +papyrus_test_utils.workspace = true +test-case.workspace = true diff --git a/crates/sequencing/papyrus_consensus_orchestrator/src/lib.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/lib.rs new file mode 100644 index 0000000000..42666c0f91 --- /dev/null +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/lib.rs @@ -0,0 +1,7 @@ +#![warn(missing_docs)] +//! An orchestrator for a StarkNet node. +//! Implements the consensus context - the interface for consensus to call out to the node. + +#[allow(missing_docs)] +// TODO: this is test code, rename accordingly. +pub mod papyrus_consensus_context; diff --git a/crates/sequencing/papyrus_consensus/src/papyrus_consensus_context.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs similarity index 91% rename from crates/sequencing/papyrus_consensus/src/papyrus_consensus_context.rs rename to crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs index cc1955f428..e0dd4cb343 100644 --- a/crates/sequencing/papyrus_consensus/src/papyrus_consensus_context.rs +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context.rs @@ -9,6 +9,14 @@ use async_trait::async_trait; use futures::channel::{mpsc, oneshot}; use futures::sink::SinkExt; use futures::StreamExt; +use papyrus_consensus::types::{ + ConsensusBlock, + ConsensusContext, + ConsensusError, + ProposalInit, + Round, + ValidatorId, +}; use papyrus_network::network_manager::BroadcastTopicSender; use papyrus_protobuf::consensus::{ConsensusMessage, Proposal, Vote}; use papyrus_storage::body::BodyStorageReader; @@ -19,19 +27,10 @@ use starknet_api::core::ContractAddress; use starknet_api::transaction::Transaction; use tracing::{debug, debug_span, info, warn, Instrument}; -use crate::types::{ - ConsensusBlock, - ConsensusContext, - ConsensusError, - ProposalInit, - Round, - ValidatorId, -}; -use crate::ProposalWrapper; - // TODO: add debug messages and span to the tasks. #[derive(Debug, Default, PartialEq, Eq, Clone)] +#[allow(missing_docs)] pub struct PapyrusConsensusBlock { content: Vec, id: BlockHash, @@ -50,6 +49,7 @@ impl ConsensusBlock for PapyrusConsensusBlock { } } +#[allow(missing_docs)] pub struct PapyrusConsensusContext { storage_reader: StorageReader, network_broadcast_sender: BroadcastTopicSender, @@ -60,6 +60,7 @@ pub struct PapyrusConsensusContext { impl PapyrusConsensusContext { // TODO(dvir): remove the dead code attribute after we will use this function. #[allow(dead_code)] + #[allow(missing_docs)] pub fn new( storage_reader: StorageReader, network_broadcast_sender: BroadcastTopicSender, @@ -273,26 +274,3 @@ async fn wait_for_block( } Ok(()) } - -impl From - for (ProposalInit, mpsc::Receiver, oneshot::Receiver) -{ - fn from(val: ProposalWrapper) -> Self { - let transactions: Vec = val.0.transactions.into_iter().collect(); - let proposal_init = ProposalInit { - height: BlockNumber(val.0.height), - round: val.0.round, - proposer: val.0.proposer, - }; - let (mut content_sender, content_receiver) = mpsc::channel(transactions.len()); - for tx in transactions { - content_sender.try_send(tx).expect("Send should succeed"); - } - content_sender.close_channel(); - - let (fin_sender, fin_receiver) = oneshot::channel(); - fin_sender.send(val.0.block_hash).expect("Send should succeed"); - - (proposal_init, content_receiver, fin_receiver) - } -} diff --git a/crates/sequencing/papyrus_consensus/src/papyrus_consensus_context_test.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs similarity index 98% rename from crates/sequencing/papyrus_consensus/src/papyrus_consensus_context_test.rs rename to crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs index 9b89f634ed..6f22576c0f 100644 --- a/crates/sequencing/papyrus_consensus/src/papyrus_consensus_context_test.rs +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/papyrus_consensus_context_test.rs @@ -1,5 +1,6 @@ use futures::channel::{mpsc, oneshot}; use futures::StreamExt; +use papyrus_consensus::types::{ConsensusBlock, ConsensusContext, ProposalInit}; use papyrus_network::network_manager::test_utils::{ mock_register_broadcast_topic, BroadcastNetworkMock, @@ -14,7 +15,6 @@ use starknet_api::core::ContractAddress; use starknet_api::transaction::Transaction; use crate::papyrus_consensus_context::{PapyrusConsensusBlock, PapyrusConsensusContext}; -use crate::types::{ConsensusBlock, ConsensusContext, ProposalInit}; // TODO(dvir): consider adding tests for times, i.e, the calls are returned immediately and nothing // happen until it should (for example, not creating a block before we have it in storage). diff --git a/crates/starknet_api/Cargo.toml b/crates/starknet_api/Cargo.toml index be278c6d39..496b47d797 100644 --- a/crates/starknet_api/Cargo.toml +++ b/crates/starknet_api/Cargo.toml @@ -10,22 +10,25 @@ description = "Starknet Rust types related to computation and execution." testing = [] [dependencies] -bitvec = "1.0.1" -cairo-lang-starknet-classes = "2.7.0-dev.0" -derive_more = "0.99.17" -hex = "0.4.3" -indexmap = { version = "2.1.0", features = ["serde"] } -itertools = "0.12.1" -primitive-types = { version = "0.12.1", features = ["serde"] } -serde = { version = "1.0.130", features = ["derive", "rc"] } -serde_json = "1.0.81" -sha3 = "0.10.8" -starknet-crypto = "0.5.1" -starknet-types-core = { version = "0.1.4", features = ["hash"] } -strum = "0.24.1" -strum_macros = "0.24.3" -thiserror = "1.0.31" +bitvec.workspace = true +cairo-lang-starknet-classes.workspace = true +derive_more.workspace = true +hex.workspace = true +indexmap = { workspace = true, features = ["serde"] } +itertools.workspace = true +primitive-types = { workspace = true, features = ["serde"] } +serde = { workspace = true, features = ["derive", "rc"] } +serde_json.workspace = true +sha3.workspace = true +starknet-crypto.workspace = true +starknet-types-core = { workspace = true, features = ["hash"] } +strum.workspace = true +strum_macros.workspace = true +thiserror.workspace = true [dev-dependencies] -assert_matches = "1.5.0" -rstest = "0.17.0" +assert_matches.workspace = true +rstest.workspace = true + +[package.metadata.cargo-machete] +ignored = ["strum"] diff --git a/crates/starknet_api/src/core.rs b/crates/starknet_api/src/core.rs index 03147360c6..0892aaebbe 100644 --- a/crates/starknet_api/src/core.rs +++ b/crates/starknet_api/src/core.rs @@ -70,6 +70,13 @@ impl ChainId { pub fn as_hex(&self) -> String { format!("0x{}", hex::encode(self.to_string())) } + + #[cfg(any(feature = "testing", test))] + pub fn create_for_testing() -> Self { + const CHAIN_ID_NAME: &str = "SN_GOERLI"; + + ChainId::Other(CHAIN_ID_NAME.to_string()) + } } /// The address of a contract, used for example in [StateDiff](`crate::state::StateDiff`), @@ -212,6 +219,14 @@ impl Nonce { } Ok(Self(incremented)) } + + pub fn try_decrement(&self) -> Result { + // Check if an underflow occurred during decrement. + if self.0 == Felt::ZERO { + return Err(StarknetApiError::OutOfRange { string: format!("{:?}", self) }); + } + Ok(Self(self.0 - Felt::ONE)) + } } /// The selector of an [EntryPoint](`crate::deprecated_contract_class::EntryPoint`). diff --git a/crates/starknet_api/src/crypto/utils.rs b/crates/starknet_api/src/crypto/utils.rs index 170de7e4ce..0b9fc7d847 100644 --- a/crates/starknet_api/src/crypto/utils.rs +++ b/crates/starknet_api/src/crypto/utils.rs @@ -49,32 +49,24 @@ pub struct Signature { pub s: Felt, } -fn to_field_element(felt: &Felt) -> starknet_crypto::FieldElement { - starknet_crypto::FieldElement::from_mont(felt.to_raw_reversed()) -} - /// Verifies the authenticity of a signed message hash given the public key of the signer. pub fn verify_message_hash_signature( message_hash: &Felt, signature: &Signature, public_key: &PublicKey, ) -> Result { - starknet_crypto::verify( - &to_field_element(&public_key.0), - &to_field_element(message_hash), - &to_field_element(&signature.r), - &to_field_element(&signature.s), + starknet_crypto::verify(&public_key.0, message_hash, &signature.r, &signature.s).map_err( + |err| match err { + starknet_crypto::VerifyError::InvalidPublicKey => { + CryptoError::InvalidPublicKey(*public_key) + } + starknet_crypto::VerifyError::InvalidMessageHash => { + CryptoError::InvalidMessageHash(*message_hash) + } + starknet_crypto::VerifyError::InvalidR => CryptoError::InvalidR(signature.r), + starknet_crypto::VerifyError::InvalidS => CryptoError::InvalidS(signature.s), + }, ) - .map_err(|err| match err { - starknet_crypto::VerifyError::InvalidPublicKey => { - CryptoError::InvalidPublicKey(*public_key) - } - starknet_crypto::VerifyError::InvalidMessageHash => { - CryptoError::InvalidMessageHash(*message_hash) - } - starknet_crypto::VerifyError::InvalidR => CryptoError::InvalidR(signature.r), - starknet_crypto::VerifyError::InvalidS => CryptoError::InvalidS(signature.s), - }) } // Collect elements for applying hash chain. diff --git a/crates/starknet_api/src/executable_transaction.rs b/crates/starknet_api/src/executable_transaction.rs index 6a2246f7d8..bbb6e0420b 100644 --- a/crates/starknet_api/src/executable_transaction.rs +++ b/crates/starknet_api/src/executable_transaction.rs @@ -1,20 +1,29 @@ use serde::{Deserialize, Serialize}; use crate::contract_class::ClassInfo; -use crate::core::{ClassHash, ContractAddress, Nonce}; +use crate::core::{ + calculate_contract_address, + ChainId, + ClassHash, + CompiledClassHash, + ContractAddress, + Nonce, +}; use crate::data_availability::DataAvailabilityMode; -use crate::rpc_transaction::RpcTransaction; +use crate::rpc_transaction::{RpcDeployAccountTransaction, RpcInvokeTransaction, RpcTransaction}; use crate::transaction::{ AccountDeploymentData, Calldata, ContractAddressSalt, - DeprecatedResourceBoundsMapping, PaymasterData, Tip, TransactionHash, + TransactionHasher, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; +use crate::StarknetApiError; macro_rules! implement_inner_tx_getter_calls { ($(($field:ident, $field_type:ty)),*) => { @@ -29,7 +38,7 @@ macro_rules! implement_getter_calls { $(pub fn $field(&self) -> $field_type { self.$field })* - }; +}; } /// Represents a paid Starknet transaction. @@ -83,7 +92,7 @@ impl Transaction { } } - pub fn resource_bounds(&self) -> Option<&DeprecatedResourceBoundsMapping> { + pub fn resource_bounds(&self) -> Option<&ValidResourceBounds> { match self { Transaction::Declare(declare_tx) => match &declare_tx.tx { crate::transaction::DeclareTransaction::V3(tx_v3) => Some(&tx_v3.resource_bounds), @@ -114,7 +123,9 @@ impl Transaction { sender_address, tip: *rpc_tx.tip(), nonce: *rpc_tx.nonce(), - resource_bounds: rpc_tx.resource_bounds().clone().into(), + resource_bounds: ValidResourceBounds::AllResources( + rpc_tx.resource_bounds().clone(), + ), signature: TransactionSignature::default(), calldata: Calldata::default(), nonce_data_availability_mode: DataAvailabilityMode::L1, @@ -136,6 +147,34 @@ pub struct DeclareTransaction { pub class_info: ClassInfo, } +impl DeclareTransaction { + pub fn create( + declare_tx: crate::transaction::DeclareTransaction, + class_info: ClassInfo, + chain_id: &ChainId, + ) -> Result { + let tx_hash = declare_tx.calculate_transaction_hash(chain_id, &declare_tx.version())?; + Ok(Self { tx: declare_tx, tx_hash, class_info }) + } + + /// Validates that the compiled class hash of the compiled contract class matches the supplied + /// compiled class hash. + /// Relevant only for version 3 transactions. + pub fn validate_compiled_class_hash(&self) -> bool { + let supplied_compiled_class_hash = match &self.tx { + crate::transaction::DeclareTransaction::V3(tx) => tx.compiled_class_hash, + crate::transaction::DeclareTransaction::V2(tx) => tx.compiled_class_hash, + crate::transaction::DeclareTransaction::V1(_) + | crate::transaction::DeclareTransaction::V0(_) => return true, + }; + + let casm_contract_class = &self.class_info.casm_contract_class; + let compiled_class_hash = CompiledClassHash(casm_contract_class.compiled_class_hash()); + + compiled_class_hash == supplied_compiled_class_hash + } +} + #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct DeployAccountTransaction { pub tx: crate::transaction::DeployAccountTransaction, @@ -157,6 +196,29 @@ impl DeployAccountTransaction { pub fn tx(&self) -> &crate::transaction::DeployAccountTransaction { &self.tx } + + pub fn create( + deploy_account_tx: crate::transaction::DeployAccountTransaction, + chain_id: &ChainId, + ) -> Result { + let contract_address = calculate_contract_address( + deploy_account_tx.contract_address_salt(), + deploy_account_tx.class_hash(), + &deploy_account_tx.constructor_calldata(), + ContractAddress::default(), + )?; + let tx_hash = + deploy_account_tx.calculate_transaction_hash(chain_id, &deploy_account_tx.version())?; + Ok(Self { tx: deploy_account_tx, tx_hash, contract_address }) + } + + pub fn from_rpc_tx( + rpc_tx: RpcDeployAccountTransaction, + chain_id: &ChainId, + ) -> Result { + let deploy_account_tx: crate::transaction::DeployAccountTransaction = rpc_tx.into(); + Self::create(deploy_account_tx, chain_id) + } } #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] @@ -178,4 +240,20 @@ impl InvokeTransaction { pub fn tx(&self) -> &crate::transaction::InvokeTransaction { &self.tx } + + pub fn create( + invoke_tx: crate::transaction::InvokeTransaction, + chain_id: &ChainId, + ) -> Result { + let tx_hash = invoke_tx.calculate_transaction_hash(chain_id, &invoke_tx.version())?; + Ok(Self { tx: invoke_tx, tx_hash }) + } + + pub fn from_rpc_tx( + rpc_tx: RpcInvokeTransaction, + chain_id: &ChainId, + ) -> Result { + let invoke_tx: crate::transaction::InvokeTransaction = rpc_tx.into(); + Self::create(invoke_tx, chain_id) + } } diff --git a/crates/starknet_api/src/lib.rs b/crates/starknet_api/src/lib.rs index 0b335dcfc2..404aa526ab 100644 --- a/crates/starknet_api/src/lib.rs +++ b/crates/starknet_api/src/lib.rs @@ -15,6 +15,8 @@ pub mod hash; pub mod rpc_transaction; pub mod serde_utils; pub mod state; +#[cfg(any(feature = "testing", test))] +pub mod test_utils; pub mod transaction; pub mod transaction_hash; pub mod type_utils; diff --git a/crates/starknet_api/src/rpc_transaction.rs b/crates/starknet_api/src/rpc_transaction.rs index 2c402c2d9b..d489835db3 100644 --- a/crates/starknet_api/src/rpc_transaction.rs +++ b/crates/starknet_api/src/rpc_transaction.rs @@ -2,8 +2,6 @@ #[path = "rpc_transaction_test.rs"] mod rpc_transaction_test; -use std::collections::BTreeMap; - use serde::{Deserialize, Serialize}; use starknet_types_core::felt::Felt; @@ -18,13 +16,20 @@ use crate::data_availability::DataAvailabilityMode; use crate::state::EntryPoint; use crate::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, + DeclareTransaction, + DeclareTransactionV3, + DeployAccountTransaction, + DeployAccountTransactionV3, + InvokeTransaction, + InvokeTransactionV3, PaymasterData, - Resource, - ResourceBounds, Tip, + Transaction, TransactionSignature, + ValidResourceBounds, }; use crate::StarknetApiError; @@ -63,7 +68,7 @@ macro_rules! implement_ref_getters { impl RpcTransaction { implement_ref_getters!( (nonce, Nonce), - (resource_bounds, ResourceBoundsMapping), + (resource_bounds, AllResourceBounds), (signature, TransactionSignature), (tip, Tip) ); @@ -84,6 +89,16 @@ impl RpcTransaction { } } +impl From for Transaction { + fn from(rpc_transaction: RpcTransaction) -> Self { + match rpc_transaction { + RpcTransaction::Declare(tx) => Transaction::Declare(tx.into()), + RpcTransaction::DeployAccount(tx) => Transaction::DeployAccount(tx.into()), + RpcTransaction::Invoke(tx) => Transaction::Invoke(tx.into()), + } + } +} + /// A RPC declare transaction. /// /// This transaction is equivalent to the component DECLARE_TXN in the @@ -98,6 +113,14 @@ pub enum RpcDeclareTransaction { V3(RpcDeclareTransactionV3), } +impl From for DeclareTransaction { + fn from(rpc_declare_transaction: RpcDeclareTransaction) -> Self { + match rpc_declare_transaction { + RpcDeclareTransaction::V3(tx) => DeclareTransaction::V3(tx.into()), + } + } +} + /// A RPC deploy account transaction. /// /// This transaction is equivalent to the component DEPLOY_ACCOUNT_TXN in the @@ -111,6 +134,14 @@ pub enum RpcDeployAccountTransaction { V3(RpcDeployAccountTransactionV3), } +impl From for DeployAccountTransaction { + fn from(rpc_deploy_account_transaction: RpcDeployAccountTransaction) -> Self { + match rpc_deploy_account_transaction { + RpcDeployAccountTransaction::V3(tx) => DeployAccountTransaction::V3(tx.into()), + } + } +} + /// A RPC invoke transaction. /// /// This transaction is equivalent to the component INVOKE_TXN in the @@ -124,6 +155,14 @@ pub enum RpcInvokeTransaction { V3(RpcInvokeTransactionV3), } +impl From for InvokeTransaction { + fn from(rpc_invoke_tx: RpcInvokeTransaction) -> Self { + match rpc_invoke_tx { + RpcInvokeTransaction::V3(tx) => InvokeTransaction::V3(tx.into()), + } + } +} + /// A declare transaction of a Cairo-v1 contract class that can be added to Starknet through the /// RPC. #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] @@ -135,7 +174,7 @@ pub struct RpcDeclareTransactionV3 { pub signature: TransactionSignature, pub nonce: Nonce, pub contract_class: ContractClass, - pub resource_bounds: ResourceBoundsMapping, + pub resource_bounds: AllResourceBounds, pub tip: Tip, pub paymaster_data: PaymasterData, pub account_deployment_data: AccountDeploymentData, @@ -143,6 +182,25 @@ pub struct RpcDeclareTransactionV3 { pub fee_data_availability_mode: DataAvailabilityMode, } +impl From for DeclareTransactionV3 { + fn from(tx: RpcDeclareTransactionV3) -> Self { + Self { + class_hash: ClassHash::default(), /* FIXME(yael 15/4/24): call the starknet-api + * function once ready */ + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds), + tip: tx.tip, + signature: tx.signature, + nonce: tx.nonce, + compiled_class_hash: tx.compiled_class_hash, + sender_address: tx.sender_address, + nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: tx.fee_data_availability_mode, + paymaster_data: tx.paymaster_data, + account_deployment_data: tx.account_deployment_data, + } + } +} + /// A deploy account transaction that can be added to Starknet through the RPC. #[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] pub struct RpcDeployAccountTransactionV3 { @@ -151,13 +209,30 @@ pub struct RpcDeployAccountTransactionV3 { pub class_hash: ClassHash, pub contract_address_salt: ContractAddressSalt, pub constructor_calldata: Calldata, - pub resource_bounds: ResourceBoundsMapping, + pub resource_bounds: AllResourceBounds, pub tip: Tip, pub paymaster_data: PaymasterData, pub nonce_data_availability_mode: DataAvailabilityMode, pub fee_data_availability_mode: DataAvailabilityMode, } +impl From for DeployAccountTransactionV3 { + fn from(tx: RpcDeployAccountTransactionV3) -> Self { + Self { + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds), + tip: tx.tip, + signature: tx.signature, + nonce: tx.nonce, + class_hash: tx.class_hash, + contract_address_salt: tx.contract_address_salt, + constructor_calldata: tx.constructor_calldata, + nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: tx.fee_data_availability_mode, + paymaster_data: tx.paymaster_data, + } + } +} + /// An invoke account transaction that can be added to Starknet through the RPC. #[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] pub struct RpcInvokeTransactionV3 { @@ -165,7 +240,7 @@ pub struct RpcInvokeTransactionV3 { pub calldata: Calldata, pub signature: TransactionSignature, pub nonce: Nonce, - pub resource_bounds: ResourceBoundsMapping, + pub resource_bounds: AllResourceBounds, pub tip: Tip, pub paymaster_data: PaymasterData, pub account_deployment_data: AccountDeploymentData, @@ -173,6 +248,23 @@ pub struct RpcInvokeTransactionV3 { pub fee_data_availability_mode: DataAvailabilityMode, } +impl From for InvokeTransactionV3 { + fn from(tx: RpcInvokeTransactionV3) -> Self { + Self { + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds), + tip: tx.tip, + signature: tx.signature, + nonce: tx.nonce, + sender_address: tx.sender_address, + calldata: tx.calldata, + nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: tx.fee_data_availability_mode, + paymaster_data: tx.paymaster_data, + account_deployment_data: tx.account_deployment_data, + } + } +} + // The contract class in SN_API state doesn't have `contract_class_version`, not following the spec. #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct ContractClass { @@ -191,18 +283,3 @@ pub struct EntryPointByType { #[serde(rename = "L1_HANDLER")] pub l1handler: Vec, } - -// The serialization of the struct in transaction is in capital letters, not following the spec. -#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] -pub struct ResourceBoundsMapping { - pub l1_gas: ResourceBounds, - pub l2_gas: ResourceBounds, -} - -impl From for crate::transaction::DeprecatedResourceBoundsMapping { - fn from(mapping: ResourceBoundsMapping) -> crate::transaction::DeprecatedResourceBoundsMapping { - let map = - BTreeMap::from([(Resource::L1Gas, mapping.l1_gas), (Resource::L2Gas, mapping.l2_gas)]); - crate::transaction::DeprecatedResourceBoundsMapping(map) - } -} diff --git a/crates/starknet_api/src/rpc_transaction_test.rs b/crates/starknet_api/src/rpc_transaction_test.rs index e2fc6de4d9..92777b53ec 100644 --- a/crates/starknet_api/src/rpc_transaction_test.rs +++ b/crates/starknet_api/src/rpc_transaction_test.rs @@ -7,7 +7,6 @@ use crate::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce, Patricia use crate::rpc_transaction::{ ContractClass, DataAvailabilityMode, - ResourceBoundsMapping, RpcDeclareTransaction, RpcDeclareTransactionV3, RpcDeployAccountTransaction, @@ -18,6 +17,7 @@ use crate::rpc_transaction::{ }; use crate::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, PaymasterData, @@ -27,10 +27,11 @@ use crate::transaction::{ }; use crate::{contract_address, felt, patricia_key}; -fn create_resource_bounds_for_testing() -> ResourceBoundsMapping { - ResourceBoundsMapping { +fn create_resource_bounds_for_testing() -> AllResourceBounds { + AllResourceBounds { l1_gas: ResourceBounds { max_amount: 100, max_price_per_unit: 12 }, l2_gas: ResourceBounds { max_amount: 58, max_price_per_unit: 31 }, + l1_data_gas: ResourceBounds { max_amount: 66, max_price_per_unit: 25 }, } } diff --git a/crates/starknet_api/src/test_utils.rs b/crates/starknet_api/src/test_utils.rs new file mode 100644 index 0000000000..029d50f495 --- /dev/null +++ b/crates/starknet_api/src/test_utils.rs @@ -0,0 +1,3 @@ +pub mod declare; +pub mod deploy_account; +pub mod invoke; diff --git a/crates/starknet_api/src/test_utils/declare.rs b/crates/starknet_api/src/test_utils/declare.rs new file mode 100644 index 0000000000..8a6af8af91 --- /dev/null +++ b/crates/starknet_api/src/test_utils/declare.rs @@ -0,0 +1,130 @@ +use crate::contract_class::ClassInfo; +use crate::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; +use crate::data_availability::DataAvailabilityMode; +use crate::executable_transaction::DeclareTransaction as ExecutableDeclareTransaction; +use crate::transaction::{ + AccountDeploymentData, + DeclareTransaction, + DeclareTransactionV0V1, + DeclareTransactionV2, + DeclareTransactionV3, + Fee, + PaymasterData, + Tip, + TransactionHash, + TransactionSignature, + TransactionVersion, + ValidResourceBounds, +}; + +#[derive(Clone)] +pub struct DeclareTxArgs { + pub max_fee: Fee, + pub signature: TransactionSignature, + pub sender_address: ContractAddress, + pub version: TransactionVersion, + pub resource_bounds: ValidResourceBounds, + pub tip: Tip, + pub nonce_data_availability_mode: DataAvailabilityMode, + pub fee_data_availability_mode: DataAvailabilityMode, + pub paymaster_data: PaymasterData, + pub account_deployment_data: AccountDeploymentData, + pub nonce: Nonce, + pub class_hash: ClassHash, + pub compiled_class_hash: CompiledClassHash, + // TODO(Arni): Consider removing this field. + pub tx_hash: TransactionHash, +} + +impl Default for DeclareTxArgs { + fn default() -> Self { + Self { + max_fee: Fee::default(), + signature: TransactionSignature::default(), + sender_address: ContractAddress::default(), + version: TransactionVersion::THREE, + resource_bounds: ValidResourceBounds::create_for_testing(), + tip: Tip::default(), + nonce_data_availability_mode: DataAvailabilityMode::L1, + fee_data_availability_mode: DataAvailabilityMode::L1, + paymaster_data: PaymasterData::default(), + account_deployment_data: AccountDeploymentData::default(), + nonce: Nonce::default(), + class_hash: ClassHash::default(), + compiled_class_hash: CompiledClassHash::default(), + tx_hash: TransactionHash::default(), + } + } +} + +/// Utility macro for creating `DeclareTxArgs` to reduce boilerplate. +#[macro_export] +macro_rules! declare_tx_args { + ($($field:ident $(: $value:expr)?),* $(,)?) => { + $crate::test_utils::declare::DeclareTxArgs { + $($field $(: $value)?,)* + ..Default::default() + } + }; + ($($field:ident $(: $value:expr)?),* , ..$defaults:expr) => { + $crate::test_utils::declare::DeclareTxArgs { + $($field $(: $value)?,)* + ..$defaults + } + }; +} + +pub fn declare_tx(declare_tx_args: DeclareTxArgs) -> DeclareTransaction { + // TODO: Make TransactionVersion an enum and use match here. + if declare_tx_args.version == TransactionVersion::ZERO { + DeclareTransaction::V0(DeclareTransactionV0V1 { + max_fee: declare_tx_args.max_fee, + signature: declare_tx_args.signature, + sender_address: declare_tx_args.sender_address, + nonce: declare_tx_args.nonce, + class_hash: declare_tx_args.class_hash, + }) + } else if declare_tx_args.version == TransactionVersion::ONE { + DeclareTransaction::V1(DeclareTransactionV0V1 { + max_fee: declare_tx_args.max_fee, + signature: declare_tx_args.signature, + sender_address: declare_tx_args.sender_address, + nonce: declare_tx_args.nonce, + class_hash: declare_tx_args.class_hash, + }) + } else if declare_tx_args.version == TransactionVersion::TWO { + DeclareTransaction::V2(DeclareTransactionV2 { + max_fee: declare_tx_args.max_fee, + signature: declare_tx_args.signature, + sender_address: declare_tx_args.sender_address, + nonce: declare_tx_args.nonce, + class_hash: declare_tx_args.class_hash, + compiled_class_hash: declare_tx_args.compiled_class_hash, + }) + } else if declare_tx_args.version == TransactionVersion::THREE { + DeclareTransaction::V3(DeclareTransactionV3 { + signature: declare_tx_args.signature, + sender_address: declare_tx_args.sender_address, + resource_bounds: declare_tx_args.resource_bounds, + tip: declare_tx_args.tip, + nonce_data_availability_mode: declare_tx_args.nonce_data_availability_mode, + fee_data_availability_mode: declare_tx_args.fee_data_availability_mode, + paymaster_data: declare_tx_args.paymaster_data, + account_deployment_data: declare_tx_args.account_deployment_data, + nonce: declare_tx_args.nonce, + class_hash: declare_tx_args.class_hash, + compiled_class_hash: declare_tx_args.compiled_class_hash, + }) + } else { + panic!("Unsupported transaction version: {:?}.", declare_tx_args.version) + } +} + +pub fn executable_declare_tx( + declare_tx_args: DeclareTxArgs, + class_info: ClassInfo, +) -> ExecutableDeclareTransaction { + let tx_hash = declare_tx_args.tx_hash; + let tx = declare_tx(declare_tx_args); + ExecutableDeclareTransaction { tx, tx_hash, class_info } +} diff --git a/crates/starknet_api/src/test_utils/deploy_account.rs b/crates/starknet_api/src/test_utils/deploy_account.rs new file mode 100644 index 0000000000..de64c1a99a --- /dev/null +++ b/crates/starknet_api/src/test_utils/deploy_account.rs @@ -0,0 +1,120 @@ +use crate::core::{calculate_contract_address, ClassHash, ContractAddress, Nonce}; +use crate::data_availability::DataAvailabilityMode; +use crate::executable_transaction::DeployAccountTransaction as ExecutableDeployAccountTransaction; +use crate::transaction::{ + Calldata, + ContractAddressSalt, + DeployAccountTransaction, + DeployAccountTransactionV1, + DeployAccountTransactionV3, + Fee, + PaymasterData, + Tip, + TransactionHash, + TransactionSignature, + TransactionVersion, + ValidResourceBounds, +}; + +#[derive(Clone)] +pub struct DeployAccountTxArgs { + pub max_fee: Fee, + pub signature: TransactionSignature, + pub deployer_address: ContractAddress, + pub version: TransactionVersion, + pub resource_bounds: ValidResourceBounds, + pub tip: Tip, + pub nonce_data_availability_mode: DataAvailabilityMode, + pub fee_data_availability_mode: DataAvailabilityMode, + pub paymaster_data: PaymasterData, + pub nonce: Nonce, + pub class_hash: ClassHash, + pub contract_address_salt: ContractAddressSalt, + pub constructor_calldata: Calldata, +} + +impl Default for DeployAccountTxArgs { + fn default() -> Self { + DeployAccountTxArgs { + max_fee: Fee::default(), + signature: TransactionSignature::default(), + deployer_address: ContractAddress::default(), + version: TransactionVersion::THREE, + resource_bounds: ValidResourceBounds::create_for_testing(), + tip: Tip::default(), + nonce_data_availability_mode: DataAvailabilityMode::L1, + fee_data_availability_mode: DataAvailabilityMode::L1, + paymaster_data: PaymasterData::default(), + nonce: Nonce::default(), + class_hash: ClassHash::default(), + contract_address_salt: ContractAddressSalt::default(), + constructor_calldata: Calldata::default(), + } + } +} + +/// Utility macro for creating `DeployAccountTxArgs` to reduce boilerplate. +#[macro_export] +macro_rules! deploy_account_tx_args { + ($($field:ident $(: $value:expr)?),* $(,)?) => { + $crate::test_utils::deploy_account::DeployAccountTxArgs { + $($field $(: $value)?,)* + ..Default::default() + } + }; + ($($field:ident $(: $value:expr)?),* , ..$defaults:expr) => { + $crate::test_utils::deploy_account::DeployAccountTxArgs { + $($field $(: $value)?,)* + ..$defaults + } + }; +} + +pub fn deploy_account_tx( + deploy_tx_args: DeployAccountTxArgs, + nonce: Nonce, +) -> DeployAccountTransaction { + // TODO: Make TransactionVersion an enum and use match here. + if deploy_tx_args.version == TransactionVersion::ONE { + DeployAccountTransaction::V1(DeployAccountTransactionV1 { + max_fee: deploy_tx_args.max_fee, + signature: deploy_tx_args.signature, + nonce, + class_hash: deploy_tx_args.class_hash, + contract_address_salt: deploy_tx_args.contract_address_salt, + constructor_calldata: deploy_tx_args.constructor_calldata, + }) + } else if deploy_tx_args.version == TransactionVersion::THREE { + DeployAccountTransaction::V3(DeployAccountTransactionV3 { + signature: deploy_tx_args.signature, + resource_bounds: deploy_tx_args.resource_bounds, + tip: deploy_tx_args.tip, + nonce_data_availability_mode: deploy_tx_args.nonce_data_availability_mode, + fee_data_availability_mode: deploy_tx_args.fee_data_availability_mode, + paymaster_data: deploy_tx_args.paymaster_data, + nonce, + class_hash: deploy_tx_args.class_hash, + contract_address_salt: deploy_tx_args.contract_address_salt, + constructor_calldata: deploy_tx_args.constructor_calldata, + }) + } else { + panic!("Unsupported transaction version: {:?}.", deploy_tx_args.version) + } +} + +pub fn executable_deploy_account_tx( + deploy_tx_args: DeployAccountTxArgs, + nonce: Nonce, +) -> ExecutableDeployAccountTransaction { + let default_tx_hash = TransactionHash::default(); + let contract_address = calculate_contract_address( + deploy_tx_args.contract_address_salt, + deploy_tx_args.class_hash, + &deploy_tx_args.constructor_calldata, + deploy_tx_args.deployer_address, + ) + .unwrap(); + let tx = deploy_account_tx(deploy_tx_args, nonce); + + ExecutableDeployAccountTransaction { tx, tx_hash: default_tx_hash, contract_address } +} diff --git a/crates/starknet_api/src/test_utils/invoke.rs b/crates/starknet_api/src/test_utils/invoke.rs new file mode 100644 index 0000000000..09f9f84721 --- /dev/null +++ b/crates/starknet_api/src/test_utils/invoke.rs @@ -0,0 +1,114 @@ +use crate::calldata; +use crate::core::{ContractAddress, Nonce}; +use crate::data_availability::DataAvailabilityMode; +use crate::executable_transaction::InvokeTransaction as ExecutableInvokeTransaction; +use crate::transaction::{ + AccountDeploymentData, + Calldata, + Fee, + InvokeTransaction, + InvokeTransactionV1, + InvokeTransactionV3, + PaymasterData, + Tip, + TransactionHash, + TransactionSignature, + TransactionVersion, + ValidResourceBounds, +}; + +#[derive(Clone)] +pub struct InvokeTxArgs { + pub max_fee: Fee, + pub signature: TransactionSignature, + pub sender_address: ContractAddress, + pub calldata: Calldata, + pub version: TransactionVersion, + pub resource_bounds: ValidResourceBounds, + pub tip: Tip, + pub nonce_data_availability_mode: DataAvailabilityMode, + pub fee_data_availability_mode: DataAvailabilityMode, + pub paymaster_data: PaymasterData, + pub account_deployment_data: AccountDeploymentData, + pub nonce: Nonce, + pub only_query: bool, +} + +impl Default for InvokeTxArgs { + fn default() -> Self { + InvokeTxArgs { + max_fee: Fee::default(), + signature: TransactionSignature::default(), + sender_address: ContractAddress::default(), + calldata: calldata![], + version: TransactionVersion::THREE, + resource_bounds: ValidResourceBounds::create_for_testing(), + tip: Tip::default(), + nonce_data_availability_mode: DataAvailabilityMode::L1, + fee_data_availability_mode: DataAvailabilityMode::L1, + paymaster_data: PaymasterData::default(), + account_deployment_data: AccountDeploymentData::default(), + nonce: Nonce::default(), + only_query: false, + } + } +} + +/// Utility macro for creating `InvokeTxArgs` to reduce boilerplate. +#[macro_export] +macro_rules! invoke_tx_args { + ($($field:ident $(: $value:expr)?),* $(,)?) => { + $crate::test_utils::invoke::InvokeTxArgs { + $($field $(: $value)?,)* + ..Default::default() + } + }; + ($($field:ident $(: $value:expr)?),* , ..$defaults:expr) => { + $crate::test_utils::invoke::InvokeTxArgs { + $($field $(: $value)?,)* + ..$defaults + } + }; +} + +pub fn invoke_tx(invoke_args: InvokeTxArgs) -> InvokeTransaction { + // TODO: Make TransactionVersion an enum and use match here. + if invoke_args.version == TransactionVersion::ZERO { + // TODO(Arni): Implement V0. See blockifier test utils for reference. There is an issue with + // the computation of the entry_point_selector. + panic!( + "This test util does not supported creation of transaction version: {:?}.", + invoke_args.version + ); + } else if invoke_args.version == TransactionVersion::ONE { + InvokeTransaction::V1(InvokeTransactionV1 { + max_fee: invoke_args.max_fee, + sender_address: invoke_args.sender_address, + nonce: invoke_args.nonce, + calldata: invoke_args.calldata, + signature: invoke_args.signature, + }) + } else if invoke_args.version == TransactionVersion::THREE { + InvokeTransaction::V3(InvokeTransactionV3 { + resource_bounds: invoke_args.resource_bounds, + calldata: invoke_args.calldata, + sender_address: invoke_args.sender_address, + nonce: invoke_args.nonce, + signature: invoke_args.signature, + tip: invoke_args.tip, + nonce_data_availability_mode: invoke_args.nonce_data_availability_mode, + fee_data_availability_mode: invoke_args.fee_data_availability_mode, + paymaster_data: invoke_args.paymaster_data, + account_deployment_data: invoke_args.account_deployment_data, + }) + } else { + panic!("Unsupported transaction version: {:?}.", invoke_args.version) + } +} + +pub fn executable_invoke_tx(invoke_args: InvokeTxArgs) -> ExecutableInvokeTransaction { + let default_tx_hash = TransactionHash::default(); + let tx = invoke_tx(invoke_args); + + ExecutableInvokeTransaction { tx, tx_hash: default_tx_hash } +} diff --git a/crates/starknet_api/src/transaction.rs b/crates/starknet_api/src/transaction.rs index 5aa8cdcb08..fd45c89186 100644 --- a/crates/starknet_api/src/transaction.rs +++ b/crates/starknet_api/src/transaction.rs @@ -1,11 +1,10 @@ -use std::collections::{BTreeMap, HashSet}; +use std::collections::BTreeMap; use std::fmt::Display; use std::sync::Arc; use derive_more::{Display, From}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use starknet_types_core::felt::Felt; -use strum::IntoEnumIterator; use strum_macros::EnumIter; use crate::block::{BlockHash, BlockNumber}; @@ -216,7 +215,7 @@ impl TransactionHasher for DeclareTransactionV2 { /// A declare V3 transaction. #[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] pub struct DeclareTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -325,7 +324,7 @@ impl TransactionHasher for DeployAccountTransactionV1 { /// A deploy account V3 transaction. #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] pub struct DeployAccountTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -462,7 +461,7 @@ impl TransactionHasher for InvokeTransactionV1 { /// An invoke V3 transaction. #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] pub struct InvokeTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -867,14 +866,25 @@ impl From for Felt { /// Execution resource. #[derive( - Clone, Copy, Debug, Deserialize, EnumIter, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, + Clone, + Copy, + Debug, + Deserialize, + EnumIter, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + Serialize, + Display, )] pub enum Resource { #[serde(rename = "L1_GAS")] L1Gas, #[serde(rename = "L2_GAS")] L2Gas, - #[serde(rename = "L1_DATA_GAS")] + #[serde(rename = "L1_DATA")] L1DataGas, } @@ -883,6 +893,7 @@ pub enum Resource { #[derive( Clone, Copy, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, )] +// TODO(Nimrod): Consider renaming this struct. pub struct ResourceBounds { // Specifies the maximum amount of each resource allowed for usage during the execution. #[serde(serialize_with = "u64_to_hex", deserialize_with = "hex_to_u64")] @@ -935,34 +946,41 @@ where // TODO(Nimrod): Remove this struct definition. pub struct DeprecatedResourceBoundsMapping(pub BTreeMap); -impl TryFrom> for DeprecatedResourceBoundsMapping { - type Error = StarknetApiError; - fn try_from( - resource_resource_bounds_pairs: Vec<(Resource, ResourceBounds)>, - ) -> Result { - let n_variants = Resource::iter().count(); - let allowed_signed_variants = [n_variants, n_variants - 1]; - let unique_resources: HashSet = - HashSet::from_iter(resource_resource_bounds_pairs.iter().map(|(k, _)| *k)); - if !allowed_signed_variants.contains(&unique_resources.len()) - || !allowed_signed_variants.contains(&resource_resource_bounds_pairs.len()) - { - // TODO(Nimrod): Consider making this check more strict. - Err(StarknetApiError::InvalidResourceMappingInitializer(format!( - "{:?}", - resource_resource_bounds_pairs - ))) - } else { - Ok(Self(resource_resource_bounds_pairs.into_iter().collect::>())) - } - } -} - +#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub enum ValidResourceBounds { L1Gas(ResourceBounds), // Pre 0.13.3. Only L1 gas. L2 bounds are signed but never used. AllResources(AllResourceBounds), } +impl Default for ValidResourceBounds { + fn default() -> Self { + ValidResourceBounds::AllResources(AllResourceBounds::default()) + } +} + +impl ValidResourceBounds { + pub fn get_l1_bounds(&self) -> ResourceBounds { + match self { + Self::L1Gas(l1_bounds) => *l1_bounds, + Self::AllResources(AllResourceBounds { l1_gas, .. }) => *l1_gas, + } + } + + pub fn get_l2_bounds(&self) -> ResourceBounds { + match self { + Self::L1Gas(_) => ResourceBounds::default(), + Self::AllResources(AllResourceBounds { l2_gas, .. }) => *l2_gas, + } + } + + // TODO(Nimrod): Default testing bounds should probably be AllResourceBounds variant. + #[cfg(any(feature = "testing", test))] + pub fn create_for_testing() -> Self { + Self::L1Gas(ResourceBounds { max_amount: 0, max_price_per_unit: 1 }) + } +} + +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize)] pub struct AllResourceBounds { pub l1_gas: ResourceBounds, pub l2_gas: ResourceBounds, @@ -970,8 +988,7 @@ pub struct AllResourceBounds { } impl AllResourceBounds { - #[allow(dead_code)] - fn get_bound(&self, resource: Resource) -> ResourceBounds { + pub fn get_bound(&self, resource: Resource) -> ResourceBounds { match resource { Resource::L1Gas => self.l1_gas, Resource::L2Gas => self.l2_gas, @@ -980,6 +997,45 @@ impl AllResourceBounds { } } +/// Deserializes raw resource bounds, given as map, into valid resource bounds. +// TODO(Nimrod): Figure out how to get same result with adding #[derive(Deserialize)]. +impl<'de> Deserialize<'de> for ValidResourceBounds { + fn deserialize(de: D) -> Result + where + D: Deserializer<'de>, + { + let raw_resource_bounds: BTreeMap = Deserialize::deserialize(de)?; + ValidResourceBounds::try_from(DeprecatedResourceBoundsMapping(raw_resource_bounds)) + .map_err(serde::de::Error::custom) + } +} + +/// Serializes ValidResourceBounds as map for Backwards compatibility. +// TODO(Nimrod): Figure out how to get same result with adding #[derive(Serialize)]. +impl Serialize for ValidResourceBounds { + fn serialize(&self, s: S) -> Result + where + S: Serializer, + { + let map = match self { + ValidResourceBounds::L1Gas(l1_gas) => BTreeMap::from([ + (Resource::L1Gas, *l1_gas), + (Resource::L2Gas, ResourceBounds::default()), + ]), + ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas, + l2_gas, + l1_data_gas, + }) => BTreeMap::from([ + (Resource::L1Gas, *l1_gas), + (Resource::L2Gas, *l2_gas), + (Resource::L1DataGas, *l1_data_gas), + ]), + }; + DeprecatedResourceBoundsMapping(map).serialize(s) + } +} + impl TryFrom for ValidResourceBounds { type Error = StarknetApiError; fn try_from( diff --git a/crates/starknet_api/src/transaction_hash.rs b/crates/starknet_api/src/transaction_hash.rs index cb01a4c451..9351014bbd 100644 --- a/crates/starknet_api/src/transaction_hash.rs +++ b/crates/starknet_api/src/transaction_hash.rs @@ -15,18 +15,17 @@ use crate::transaction::{ DeployAccountTransactionV1, DeployAccountTransactionV3, DeployTransaction, - DeprecatedResourceBoundsMapping, InvokeTransaction, InvokeTransactionV0, InvokeTransactionV1, InvokeTransactionV3, L1HandlerTransaction, - Resource, ResourceBounds, Tip, Transaction, TransactionHash, TransactionVersion, + ValidResourceBounds, }; use crate::StarknetApiError; @@ -147,6 +146,7 @@ fn get_deprecated_transaction_hashes( } /// Validates the hash of a starknet transaction. +/// /// For transactions on testnet or those with a low block_number, we validate the /// transaction hash against all potential historical hash computations. For recent /// transactions on mainnet, the hash is validated by calculating the precise hash @@ -176,16 +176,14 @@ pub(crate) fn ascii_as_felt(ascii_str: &str) -> Result { // An implementation of the SNIP: https://github.com/EvyatarO/SNIPs/blob/snip-8/SNIPS/snip-8.md fn get_tip_resource_bounds_hash( - resource_bounds_mapping: &DeprecatedResourceBoundsMapping, + resource_bounds: &ValidResourceBounds, tip: &Tip, ) -> Result { - let l1_resource_bounds = - resource_bounds_mapping.0.get(&Resource::L1Gas).expect("Missing l1 resource"); - let l1_resource = get_concat_resource(l1_resource_bounds, L1_GAS)?; + let l1_resource_bounds = resource_bounds.get_l1_bounds(); + let l2_resource_bounds = resource_bounds.get_l2_bounds(); - let l2_resource_bounds = - resource_bounds_mapping.0.get(&Resource::L2Gas).expect("Missing l2 resource"); - let l2_resource = get_concat_resource(l2_resource_bounds, L2_GAS)?; + let l1_resource = get_concat_resource(&l1_resource_bounds, L1_GAS)?; + let l2_resource = get_concat_resource(&l2_resource_bounds, L2_GAS)?; Ok(HashChain::new() .chain(&tip.0.into()) diff --git a/crates/starknet_client/Cargo.toml b/crates/starknet_client/Cargo.toml index 34dcf2b4a6..ac344a3296 100644 --- a/crates/starknet_client/Cargo.toml +++ b/crates/starknet_client/Cargo.toml @@ -40,6 +40,7 @@ url.workspace = true assert_matches.workspace = true enum-iterator.workspace = true mockall.workspace = true +# TODO: Upgrade to workspace-defined version. mockito = "0.31.0" rand.workspace = true rand_chacha.workspace = true diff --git a/crates/starknet_client/src/reader/objects/test_utils.rs b/crates/starknet_client/src/reader/objects/test_utils.rs index 3876eeb723..f4d0f8491e 100644 --- a/crates/starknet_client/src/reader/objects/test_utils.rs +++ b/crates/starknet_client/src/reader/objects/test_utils.rs @@ -16,7 +16,6 @@ use starknet_api::transaction::{ AccountDeploymentData, Calldata, ContractAddressSalt, - DeprecatedResourceBoundsMapping, Event, Fee, L1ToL2Payload, @@ -27,6 +26,7 @@ use starknet_api::transaction::{ TransactionOffsetInBlock, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; @@ -60,7 +60,7 @@ auto_impl_get_test_instance! { Reserved = 0, } pub struct IntermediateDeclareTransaction { - pub resource_bounds: Option, + pub resource_bounds: Option, pub tip: Option, pub signature: TransactionSignature, pub nonce: Nonce, @@ -76,7 +76,7 @@ auto_impl_get_test_instance! { pub transaction_hash: TransactionHash, } pub struct IntermediateDeployAccountTransaction { - pub resource_bounds: Option, + pub resource_bounds: Option, pub tip: Option, pub signature: TransactionSignature, pub nonce: Nonce, @@ -100,7 +100,7 @@ auto_impl_get_test_instance! { pub version: TransactionVersion, } pub struct IntermediateInvokeTransaction { - pub resource_bounds: Option, + pub resource_bounds: Option, pub tip: Option, pub calldata: Calldata, pub sender_address: ContractAddress, diff --git a/crates/starknet_client/src/reader/objects/transaction.rs b/crates/starknet_client/src/reader/objects/transaction.rs index 839ce41a74..4121cb26d8 100644 --- a/crates/starknet_client/src/reader/objects/transaction.rs +++ b/crates/starknet_client/src/reader/objects/transaction.rs @@ -23,7 +23,6 @@ use starknet_api::transaction::{ DeclareTransactionOutput, DeployAccountTransactionOutput, DeployTransactionOutput, - DeprecatedResourceBoundsMapping, Event, Fee, InvokeTransactionOutput, @@ -40,6 +39,7 @@ use starknet_api::transaction::{ TransactionOutput, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use strum_macros::EnumIter; use tracing::error; @@ -178,7 +178,7 @@ impl From for starknet_api::data_availability::Dat #[serde(deny_unknown_fields)] pub struct IntermediateDeclareTransaction { #[serde(skip_serializing_if = "Option::is_none")] - pub resource_bounds: Option, + pub resource_bounds: Option, #[serde(skip_serializing_if = "Option::is_none")] pub tip: Option, pub signature: TransactionSignature, @@ -347,7 +347,7 @@ impl From for starknet_api::transaction::DeployTransaction { #[serde(deny_unknown_fields)] pub struct IntermediateDeployAccountTransaction { #[serde(skip_serializing_if = "Option::is_none")] - pub resource_bounds: Option, + pub resource_bounds: Option, #[serde(skip_serializing_if = "Option::is_none")] pub tip: Option, pub signature: TransactionSignature, @@ -470,7 +470,7 @@ impl TryFrom #[serde(deny_unknown_fields)] pub struct IntermediateInvokeTransaction { #[serde(skip_serializing_if = "Option::is_none")] - pub resource_bounds: Option, + pub resource_bounds: Option, #[serde(skip_serializing_if = "Option::is_none")] pub tip: Option, pub calldata: Calldata, diff --git a/crates/starknet_client/src/writer/objects/transaction.rs b/crates/starknet_client/src/writer/objects/transaction.rs index 50adae8afd..444d41aad8 100644 --- a/crates/starknet_client/src/writer/objects/transaction.rs +++ b/crates/starknet_client/src/writer/objects/transaction.rs @@ -129,6 +129,7 @@ pub enum DeployAccountTransaction { } /// An invoke account transaction that can be added to Starknet through the Starknet gateway. +/// /// The invoke is a V0 transaction. /// It has a serialization format that the Starknet gateway accepts in the `add_transaction` /// HTTP method. @@ -146,6 +147,7 @@ pub struct InvokeV0Transaction { } /// An invoke account transaction that can be added to Starknet through the Starknet gateway. +/// /// The invoke is a V1 transaction. /// It has a serialization format that the Starknet gateway accepts in the `add_transaction` /// HTTP method. @@ -162,6 +164,7 @@ pub struct InvokeV1Transaction { } /// An invoke account transaction that can be added to Starknet through the Starknet gateway. +/// /// The invoke is a V3 transaction. /// It has a serialization format that the Starknet gateway accepts in the `add_transaction` /// HTTP method. diff --git a/crates/starknet_committer/Cargo.toml b/crates/starknet_committer/Cargo.toml index 1546be4c6f..bc354434e1 100644 --- a/crates/starknet_committer/Cargo.toml +++ b/crates/starknet_committer/Cargo.toml @@ -4,7 +4,6 @@ version.workspace = true edition.workspace = true repository.workspace = true license.workspace = true -license-file.workspace = true description = "Computes and manages Starknet state." @@ -13,10 +12,10 @@ hex.workspace = true pretty_assertions.workspace = true rstest.workspace = true serde_json.workspace = true -starknet-types-core.workspace = true +starknet-types-core = { workspace = true, features = ["hash"] } starknet_patricia = { workspace = true, features = ["testing"] } thiserror.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["rt"] } tracing.workspace = true [lints] diff --git a/crates/starknet_patricia/Cargo.toml b/crates/starknet_patricia/Cargo.toml index 01de51a31d..f636ebd862 100644 --- a/crates/starknet_patricia/Cargo.toml +++ b/crates/starknet_patricia/Cargo.toml @@ -29,7 +29,7 @@ starknet-types-core.workspace = true strum.workspace = true strum_macros.workspace = true thiserror.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["macros", "rt", "rt-multi-thread"] } tracing.workspace = true # Optional dependencies required for tests and the testing feature. diff --git a/crates/starknet_patricia/src/patricia_merkle_tree/original_skeleton_tree/tree.rs b/crates/starknet_patricia/src/patricia_merkle_tree/original_skeleton_tree/tree.rs index 42530983eb..40d29105f4 100644 --- a/crates/starknet_patricia/src/patricia_merkle_tree/original_skeleton_tree/tree.rs +++ b/crates/starknet_patricia/src/patricia_merkle_tree/original_skeleton_tree/tree.rs @@ -12,6 +12,7 @@ pub type OriginalSkeletonNodeMap = HashMap; pub type OriginalSkeletonTreeResult = Result; /// Consider a Patricia-Merkle Tree which should be updated with new leaves. +/// /// This trait represents the structure of the subtree which will be modified in the /// update. It also contains the hashes (for edge siblings - also the edge data) of the unmodified /// nodes on the Merkle paths from the updated leaves to the root. diff --git a/crates/starknet_patricia/src/patricia_merkle_tree/updated_skeleton_tree/tree.rs b/crates/starknet_patricia/src/patricia_merkle_tree/updated_skeleton_tree/tree.rs index 679da99832..40efd67d42 100644 --- a/crates/starknet_patricia/src/patricia_merkle_tree/updated_skeleton_tree/tree.rs +++ b/crates/starknet_patricia/src/patricia_merkle_tree/updated_skeleton_tree/tree.rs @@ -17,6 +17,7 @@ pub(crate) type UpdatedSkeletonNodeMap = HashMap pub(crate) type UpdatedSkeletonTreeResult = Result; /// Consider a Patricia-Merkle Tree which has been updated with new leaves. +/// /// This trait represents the structure of the subtree which was modified in the update. /// It also contains the hashes of the unmodified nodes on the Merkle paths from the updated leaves /// to the root. diff --git a/crates/starknet_sierra_compile/Cargo.toml b/crates/starknet_sierra_compile/Cargo.toml index 5d76a24570..97e211e96a 100644 --- a/crates/starknet_sierra_compile/Cargo.toml +++ b/crates/starknet_sierra_compile/Cargo.toml @@ -17,6 +17,7 @@ serde.workspace = true serde_json.workspace = true starknet-types-core.workspace = true starknet_api.workspace = true +tempfile.workspace = true thiserror.workspace = true validator.workspace = true diff --git a/crates/starknet_sierra_compile/build.rs b/crates/starknet_sierra_compile/build.rs new file mode 100644 index 0000000000..ff1873ecf1 --- /dev/null +++ b/crates/starknet_sierra_compile/build.rs @@ -0,0 +1,81 @@ +use std::process::Command; + +include!("src/build_utils.rs"); + +fn main() { + println!("cargo:rerun-if-changed=../../Cargo.lock"); + println!("cargo:rerun-if-changed=build.rs"); + + install_starknet_sierra_compile(); +} + +const REQUIRED_VERSION: &str = "2.7.1"; + +/// Downloads the Cairo crate from StarkWare's release page and extracts its contents into the +/// `target` directory. This crate includes the `starknet-sierra-compile` binary, which is used to +/// compile Sierra to Casm. The binary is executed as a subprocess whenever Sierra compilation is +/// required. +fn install_starknet_sierra_compile() { + let binary_path = binary_path(); + + match Command::new(&binary_path).args(["--version"]).output() { + Ok(binary_version) => { + let binary_version = String::from_utf8(binary_version.stdout) + .expect("Failed to convert the binary version to a string."); + if binary_version.contains(REQUIRED_VERSION) { + println!("The starknet-sierra-compile binary is up to date."); + return; + } else { + println!( + "The starknet-sierra-compile binary is not up to date. Installing the \ + required version." + ); + std::fs::remove_file(&binary_path).expect("Failed to remove the old binary."); + } + } + Err(_) => { + println!( + "The starknet-sierra-compile binary is not installed. Installing the required \ + version." + ); + } + } + + let out_dir = out_dir(); + let temp_cargo_path = out_dir.join("cargo"); + let post_install_file_path = temp_cargo_path.join("bin").join(BINARY_NAME); + + // Create the temporary cargo directory if it doesn't exist + std::fs::create_dir_all(&temp_cargo_path).expect("Failed to create cargo directory"); + let install_command_status = Command::new("cargo") + .args([ + "install", + BINARY_NAME, + "--root", + temp_cargo_path.to_str().expect("Failed to convert cargo_path to str"), + "--version", + REQUIRED_VERSION, + ]) + .status() + .expect("Failed to install starknet-sierra-compile"); + + if !install_command_status.success() { + panic!("Failed to install starknet-sierra-compile"); + } + + // Move the 'starknet-sierra-compile' executable to a shared location + std::fs::create_dir_all(shared_folder_dir()) + .expect("Failed to create shared executables folder"); + let move_command_status = Command::new("mv") + .args([post_install_file_path.as_os_str(), binary_path.as_os_str()]) + .status() + .expect("Failed to perform mv command."); + + if !move_command_status.success() { + panic!("Failed to move the starknet-sierra-compile binary to the shared folder."); + } + + std::fs::remove_dir_all(temp_cargo_path).expect("Failed to remove the cargo directory."); + + println!("Successfully set executable file: {:?}", binary_path.display()); +} diff --git a/crates/starknet_sierra_compile/src/build_utils.rs b/crates/starknet_sierra_compile/src/build_utils.rs new file mode 100644 index 0000000000..af239682e5 --- /dev/null +++ b/crates/starknet_sierra_compile/src/build_utils.rs @@ -0,0 +1,28 @@ +use std::path::{Path, PathBuf}; + +const BINARY_NAME: &str = "starknet-sierra-compile"; + +fn out_dir() -> PathBuf { + Path::new(&std::env::var("OUT_DIR").expect("Failed to get the OUT_DIR environment variable")) + .to_path_buf() +} + +/// Get the crate's `OUT_DIR` and navigate up to reach the `target/BUILD_FLAVOR` directory. +/// This directory is shared accross all crates in this project. +fn target_dir() -> PathBuf { + let out_dir = out_dir(); + + out_dir + .ancestors() + .nth(3) + .expect("Failed to navigate up three levels from OUT_DIR") + .to_path_buf() +} + +fn shared_folder_dir() -> PathBuf { + target_dir().join("shared_executables") +} + +pub fn binary_path() -> PathBuf { + shared_folder_dir().join(BINARY_NAME) +} diff --git a/crates/starknet_sierra_compile/src/command_line_compiler.rs b/crates/starknet_sierra_compile/src/command_line_compiler.rs new file mode 100644 index 0000000000..2a59932ba3 --- /dev/null +++ b/crates/starknet_sierra_compile/src/command_line_compiler.rs @@ -0,0 +1,61 @@ +use std::io::Write; +use std::path::PathBuf; +use std::process::Command; + +use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; +use cairo_lang_starknet_classes::contract_class::ContractClass; +use tempfile::NamedTempFile; + +use crate::build_utils::binary_path; +use crate::config::SierraToCasmCompilationConfig; +use crate::errors::CompilationUtilError; +use crate::SierraToCasmCompiler; + +#[derive(Clone)] +pub struct CommandLineCompiler { + pub config: SierraToCasmCompilationConfig, + path_to_starknet_sierra_compile_binary: PathBuf, +} + +impl CommandLineCompiler { + pub fn new(config: SierraToCasmCompilationConfig) -> Self { + Self { config, path_to_starknet_sierra_compile_binary: binary_path() } + } +} + +impl SierraToCasmCompiler for CommandLineCompiler { + fn compile( + &self, + contract_class: ContractClass, + ) -> Result { + // Create a temporary file to store the Sierra contract class. + let serialized_contract_class = serde_json::to_string(&contract_class)?; + + let mut temp_file = NamedTempFile::new()?; + temp_file.write_all(serialized_contract_class.as_bytes())?; + let temp_file_path = temp_file.path().to_str().ok_or( + CompilationUtilError::UnexpectedError("Failed to get temporary file path".to_owned()), + )?; + + // Set the parameters for the compile process. + // TODO(Arni): Setup the ulimit for the process. + let mut command = Command::new(self.path_to_starknet_sierra_compile_binary.as_os_str()); + command.args([ + temp_file_path, + "--add-pythonic-hints", + "--max-bytecode-size", + &self.config.max_bytecode_size.to_string(), + ]); + + // Run the compile process. + let compile_output = command.output()?; + + if !compile_output.status.success() { + let stderr_output = String::from_utf8(compile_output.stderr) + .unwrap_or("Failed to get stderr output".into()); + return Err(CompilationUtilError::CompilationError(stderr_output)); + }; + + Ok(serde_json::from_slice::(&compile_output.stdout)?) + } +} diff --git a/crates/starknet_sierra_compile/src/compile_test.rs b/crates/starknet_sierra_compile/src/compile_test.rs index 547b92c497..675f911343 100644 --- a/crates/starknet_sierra_compile/src/compile_test.rs +++ b/crates/starknet_sierra_compile/src/compile_test.rs @@ -3,22 +3,30 @@ use std::path::Path; use assert_matches::assert_matches; use mempool_test_utils::{get_absolute_path, FAULTY_ACCOUNT_CLASS_FILE, TEST_FILES_FOLDER}; -use rstest::{fixture, rstest}; +use rstest::rstest; use crate::cairo_lang_compiler::CairoLangSierraToCasmCompiler; +use crate::command_line_compiler::CommandLineCompiler; use crate::config::SierraToCasmCompilationConfig; use crate::errors::CompilationUtilError; use crate::test_utils::contract_class_from_file; use crate::SierraToCasmCompiler; -#[fixture] -fn compiler() -> impl SierraToCasmCompiler { - CairoLangSierraToCasmCompiler { config: SierraToCasmCompilationConfig::default() } +const SIERRA_TO_CASM_COMPILATION_CONFIG: SierraToCasmCompilationConfig = + SierraToCasmCompilationConfig { max_bytecode_size: 81920 }; + +fn cairo_lang_compiler() -> CairoLangSierraToCasmCompiler { + CairoLangSierraToCasmCompiler { config: SIERRA_TO_CASM_COMPILATION_CONFIG } +} +fn commnad_line_compiler() -> CommandLineCompiler { + CommandLineCompiler::new(SIERRA_TO_CASM_COMPILATION_CONFIG) } // TODO: use the other compiler as well. #[rstest] -fn test_compile_sierra_to_casm(compiler: impl SierraToCasmCompiler) { +#[case::cairo_lang_compiler(cairo_lang_compiler())] +#[case::command_line_compiler(commnad_line_compiler())] +fn test_compile_sierra_to_casm(#[case] compiler: impl SierraToCasmCompiler) { env::set_current_dir(get_absolute_path(TEST_FILES_FOLDER)).expect("Failed to set current dir."); let sierra_path = Path::new(FAULTY_ACCOUNT_CLASS_FILE); let expected_casm_contract_length = 72304; @@ -32,7 +40,9 @@ fn test_compile_sierra_to_casm(compiler: impl SierraToCasmCompiler) { // TODO(Arni, 1/5/2024): Add a test for panic result test. #[rstest] -fn test_negative_flow_compile_sierra_to_casm(compiler: impl SierraToCasmCompiler) { +#[case::cairo_lang_compiler(cairo_lang_compiler())] +#[case::command_line_compiler(commnad_line_compiler())] +fn test_negative_flow_compile_sierra_to_casm(#[case] compiler: impl SierraToCasmCompiler) { env::set_current_dir(get_absolute_path(TEST_FILES_FOLDER)).expect("Failed to set current dir."); let sierra_path = Path::new(FAULTY_ACCOUNT_CLASS_FILE); diff --git a/crates/starknet_sierra_compile/src/errors.rs b/crates/starknet_sierra_compile/src/errors.rs index c1f25719ec..85ca1823c2 100644 --- a/crates/starknet_sierra_compile/src/errors.rs +++ b/crates/starknet_sierra_compile/src/errors.rs @@ -21,3 +21,15 @@ impl From for CompilationUtilError { CompilationUtilError::CompilationError(error.to_string()) } } + +impl From for CompilationUtilError { + fn from(error: serde_json::Error) -> Self { + CompilationUtilError::UnexpectedError(error.to_string()) + } +} + +impl From for CompilationUtilError { + fn from(error: std::io::Error) -> Self { + CompilationUtilError::UnexpectedError(error.to_string()) + } +} diff --git a/crates/starknet_sierra_compile/src/lib.rs b/crates/starknet_sierra_compile/src/lib.rs index e68efcc505..8734f4d9c2 100644 --- a/crates/starknet_sierra_compile/src/lib.rs +++ b/crates/starknet_sierra_compile/src/lib.rs @@ -4,7 +4,9 @@ use cairo_lang_starknet_classes::contract_class::ContractClass; use crate::errors::CompilationUtilError; +pub mod build_utils; pub mod cairo_lang_compiler; +pub mod command_line_compiler; pub mod config; pub mod errors; pub mod utils; diff --git a/crates/task_executor/Cargo.toml b/crates/task_executor/Cargo.toml index f622c6f95c..10d677906e 100644 --- a/crates/task_executor/Cargo.toml +++ b/crates/task_executor/Cargo.toml @@ -6,7 +6,7 @@ repository.workspace = true license.workspace = true [dependencies] -tokio.workspace = true +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } [dev-dependencies] futures.workspace = true diff --git a/crates/tests-integration/build.rs b/crates/tests-integration/build.rs new file mode 100644 index 0000000000..2c3d009e87 --- /dev/null +++ b/crates/tests-integration/build.rs @@ -0,0 +1,3 @@ +// Sets up the environment variable OUT_DIR, which holds the cairo compiler binary. +// The binary is dowloaded to OUT_DIR by the starknet_sierra_compile crate. +fn main() {} diff --git a/crates/tests-integration/src/integration_test_setup.rs b/crates/tests-integration/src/integration_test_setup.rs index 0cb1a95da5..1cdda80fb9 100644 --- a/crates/tests-integration/src/integration_test_setup.rs +++ b/crates/tests-integration/src/integration_test_setup.rs @@ -14,13 +14,13 @@ use starknet_task_executor::tokio_executor::TokioExecutor; use tokio::runtime::Handle; use tokio::task::JoinHandle; -use crate::integration_test_utils::{create_config, GatewayClient}; +use crate::integration_test_utils::{create_config, HttpTestClient}; use crate::mock_batcher::MockBatcher; use crate::state_reader::spawn_test_rpc_state_reader; pub struct IntegrationTestSetup { pub task_executor: TokioExecutor, - pub gateway_client: GatewayClient, + pub http_test_client: HttpTestClient, pub batcher: MockBatcher, pub gateway_handle: JoinHandle<()>, pub mempool_handle: JoinHandle<()>, @@ -52,7 +52,7 @@ impl IntegrationTestSetup { let (clients, servers) = create_clients_servers_from_config(&config); let GatewayNetworkConfig { ip, port } = config.gateway_config.network_config; - let gateway_client = GatewayClient::new(SocketAddr::from((ip, port))); + let http_test_client = HttpTestClient::new(SocketAddr::from((ip, port))); let gateway_future = get_server_future("Gateway", true, servers.gateway); let gateway_handle = task_executor.spawn_with_handle(gateway_future); @@ -69,15 +69,15 @@ impl IntegrationTestSetup { let mempool_future = get_server_future("Mempool", true, servers.mempool); let mempool_handle = task_executor.spawn_with_handle(mempool_future); - Self { task_executor, gateway_client, batcher, gateway_handle, mempool_handle } + Self { task_executor, http_test_client, batcher, gateway_handle, mempool_handle } } pub async fn assert_add_tx_success(&self, tx: &RpcTransaction) -> TransactionHash { - self.gateway_client.assert_add_tx_success(tx).await + self.http_test_client.assert_add_tx_success(tx).await } pub async fn assert_add_tx_error(&self, tx: &RpcTransaction) -> GatewaySpecError { - self.gateway_client.assert_add_tx_error(tx).await + self.http_test_client.assert_add_tx_error(tx).await } pub async fn get_txs(&self, n_txs: usize) -> Vec { diff --git a/crates/tests-integration/src/integration_test_utils.rs b/crates/tests-integration/src/integration_test_utils.rs index 1905b68dda..3840bac1a9 100644 --- a/crates/tests-integration/src/integration_test_utils.rs +++ b/crates/tests-integration/src/integration_test_utils.rs @@ -43,13 +43,13 @@ pub async fn create_config(rpc_server_addr: SocketAddr) -> MempoolNodeConfig { MempoolNodeConfig { gateway_config, rpc_state_reader_config, ..MempoolNodeConfig::default() } } -/// A test utility client for interacting with a gateway server. -pub struct GatewayClient { +/// A test utility client for interacting with an http server. +pub struct HttpTestClient { socket: SocketAddr, client: Client, } -impl GatewayClient { +impl HttpTestClient { pub fn new(socket: SocketAddr) -> Self { let client = Client::new(); Self { socket, client } diff --git a/deployments/papyrus/helm/Chart.yaml b/deployments/papyrus/helm/Chart.yaml index 4f53da0c22..73891673d6 100644 --- a/deployments/papyrus/helm/Chart.yaml +++ b/deployments/papyrus/helm/Chart.yaml @@ -15,4 +15,4 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.0.2 +version: 0.1.0 diff --git a/deployments/papyrus/helm/config/example.json b/deployments/papyrus/helm/config/example.json new file mode 100644 index 0000000000..d9cef9180b --- /dev/null +++ b/deployments/papyrus/helm/config/example.json @@ -0,0 +1,8 @@ +{ + "base_layer.node_url": "", + "network.tcp_port": 10000, + "storage.db_config.path_prefix": "./data", + "network.#is_none": false, + "storage.scope": "FullArchive", + "collect_metrics": true +} diff --git a/deployments/papyrus/helm/reference/template.yaml b/deployments/papyrus/helm/reference/template.yaml new file mode 100644 index 0000000000..8390b2f294 --- /dev/null +++ b/deployments/papyrus/helm/reference/template.yaml @@ -0,0 +1,164 @@ +--- +# Source: papyrus/templates/configmap-env.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: papyrus-env + labels: + helm.sh/chart: papyrus-0.1.0 + app: papyrus + app.kubernetes.io/name: papyrus + app.kubernetes.io/managed-by: Helm +data: + RUST_LOG: info + PRESET: mainnet.json + CONCURRENT_REQUESTS: "50" +--- +# Source: papyrus/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: papyrus-config + labels: + helm.sh/chart: papyrus-0.1.0 + app: papyrus + app.kubernetes.io/name: papyrus + app.kubernetes.io/managed-by: Helm +data: + config.json: |- + {} +--- +# Source: papyrus/templates/pvc.yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: papyrus-data + labels: + helm.sh/chart: papyrus-0.1.0 + app: papyrus + app.kubernetes.io/name: papyrus + app.kubernetes.io/managed-by: Helm +spec: + storageClassName: + accessModes: + - ReadWriteOnce + volumeMode: Filesystem + resources: + requests: + storage: "512Gi" +--- +# Source: papyrus/templates/service-p2p.yaml +apiVersion: v1 +kind: Service +metadata: + name: papyrus-p2p + labels: + helm.sh/chart: papyrus-0.1.0 + app: papyrus + app.kubernetes.io/name: papyrus + app.kubernetes.io/managed-by: Helm +spec: + selector: + app.kubernetes.io/name: papyrus + type: ClusterIP + ports: + - name: p2p + port: 10000 + protocol: TCP + targetPort: p2p +--- +# Source: papyrus/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: papyrus + labels: + helm.sh/chart: papyrus-0.1.0 + app: papyrus + app.kubernetes.io/name: papyrus + app.kubernetes.io/managed-by: Helm +spec: + selector: + app.kubernetes.io/name: papyrus + type: ClusterIP + ports: + - name: rpc + port: 8080 + protocol: TCP + targetPort: rpc + - name: monitoring + port: 8081 + protocol: TCP + targetPort: monitoring +--- +# Source: papyrus/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: papyrus + namespace: idan-papyrus-p2p-dnsaddr-test + labels: + helm.sh/chart: papyrus-0.1.0 + app: papyrus + app.kubernetes.io/name: papyrus + app.kubernetes.io/managed-by: Helm +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: papyrus + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + maxSurge: 1 + template: + metadata: + annotations: + prometheus.io/scrape: "true" + prometheus.io/path: "/monitoring/metrics" + prometheus.io/port: "8081" + labels: + app: papyrus + app.kubernetes.io/name: papyrus + spec: + securityContext: + fsGroup: 1000 + volumes: + - name: data + persistentVolumeClaim: + claimName: papyrus-data + - name: config-volume + configMap: + name: papyrus-config + containers: + - name: papyrus + image: "ghcr.io/starkware-libs/sequencer/papyrus:0.4.0" + imagePullPolicy: Always + resources: + limits: + cpu: "1" + memory: 1Gi + requests: + cpu: "500m" + memory: 1Gi + args: + - --config_file + - /app/config/papyrus/presets/mainnet.json,/app/config/papyrus/custom/config.json + + ports: + - containerPort: 8080 + name: rpc + - containerPort: 8081 + name: monitoring + - containerPort: 10000 + name: p2p + volumeMounts: + - name: data + mountPath: /app/data + - name: config-volume + mountPath: /app/config/papyrus/custom/config.json + subPath: config.json + envFrom: + - configMapRef: + name: papyrus-config diff --git a/deployments/papyrus/helm/templates/_helpers.tpl b/deployments/papyrus/helm/templates/_helpers.tpl index eef0f98ec6..9b6c563648 100644 --- a/deployments/papyrus/helm/templates/_helpers.tpl +++ b/deployments/papyrus/helm/templates/_helpers.tpl @@ -60,17 +60,3 @@ Create the name of the service account to use {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} - -{{/* -Build the p2p peer multiaddress string -*/}} -{{- define "p2p.bootstrapPeerMultiaddr" -}} -{{- if and .Values.p2p.enabled (not .Values.p2p.bootstrap) -}} - {{- $ip := .Values.p2p.nodeConfig.bootstrapServer.multiaddrIp -}} - {{- $port := .Values.p2p.nodeConfig.bootstrapServer.multiaddrPort -}} - {{- $uid := .Values.p2p.nodeConfig.bootstrapServer.multiaddrUid -}} - {{- printf "/ip4/%s/tcp/%s/p2p/%s" $ip $port $uid -}} -{{- else -}} - {{- "" -}} -{{- end -}} -{{- end -}} \ No newline at end of file diff --git a/deployments/papyrus/helm/templates/configmap-env.yaml b/deployments/papyrus/helm/templates/configmap-env.yaml new file mode 100644 index 0000000000..5e5da60528 --- /dev/null +++ b/deployments/papyrus/helm/templates/configmap-env.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "papyrus.name" . }}-env + labels: + {{- include "papyrus.labels" . | nindent 4 }} +data: + RUST_LOG: {{ .Values.rustLogLevel }} + PRESET: {{ .Values.starknet.preset }} + CONCURRENT_REQUESTS: {{ .Values.node.concurrentFgRequests | quote }} + {{- if .Values.starknet.additionalHeaders }} + ADDITIONAL_HEADER: {{ .Values.starknet.additionalHeaders }} + {{- end }} + {{- if .Values.backup.enabled }} + SLEEP_INTERVAL: {{ .Values.backup.sleepInterval }} + S3_BUCKET_NAME: {{ .Values.backup.aws.s3BucketName }} + PAPYRUS_VERSION: {{ .Values.image.tag | quote }} + COMPRESS_BACKUP: {{ .Values.backup.compress | quote }} + {{- end }} diff --git a/deployments/papyrus/helm/templates/run-configmap.yaml b/deployments/papyrus/helm/templates/configmap-run.yaml similarity index 99% rename from deployments/papyrus/helm/templates/run-configmap.yaml rename to deployments/papyrus/helm/templates/configmap-run.yaml index 8218ceefea..ffbe00b7f6 100644 --- a/deployments/papyrus/helm/templates/run-configmap.yaml +++ b/deployments/papyrus/helm/templates/configmap-run.yaml @@ -9,3 +9,4 @@ data: backup.sh: | {{- tpl (.Files.Get "files/backup.sh") . | nindent 4 }} {{- end }} + diff --git a/deployments/papyrus/helm/templates/configmap.yaml b/deployments/papyrus/helm/templates/configmap.yaml index 3cd1c01d0b..bff1f5b8c3 100644 --- a/deployments/papyrus/helm/templates/configmap.yaml +++ b/deployments/papyrus/helm/templates/configmap.yaml @@ -1,3 +1,4 @@ + apiVersion: v1 kind: ConfigMap metadata: @@ -5,15 +6,14 @@ metadata: labels: {{- include "papyrus.labels" . | nindent 4 }} data: - RUST_LOG: {{ .Values.rustLogLevel }} - PRESET: {{ .Values.starknet.preset }} - CONCURRENT_REQUESTS: {{ .Values.node.concurrentFgRequests | quote }} - {{- if .Values.starknet.additionalHeaders }} - ADDITIONAL_HEADER: {{ .Values.starknet.additionalHeaders }} - {{- end }} - {{- if .Values.backup.enabled }} - SLEEP_INTERVAL: {{ .Values.backup.sleepInterval }} - S3_BUCKET_NAME: {{ .Values.backup.aws.s3BucketName }} - PAPYRUS_VERSION: {{ .Values.image.tag | quote }} - COMPRESS_BACKUP: {{ .Values.backup.compress | quote }} - {{- end }} + config.json: |- + {{- if .Values.deployment.configFile }} + {{- $filePath := printf "config/%s" .Values.deployment.configFile -}} + {{- if not (.Files.Get $filePath) -}} + {{- fail (printf "Error: The file %s does not exist in the chart." $filePath) -}} + {{- else }} + {{ .Files.Get $filePath | nindent 4 }} + {{- end }} + {{- else }} + {} + {{- end }} diff --git a/deployments/papyrus/helm/templates/deployment.yaml b/deployments/papyrus/helm/templates/deployment.yaml index eee67750ab..24ff73688f 100644 --- a/deployments/papyrus/helm/templates/deployment.yaml +++ b/deployments/papyrus/helm/templates/deployment.yaml @@ -37,6 +37,9 @@ spec: - name: data persistentVolumeClaim: claimName: {{ template "papyrus.name" . }}-data + - name: config-volume + configMap: + name: {{ template "papyrus.name" . }}-config {{- if .Values.backup.enabled }} - name: run configMap: @@ -69,23 +72,7 @@ spec: {{- end }} args: - --config_file - - /app/config/papyrus/presets/{{ .Values.starknet.preset }} - - --base_layer.node_url - - {{ .Values.base_layer_node_url }} - {{- if .Values.p2p.enabled }} - - --network.tcp_port - - {{ .Values.p2p.config.networkTcpPort | quote }} - - --storage.db_config.path_prefix - - {{ .Values.p2p.config.storageDbConfigPathPrefix | quote }} - - --network.#is_none - - {{ .Values.p2p.config.networkIsNone | quote }} - {{- if not .Values.p2p.bootstrap }} - - --network.bootstrap_peer_multiaddr.#is_none - - {{ .Values.p2p.nodeConfig.bootstrapServer.multiaddrIsNone | quote }} - - --network.bootstrap_peer_multiaddr - - {{ include "p2p.bootstrapPeerMultiaddr" . | quote }} - {{- end}} - {{- end }} + - /app/config/papyrus/presets/{{ .Values.starknet.preset }},/app/config/papyrus/custom/config.json {{ range $key, $value := .Values.deployment.extraArgs }} {{- if $value }} - --{{ $key }} @@ -103,13 +90,16 @@ spec: - containerPort: {{ .Values.service.ports.monitoring.port }} name: monitoring {{- end }} - {{- if .Values.p2p.enabled }} - - containerPort: {{ .Values.p2p.config.networkTcpPort }} + {{- if .Values.p2pService.enabled }} + - containerPort: {{ .Values.p2pService.port }} name: p2p {{- end }} volumeMounts: - name: data mountPath: /app/data + - name: config-volume + mountPath: /app/config/papyrus/custom/config.json + subPath: config.json envFrom: - configMapRef: name: {{ template "papyrus.name" . }}-config @@ -121,11 +111,14 @@ spec: volumeMounts: - name: data mountPath: /app/data + - name: config-volume + mountPath: /app/config/papyrus/custom/config.json + subPath: config.json - name: run mountPath: /app/run envFrom: - configMapRef: - name: {{ template "papyrus.name" . }}-config + name: {{ template "papyrus.name" . }}-env - secretRef: name: {{ template "papyrus.name" . }}-aws-creds {{- end }} diff --git a/deployments/papyrus/helm/templates/p2p-service.yaml b/deployments/papyrus/helm/templates/p2p-service.yaml deleted file mode 100644 index f8435115fa..0000000000 --- a/deployments/papyrus/helm/templates/p2p-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and ( not .Values.backup.enabled ) .Values.p2p.service.enabled }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "papyrus.name" . }}-p2p - labels: - {{- include "papyrus.labels" . | nindent 4 }} -spec: - selector: - {{- include "papyrus.selectorLabels" . | nindent 6 }} - type: {{ .Values.p2p.service.type }} - ports: - - name: p2p - port: {{ .Values.p2p.service.port }} - protocol: {{ .Values.p2p.service.protocol }} - targetPort: p2p -{{- end }} \ No newline at end of file diff --git a/deployments/papyrus/helm/templates/service-p2p.yaml b/deployments/papyrus/helm/templates/service-p2p.yaml new file mode 100644 index 0000000000..15c7e69271 --- /dev/null +++ b/deployments/papyrus/helm/templates/service-p2p.yaml @@ -0,0 +1,28 @@ +{{- if and ( not .Values.backup.enabled ) .Values.p2pService.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "papyrus.name" . }}-p2p + labels: + {{- include "papyrus.labels" . | nindent 4 }} + annotations: + {{- if .Values.p2pService.annotations }} + {{ toYaml .Values.p2pService.annotations | nindent 4 }} + {{- end}} +spec: + selector: + {{- include "papyrus.selectorLabels" . | nindent 6 }} + type: {{ .Values.p2pService.type }} + {{- if and (eq .Values.p2pService.type "ClusterIP") .Values.p2pService.clusterIP }} + clusterIP: {{ .Values.p2pService.clusterIP }} + {{- end }} + {{- if and (eq .Values.p2pService.type "LoadBalancer") .Values.p2pService.loadBalancerIP }} + loadBalancerIP: {{ .Values.p2pService.loadBalancerIP }} + {{- end }} + ports: + - name: p2p + port: {{ .Values.p2pService.port }} + protocol: {{ .Values.p2pService.protocol }} + targetPort: p2p +{{- end }} diff --git a/deployments/papyrus/helm/templates/statefulset.yaml b/deployments/papyrus/helm/templates/statefulset.yaml index 0b41b35714..e5ed6e5bcb 100644 --- a/deployments/papyrus/helm/templates/statefulset.yaml +++ b/deployments/papyrus/helm/templates/statefulset.yaml @@ -33,6 +33,9 @@ spec: securityContext: fsGroup: 1000 volumes: + - name: config-volume + configMap: + name: {{ template "papyrus.name" . }}-config {{- if .Values.backup.enabled }} - name: run configMap: @@ -65,23 +68,7 @@ spec: {{- end }} args: - --config_file - - /app/config/papyrus/presets/{{ .Values.starknet.preset }} - - --base_layer.node_url - - {{ .Values.base_layer_node_url }} - {{- if .Values.p2p.enabled }} - - --network.tcp_port - - {{ .Values.p2p.config.networkTcpPort | quote }} - - --storage.db_config.path_prefix - - {{ .Values.p2p.config.storageDbConfigPathPrefix | quote }} - - --network.#is_none - - {{ .Values.p2p.config.networkIsNone | quote }} - {{- if not .Values.p2p.bootstrap }} - - --network.bootstrap_peer_multiaddr.#is_none - - {{ .Values.p2p.nodeConfig.bootstrapServer.multiaddrIsNone | quote }} - - --network.bootstrap_peer_multiaddr - - {{ include "p2p.bootstrapPeerMultiaddr" . | quote }} - {{- end}} - {{- end }} + - /app/config/papyrus/presets/{{ .Values.starknet.preset }},/app/config/papyrus/custom/config.json {{ range $key, $value := .Values.deployment.extraArgs }} {{- if $value }} - --{{ $key }} @@ -99,16 +86,19 @@ spec: - containerPort: {{ .Values.service.ports.monitoring.port }} name: monitoring {{- end }} - {{- if .Values.p2p.enabled }} - - containerPort: {{ .Values.p2p.config.networkTcpPort }} + {{- if .Values.p2pService.enabled }} + - containerPort: {{ .Values.p2pService.port }} name: p2p {{- end }} volumeMounts: - name: {{ template "papyrus.name" . }}-data mountPath: /app/data + - name: config-volume + mountPath: /app/config/papyrus/custom/config.json + subPath: config.json envFrom: - configMapRef: - name: {{ template "papyrus.name" . }}-config + name: {{ template "papyrus.name" . }}-env {{- else }} command: - sh @@ -117,11 +107,14 @@ spec: volumeMounts: - name: {{ template "papyrus.name" . }}-data mountPath: /app/data + - name: config-volume + mountPath: /app/config/papyrus/custom/config.json + subPath: config.json - name: run mountPath: /app/run envFrom: - configMapRef: - name: {{ template "papyrus.name" . }}-config + name: {{ template "papyrus.name" . }}-env - secretRef: name: {{ template "papyrus.name" . }}-aws-creds {{- end }} diff --git a/deployments/papyrus/helm/values.yaml b/deployments/papyrus/helm/values.yaml index 3d682a6bbc..4fba11c68e 100644 --- a/deployments/papyrus/helm/values.yaml +++ b/deployments/papyrus/helm/values.yaml @@ -14,37 +14,6 @@ starknet: # possible values: "mainnet.json, sepolia_testnet" and "sepolia_integration". preset: mainnet.json -p2p: - enabled: false - # Set to true if node act as bootstrap server - bootstrap: false - # General config - config: - # Optional - The node self port to listen - networkTcpPort: 10000 - # Optional - The node data path - storageDbConfigPathPrefix: data - # Optional - network.#is_none flag - networkIsNone: false - # Config to include only if "bootstrap: false" - nodeConfig: - bootstrapServer: - # Mandatory - The network.#is_none flag on the bootsrap server - multiaddrIsNone: - # Mandatory - The bootstrap server ip address. If service is used, use the service address. If not, use the pod address. - multiaddrIp: - # Mandatory - The bootstrap server to connect to, port - multiaddrPort: - # Mandatory - The bootstrap server to connect to, uid - multiaddrUid: - service: - enabled: false - type: ClusterIP - port: 10000 - protocol: TCP - loadBalancerIP: - annotations: {} - deployment: # Supported values: deployment, statefulset type: deployment @@ -54,6 +23,15 @@ deployment: repository: ghcr.io/starkware-libs/sequencer/papyrus tag: 0.4.0 + # The name of the papyrus config file. For example: my-config.json + # The config file must be placed under "config" folder in the chart root folder. + # ./ + # templates/ + # ---> config/ + # Chart.yaml + # values.yaml + configFile: + # The container's pullPolicy pullPolicy: Always @@ -130,6 +108,21 @@ service: port: 8081 protocol: TCP +p2pService: + enabled: true + # supported options are ClusterIP, LoadBalancer + type: ClusterIP + port: 10000 + protocol: TCP + # If service type is ClusterIP, + # Set static ip for the kubernetes service. Note that the ip address is not reserved and there might be a chance for ip collision. + # See https://kubernetes.io/docs/concepts/services-networking/cluster-ip-allocation/ to understand how to avoid such case. + clusterIP: + # If service type is LoadBalancer, + # Set static ip for the loadbalancer. Note that a static IP needs to be reserved first in a cloud environment in order to use it. + loadBalancerIP: + annotations: {} + # Persistent volume claim variables for a papyrus pod. pvc: # Recommended size is at least 512Gi. diff --git a/docs/papyrus/CONTRIBUTING.md b/docs/papyrus/CONTRIBUTING.md index 9678574379..57cce3dba0 100644 --- a/docs/papyrus/CONTRIBUTING.md +++ b/docs/papyrus/CONTRIBUTING.md @@ -47,7 +47,6 @@ Then, you will need to install - [Ganache 7.4.3](https://www.npmjs.com/package/ganache) - You'll need to install 7.4.3 and not a version above it. We'll relax this in the future. - You'll need Ganache only for the tests of the [papyrus_base_layer](../../crates/papyrus_base_layer/) crate. -- Protoc - follow the installation instructions in our [Prerequisites](../papyrus/README.adoc#Prerequisites). ### CI Your code will need to pass [CI](../.github/workflows/ci.yml) before it can be merged. This means your code will need to: diff --git a/docs/papyrus/README.adoc b/docs/papyrus/README.adoc index 07474f0986..6c9bc304c2 100644 --- a/docs/papyrus/README.adoc +++ b/docs/papyrus/README.adoc @@ -46,32 +46,6 @@ Use it at your own risk. * https://www.rust-lang.org/tools/install[Rust] must be installed. Minimum supported version is `1.76`. * You must have access to an Ethereum node. For example, you can use a node provider such as Infura. -* link: https://grpc.io/docs/protoc-installation[Protoc] - - You'll need Protoc only for compiling the link:../crates/papyrus_network/[papyrus_network] crate. - - Make sure you have version 15 or higher installed. If not: - 1. Remove your current Protoc installation: -+ -[source,bash] ----- -sudo apt remove protoc/protobuf-compiler ----- - - 2. Install version 15 or higher (replace DIR with your preferred installation directory): -+ -[source,bash] ----- -DIR="$HOME/.local" -curl -L "https://github.com/protocolbuffers/protobuf/releases/download/v25.1/protoc-25.1-linux-x86_64.zip" -o protoc.zip -unzip ./protoc.zip -d $DIR -rm ./protoc.zip ----- - - 3. Add DIR to your PATH if it's not already there: -+ -[source,bash] ----- -export PATH=$PATH:$DIR/bin ----- [discrete] ==== Procedure @@ -260,6 +234,11 @@ cargo run --release --package papyrus_node --bin papyrus_node -- \ --network.bootstrap_peer_multiaddr /ip4//tcp//p2p/ ---- +You can also use DNS instead of ip4 by typing +---- + --network.bootstrap_peer_multiaddr /dns//tcp//p2p/ +---- + ==== P2P Sync (with bootstrap connection) [source, bash] ---- diff --git a/scripts/build_native_blockifier.sh b/scripts/build_native_blockifier.sh index db56e326c7..0df01b83a8 100755 --- a/scripts/build_native_blockifier.sh +++ b/scripts/build_native_blockifier.sh @@ -13,6 +13,9 @@ function build() { pushd crates/native_blockifier pypy3.9 -m venv venv source venv/bin/activate + export MLIR_SYS_180_PREFIX=/usr/lib/llvm-18/ + export LLVM_SYS_181_PREFIX=/usr/lib/llvm-18/ + export TABLEGEN_180_PREFIX=/usr/lib/llvm-18/ cargo build --release -p native_blockifier --features "testing" || clean clean popd diff --git a/scripts/clippy.sh b/scripts/clippy.sh index 7ca2f22768..cb02949fbd 100755 --- a/scripts/clippy.sh +++ b/scripts/clippy.sh @@ -1,7 +1,7 @@ #!/bin/bash # TODO: Revert clippy::unwrap_used to -D after fixing all the unwraps. -cargo clippy --workspace --all-targets --all-features -- \ +cargo clippy -p blockifier --all-targets --all-features -- \ -D future-incompatible \ -D nonstandard-style \ -D rust-2018-idioms \ diff --git a/scripts/install_build_tools.sh b/scripts/install_build_tools.sh index fd4e617598..216412d7dd 100644 --- a/scripts/install_build_tools.sh +++ b/scripts/install_build_tools.sh @@ -31,6 +31,17 @@ function install_rust () { curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path } +function install_llvm() { + echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-18 main" > /etc/apt/sources.list.d/llvm-18.list + echo "deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-18 main" >> /etc/apt/sources.list.d/llvm-18.list + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - + + apt update -y + apt install -y libmlir-18-dev libpolly-18-dev llvm-18-dev mlir-18-tools +} + +install_llvm + install_pypy & install_rust & wait diff --git a/scripts/merge_branches.py b/scripts/merge_branches.py index 4ebd1fc2b0..29c84f3224 100755 --- a/scripts/merge_branches.py +++ b/scripts/merge_branches.py @@ -10,6 +10,7 @@ import argparse import json import os +import subprocess import time from typing import Dict, List, Optional from utils import run_command diff --git a/scripts/run_codecov.py b/scripts/run_codecov.py new file mode 100644 index 0000000000..2939fd53bc --- /dev/null +++ b/scripts/run_codecov.py @@ -0,0 +1,50 @@ +#!/bin/env python3 + +import argparse +from calendar import c +import subprocess +from typing import List, Set, Optional +from tests_utils import ( + get_local_changes, + get_modified_packages, +) + + +def run_codecov(changes_only: bool, commit_id: Optional[str]): + + local_changes = get_local_changes(".", commit_id=commit_id) + modified_packages = set(get_modified_packages(local_changes)) + + if changes_only and len(modified_packages) == 0: + print("No changes detected.") + return + + print(f"Running code coverage for {modified_packages}.") + + args = [] + + for package in modified_packages: + args.extend(["--package", package]) + + cmd = ["cargo", "llvm-cov", "--codecov", "-r", "--output-path", "codecov.json"] + args + + print("Running code coverage...") + print(cmd, flush=True) + subprocess.run(cmd, check=True) + print("Code coverage complete.") + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Code coverage script.") + parser.add_argument("--changes_only", action="store_true") + parser.add_argument("--commit_id", type=str, help="GIT commit ID to compare against.") + return parser.parse_args() + + +def main(): + args = parse_args() + run_codecov(changes_only=args.changes_only, commit_id=args.commit_id) + + +if __name__ == "__main__": + main() diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 11f1d8efbd..78c0528e11 100755 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -1,74 +1,19 @@ #!/bin/env python3 import argparse -from calendar import c -import re import subprocess -import os -from typing import Dict, List, Set, Optional -from git import Repo - -PATTERN = r"(\w+)\s*v([\d.]*.*)\((.*?)\)" - -# Pattern to match the dependency tree output (`cargo tree -i` output). -# First match group is the dependent crate name; second match group is the local path to the -# dependant crate. -# '([a-zA-Z0-9_]+)' is the crate name. -# ' [^(]* ' is anything between the crate name and the path (path is in parens). -# '\(([^)]+)\)' should match the path to the crate. No closing paren in the path. -DEPENDENCY_PATTERN = r"([a-zA-Z0-9_]+) [^(]* \(([^)]+)\)" - +from typing import List, Set, Optional +from tests_utils import ( + get_workspace_tree, + get_local_changes, + get_modified_packages, + get_package_dependencies, +) # Set of files which - if changed - should trigger tests for all packages. ALL_TEST_TRIGGERS: Set[str] = {"Cargo.toml", "Cargo.lock"} -def get_workspace_tree() -> Dict[str, str]: - tree = dict() - res = subprocess.check_output("cargo tree --depth 0".split()).decode("utf-8").splitlines() - for l in res: - m = re.match(PATTERN, l) - if m is not None: - tree.update({m.group(1): m.group(3)}) - return tree - - -def get_local_changes(repo_path, commit_id: Optional[str]) -> List[str]: - os.environ["GIT_PYTHON_REFRESH"] = "quiet" # noqa - repo = Repo(repo_path) - try: - repo.head.object # Check if local_repo is a git repo. - except ValueError: - print(f"unable to validate {repo_path} as a git repo.") - raise - - return [c.a_path for c in repo.head.commit.diff(commit_id)] - - -def get_modified_packages(files: List[str]) -> Set[str]: - tree = get_workspace_tree() - packages = set() - for file in files: - for p_name, p_path in tree.items(): - if os.path.abspath(file).startswith(p_path): - packages.add(p_name) - return packages - - -def get_package_dependencies(package_name: str) -> Set[str]: - res = ( - subprocess.check_output(f"cargo tree -i {package_name} --prefix none".split()) - .decode("utf-8") - .splitlines() - ) - deps = set() - for l in res: - m = re.match(DEPENDENCY_PATTERN, l) - if m is not None: - deps.add(m.group(1)) - return deps - - def packages_to_test_due_to_global_changes(files: List[str]) -> Set[str]: if len(set(files).intersection(ALL_TEST_TRIGGERS)) > 0: return set(get_workspace_tree().keys()) diff --git a/scripts/rust_fmt.sh b/scripts/rust_fmt.sh index 58e1d7bd56..0942c84535 100755 --- a/scripts/rust_fmt.sh +++ b/scripts/rust_fmt.sh @@ -2,6 +2,12 @@ # Install toolchain if missing (local run). TOOLCHAIN="nightly-2024-04-29" -rustup toolchain list | grep -q ${TOOLCHAIN} || rustup toolchain install ${TOOLCHAIN} + +function install_rustfmt() { + rustup toolchain install ${TOOLCHAIN} + rustup component add --toolchain ${TOOLCHAIN} rustfmt +} + +rustup toolchain list | grep -q ${TOOLCHAIN} || install_rustfmt cargo +${TOOLCHAIN} fmt --all -- "$@" diff --git a/scripts/sequencer-ci.Dockerfile b/scripts/sequencer-ci.Dockerfile index fc67b904be..4d15d11135 100644 --- a/scripts/sequencer-ci.Dockerfile +++ b/scripts/sequencer-ci.Dockerfile @@ -1,14 +1,24 @@ FROM ubuntu:20.04 +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=America/New_York + RUN apt update && apt -y install \ build-essential \ clang \ curl \ - python3-dev + python3-dev \ + libzstd-dev \ + wget \ + gnupg ENV RUSTUP_HOME=/opt/rust ENV CARGO_HOME=/opt/rust ENV PATH=$PATH:/opt/rust/bin +ENV MLIR_SYS_180_PREFIX=/usr/lib/llvm-18/ +ENV LLVM_SYS_181_PREFIX=/usr/lib/llvm-18/ +ENV TABLEGEN_180_PREFIX=/usr/lib/llvm-18/ + COPY install_build_tools.sh . RUN bash install_build_tools.sh diff --git a/scripts/setup_native_deps.sh b/scripts/setup_native_deps.sh new file mode 100755 index 0000000000..550796cb8c --- /dev/null +++ b/scripts/setup_native_deps.sh @@ -0,0 +1,117 @@ +#!/bin/bash + +install_essential_deps_linux() { + apt-get update -y + apt-get install -y \ + curl \ + jq \ + ripgrep \ + wget \ + ca-certificates \ + gnupg \ + git +} + +setup_llvm_deps() { + case "$(uname)" in + Darwin) + brew update + brew install llvm@18 + + LIBRARY_PATH=/opt/homebrew/lib + MLIR_SYS_180_PREFIX="$(brew --prefix llvm@18)" + LLVM_SYS_181_PREFIX="$MLIR_SYS_180_PREFIX" + TABLEGEN_180_PREFIX="$MLIR_SYS_180_PREFIX" + + export LIBRARY_PATH + export MLIR_SYS_180_PREFIX + export LLVM_SYS_181_PREFIX + export TABLEGEN_180_PREFIX + ;; + Linux) + export DEBIAN_FRONTEND=noninteractive + export TZ=America/New_York + + CODENAME=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) + [ -z "$CODENAME" ] && { echo "Error: Unable to determine OS codename"; exit 1; } + + echo "deb http://apt.llvm.org/$CODENAME/ llvm-toolchain-$CODENAME-18 main" > /etc/apt/sources.list.d/llvm-18.list + echo "deb-src http://apt.llvm.org/$CODENAME/ llvm-toolchain-$CODENAME-18 main" >> /etc/apt/sources.list.d/llvm-18.list + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - + + apt-get update && apt-get upgrade -y + apt-get install -y zstd + apt-get install -y llvm-18 llvm-18-dev llvm-18-runtime clang-18 clang-tools-18 lld-18 libpolly-18-dev libmlir-18-dev mlir-18-tools + apt-get install -y libgmp3-dev + + MLIR_SYS_180_PREFIX=/usr/lib/llvm-18/ + LLVM_SYS_181_PREFIX=/usr/lib/llvm-18/ + TABLEGEN_180_PREFIX=/usr/lib/llvm-18/ + + export MLIR_SYS_180_PREFIX + export LLVM_SYS_181_PREFIX + export TABLEGEN_180_PREFIX + ;; + *) + echo "Error: Unsupported operating system" + exit 1 + ;; + esac + + # GitHub Actions specific + [ -n "$GITHUB_ACTIONS" ] && { + echo "MLIR_SYS_180_PREFIX=$MLIR_SYS_180_PREFIX" >> $GITHUB_ENV + echo "LLVM_SYS_181_PREFIX=$LLVM_SYS_181_PREFIX" >> $GITHUB_ENV + echo "TABLEGEN_180_PREFIX=$TABLEGEN_180_PREFIX" >> $GITHUB_ENV + } +} + +install_rust() { + if command -v cargo >/dev/null 2>&1; then + echo "Rust is already installed with cargo available in PATH." + return 0 + fi + + echo "cargo not found. Installing Rust..." + if ! curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path; then + echo >&2 "Failed to install Rust. Aborting." + return 1 + fi + + # shellcheck disable=SC1090 + source "$HOME/.cargo/env" || { + echo >&2 "Failed to source Rust environment. Aborting." + return 1 + } + + echo "Rust installed successfully." +} + +install_cairo_native_runtime() { + install_rust || { echo "Error: Failed to install Rust"; exit 1; } + + git clone https://github.com/lambdaclass/cairo_native.git + pushd ./cairo_native || exit 1 + cargo build -p cairo-native-runtime --release --all-features --quiet + popd || exit 1 + + mv ./cairo_native/target/release/libcairo_native_runtime.a ./libcairo_native_runtime.so + rm -rf ./cairo_native + + export CAIRO_NATIVE_RUNTIME_LIBRARY="$(pwd)/libcairo_native_runtime.so" + + echo "CAIRO_NATIVE_RUNTIME_LIBRARY=$CAIRO_NATIVE_RUNTIME_LIBRARY" + + [ -n "$GITHUB_ACTIONS" ] && echo "CAIRO_NATIVE_RUNTIME_LIBRARY=$CAIRO_NATIVE_RUNTIME_LIBRARY" >> $GITHUB_ENV +} + +main() { + [ "$(uname)" = "Linux" ] && install_essential_deps_linux + + setup_llvm_deps + install_cairo_native_runtime + + echo "LLVM and Cairo native runtime dependencies installed successfully." +} + +main "$@" \ No newline at end of file diff --git a/scripts/tests_utils.py b/scripts/tests_utils.py new file mode 100644 index 0000000000..eedbdc3523 --- /dev/null +++ b/scripts/tests_utils.py @@ -0,0 +1,64 @@ +#!/bin/env python3 + +from calendar import c +import re +import subprocess +import os +from typing import Dict, List, Set, Optional +from git import Repo + +PATTERN = r"(\w+)\s*v([\d.]*.*)\((.*?)\)" + +# Pattern to match the dependency tree output (`cargo tree -i` output). +# First match group is the dependent crate name; second match group is the local path to the +# dependant crate. +# '([a-zA-Z0-9_]+)' is the crate name. +# ' [^(]* ' is anything between the crate name and the path (path is in parens). +# '\(([^)]+)\)' should match the path to the crate. No closing paren in the path. +DEPENDENCY_PATTERN = r"([a-zA-Z0-9_]+) [^(]* \(([^)]+)\)" + + +def get_workspace_tree() -> Dict[str, str]: + tree = dict() + res = subprocess.check_output("cargo tree --depth 0".split()).decode("utf-8").splitlines() + for l in res: + m = re.match(PATTERN, l) + if m is not None: + tree.update({m.group(1): m.group(3)}) + return tree + + +def get_local_changes(repo_path, commit_id: Optional[str]) -> List[str]: + os.environ["GIT_PYTHON_REFRESH"] = "quiet" # noqa + repo = Repo(repo_path) + try: + repo.head.object # Check if local_repo is a git repo. + except ValueError: + print(f"unable to validate {repo_path} as a git repo.") + raise + + return [c.a_path for c in repo.head.commit.diff(commit_id)] + + +def get_modified_packages(files: List[str]) -> Set[str]: + tree = get_workspace_tree() + packages = set() + for file in files: + for p_name, p_path in tree.items(): + if os.path.abspath(file).startswith(p_path): + packages.add(p_name) + return packages + + +def get_package_dependencies(package_name: str) -> Set[str]: + res = ( + subprocess.check_output(f"cargo tree -i {package_name} --prefix none".split()) + .decode("utf-8") + .splitlines() + ) + deps = set() + for l in res: + m = re.match(DEPENDENCY_PATTERN, l) + if m is not None: + deps.add(m.group(1)) + return deps diff --git a/workspace_tests/toml_utils.rs b/workspace_tests/toml_utils.rs index 396be022c7..bdac2c902e 100644 --- a/workspace_tests/toml_utils.rs +++ b/workspace_tests/toml_utils.rs @@ -1,4 +1,6 @@ use std::collections::HashMap; +use std::fs; +use std::path::Path; use std::sync::LazyLock; use serde::{Deserialize, Serialize}; @@ -7,7 +9,7 @@ use serde::{Deserialize, Serialize}; #[serde(untagged)] pub(crate) enum DependencyValue { String(String), - Object { version: String, path: Option }, + Object { version: Option, path: Option, features: Option> }, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -27,6 +29,13 @@ pub(crate) struct CargoToml { workspace: WorkspaceFields, } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub(crate) struct CrateCargoToml { + dependencies: Option>, + #[serde(rename = "dev-dependencies")] + dev_dependencies: Option>, +} + #[derive(Debug)] pub(crate) struct LocalCrate { pub(crate) path: String, @@ -41,9 +50,22 @@ pub(crate) static ROOT_TOML: LazyLock = LazyLock::new(|| { }); impl CargoToml { + pub(crate) fn members(&self) -> &Vec { + &self.workspace.members + } + + pub(crate) fn workspace_version(&self) -> &str { + &self.workspace.package.version + } + + pub(crate) fn dependencies(&self) -> impl Iterator + '_ { + self.workspace.dependencies.iter() + } + pub(crate) fn path_dependencies(&self) -> impl Iterator + '_ { - self.workspace.dependencies.iter().filter_map(|(_name, value)| { - if let DependencyValue::Object { path: Some(path), version } = value { + self.dependencies().filter_map(|(_name, value)| { + if let DependencyValue::Object { path: Some(path), version: Some(version), .. } = value + { Some(LocalCrate { path: path.to_string(), version: version.to_string() }) } else { None @@ -51,11 +73,34 @@ impl CargoToml { }) } - pub(crate) fn members(&self) -> &Vec { - &self.workspace.members + pub(crate) fn member_cargo_tomls(&self) -> Vec { + let manifest_dir = env!("CARGO_MANIFEST_DIR"); + let crates_dir = format!("{}/../", manifest_dir); + self.members() + .iter() + .map(|member| { + let cargo_toml_path = Path::new(&crates_dir).join(member).join("Cargo.toml"); + + let cargo_toml_content = fs::read_to_string(&cargo_toml_path) + .expect(&format!("Failed to read {:?}", cargo_toml_path)); + + let cargo_toml: CrateCargoToml = toml::from_str(&cargo_toml_content).unwrap(); + cargo_toml + }) + .collect() } +} - pub(crate) fn workspace_version(&self) -> &str { - &self.workspace.package.version +impl CrateCargoToml { + pub(crate) fn path_dependencies(&self) -> impl Iterator + '_ { + self.dependencies.iter().chain(self.dev_dependencies.iter()).flatten().filter_map( + |(_name, value)| { + if let DependencyValue::Object { path: Some(path), .. } = value { + Some(path.to_string()) + } else { + None + } + }, + ) } } diff --git a/workspace_tests/version_integrity_test.rs b/workspace_tests/version_integrity_test.rs index d3133f2589..236ff0d685 100644 --- a/workspace_tests/version_integrity_test.rs +++ b/workspace_tests/version_integrity_test.rs @@ -1,4 +1,4 @@ -use crate::toml_utils::{LocalCrate, ROOT_TOML}; +use crate::toml_utils::{DependencyValue, LocalCrate, ROOT_TOML}; #[test] fn test_path_dependencies_are_members() { @@ -26,3 +26,33 @@ fn test_version_alignment() { '{workspace_version}': {crates_with_incorrect_version:?}." ); } + +#[test] +fn validate_no_path_dependencies() { + let mut all_path_deps_in_crate_tomls: Vec = Vec::new(); + for crate_cargo_toml in ROOT_TOML.member_cargo_tomls().iter() { + let crate_paths: Vec = crate_cargo_toml.path_dependencies().collect(); + all_path_deps_in_crate_tomls.extend(crate_paths); + } + assert!( + all_path_deps_in_crate_tomls.is_empty(), + "The following crates have path dependency {all_path_deps_in_crate_tomls:?}." + ); +} + +#[test] +fn test_no_features_in_workspace() { + let dependencies_with_features: Vec<_> = ROOT_TOML + .dependencies() + .filter_map(|(name, dependency)| match dependency { + DependencyValue::Object { features: Some(features), .. } => Some((name, features)), + _ => None, + }) + .collect(); + assert!( + dependencies_with_features.is_empty(), + "The following dependencies have features enabled in the workspace Cargo.toml: \ + {dependencies_with_features:#?}. Features should only be activated in the crate that \ + needs them." + ); +}