From c555aba1403b8a6d3bf22e3c821a0a9c9c852795 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 22 Oct 2024 13:58:42 +0800 Subject: [PATCH] ci --- .github/workflows/build.yml | 172 ----- .github/workflows/codeql-analysis.yml | 77 -- .github/workflows/container.yml | 52 -- .github/workflows/gosec.yml | 37 - .github/workflows/linkchecker.yml | 25 - .github/workflows/lint.yml | 106 --- .github/workflows/proto.yml | 49 -- .github/workflows/release.yml | 103 --- .github/workflows/semgrep.yml | 35 - .github/workflows/sims.yml | 446 ------------ .github/workflows/test.yml | 60 +- integration_tests/test_bank_precompiles.py | 86 --- integration_tests/test_basic.py | 108 --- integration_tests/test_broadcast.py | 20 - integration_tests/test_e2ee.py | 152 ---- integration_tests/test_eip1559.py | 107 --- integration_tests/test_eip712.py | 82 --- integration_tests/test_exported_genesis.py | 55 -- integration_tests/test_filters.py | 38 - integration_tests/test_gov_update_params.py | 65 -- integration_tests/test_gravity.py | 683 ------------------ integration_tests/test_gravity_2.py | 422 ----------- integration_tests/test_ibc.py | 218 ------ integration_tests/test_ibc_rly.py | 364 ---------- integration_tests/test_ibc_rly_gas.py | 40 - integration_tests/test_ibc_timeout.py | 59 -- integration_tests/test_ibc_update_client.py | 133 ---- integration_tests/test_ica.py | 181 ----- integration_tests/test_ica_incentivized.py | 100 --- integration_tests/test_ica_precompile.py | 480 ------------ integration_tests/test_mempool.py | 82 --- integration_tests/test_min_gas_price.py | 123 ---- integration_tests/test_permissions.py | 23 - integration_tests/test_pruned_node.py | 122 ---- integration_tests/test_replay_block.py | 141 ---- integration_tests/test_rollback.py | 96 --- integration_tests/test_streamer.py | 63 -- integration_tests/test_subscribe.py | 169 ----- integration_tests/test_upgrade.py | 296 -------- integration_tests/test_versiondb.py | 102 --- integration_tests/test_vesting.py | 21 - integration_tests/utils.py | 5 +- .../compositions/docker-compose.jsonnet | 2 +- 43 files changed, 6 insertions(+), 5794 deletions(-) delete mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/codeql-analysis.yml delete mode 100644 .github/workflows/container.yml delete mode 100644 .github/workflows/gosec.yml delete mode 100644 .github/workflows/linkchecker.yml delete mode 100644 .github/workflows/lint.yml delete mode 100644 .github/workflows/proto.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/semgrep.yml delete mode 100644 .github/workflows/sims.yml delete mode 100644 integration_tests/test_bank_precompiles.py delete mode 100644 integration_tests/test_broadcast.py delete mode 100644 integration_tests/test_e2ee.py delete mode 100644 integration_tests/test_eip1559.py delete mode 100644 integration_tests/test_eip712.py delete mode 100644 integration_tests/test_exported_genesis.py delete mode 100644 integration_tests/test_gov_update_params.py delete mode 100644 integration_tests/test_gravity.py delete mode 100644 integration_tests/test_gravity_2.py delete mode 100644 integration_tests/test_ibc.py delete mode 100644 integration_tests/test_ibc_rly.py delete mode 100644 integration_tests/test_ibc_rly_gas.py delete mode 100644 integration_tests/test_ibc_timeout.py delete mode 100644 integration_tests/test_ibc_update_client.py delete mode 100644 integration_tests/test_ica.py delete mode 100644 integration_tests/test_ica_incentivized.py delete mode 100644 integration_tests/test_ica_precompile.py delete mode 100644 integration_tests/test_mempool.py delete mode 100644 integration_tests/test_min_gas_price.py delete mode 100644 integration_tests/test_permissions.py delete mode 100644 integration_tests/test_pruned_node.py delete mode 100644 integration_tests/test_replay_block.py delete mode 100644 integration_tests/test_rollback.py delete mode 100644 integration_tests/test_streamer.py delete mode 100644 integration_tests/test_subscribe.py delete mode 100644 integration_tests/test_upgrade.py delete mode 100644 integration_tests/test_versiondb.py delete mode 100644 integration_tests/test_vesting.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index e309e8e155..0000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,172 +0,0 @@ -name: Build -on: - merge_group: - pull_request: - push: - branches: - - main - - release/** - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build: - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, macos-14] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - id: changed-files - uses: tj-actions/changed-files@v41 - with: - files: | - **/*.go - *.mod - *.sum - - uses: cachix/cachix-action@v12 - if: steps.changed-files.outputs.any_changed == 'true' - with: - name: cronos - # github don't pass secrets for pull request from fork repos, - # in that case the push is disabled naturally. - signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" - - name: Run build - run: ./scripts/release.sh - if: steps.changed-files.outputs.any_changed == 'true' - - uses: actions/upload-artifact@v3 - with: - name: "cronosd-tarball-${{ matrix.os }}" - path: "*.tar.gz" - if-no-files-found: ignore - - unittest: - runs-on: ubuntu-latest - timeout-minutes: 40 - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - id: changed-files - uses: tj-actions/changed-files@v41 - with: - files: | - **/*.go - *.mod - *.sum - - uses: cachix/cachix-action@v12 - if: steps.changed-files.outputs.any_changed == 'true' - with: - name: cronos - # github don't pass secrets for pull request from fork repos, - # in that case the push is disabled naturally. - signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" - - name: test & coverage report creation - run: | - nix develop .#rocksdb -c make test test-versiondb - if: steps.changed-files.outputs.any_changed == 'true' - - name: filter out proto files - run: | - excludelist+=" $(find ./ -type f -name '*.pb.go')" - for filename in ${excludelist}; do - filename=$(echo $filename | sed 's/^./github.com\/crypto-org-chain\/cronos/g') - echo "Excluding ${filename} from coverage report..." - sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt - done - if: steps.changed-files.outputs.any_changed == 'true' - - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./coverage.txt,./memiavl/coverage.txt,./store/coverage.txt,./versiondb/coverage.txt - fail_ci_if_error: true - if: steps.changed-files.outputs.any_changed == 'true' - - gomod2nix: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: changed-files - uses: tj-actions/changed-files@v41 - with: - files: | - go.mod - go.sum - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - if: steps.changed-files.outputs.any_changed == 'true' - - name: gomod2nix - run: nix develop -c gomod2nix - if: steps.changed-files.outputs.any_changed == 'true' - - name: check working directory is clean - id: changes - run: | - set +e - (git diff --no-ext-diff --exit-code) - echo "name=changed::$?" >> $GITHUB_OUTPUT - - uses: actions/upload-artifact@v3 - if: steps.changes.outputs.changed == 1 - with: - name: gomod2nix.toml - path: ./gomod2nix.toml - - if: steps.changes.outputs.changed == 1 - run: echo "Working directory is dirty" && exit 1 - - contracts: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: changed-files - uses: tj-actions/changed-files@v41 - with: - files: | - contracts - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - if: steps.changed-files.outputs.any_changed == 'true' - - uses: cachix/cachix-action@v12 - if: steps.changed-files.outputs.any_changed == 'true' - with: - name: cronos - extraPullNames: dapp - signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" - - name: test contracts - if: steps.changed-files.outputs.any_changed == 'true' - run: make test-cronos-contracts - - name: build contracts - if: steps.changed-files.outputs.any_changed == 'true' - run: make gen-cronos-contracts - - name: check working directory is clean - id: changes - run: | - set +e - (git diff --no-ext-diff --exit-code) - echo "name=changed::$?" >> $GITHUB_OUTPUT - - uses: actions/upload-artifact@v3 - if: steps.changes.outputs.changed == 1 - with: - name: contracts_out - path: ./contracts/out - if-no-files-found: ignore - - if: steps.changes.outputs.changed == 1 - run: echo "Working directory is dirty" && exit 1 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 2d8fba0125..0000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,77 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: - - main - - release/** - paths: - - "**.go" - pull_request: - branches: - - main - - release/** - paths: - - "**.go" - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'go' ] - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: '^1.22.0' - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: "go" - queries: +security-and-quality,github/codeql/go/ql/src/experimental/InconsistentCode/DeferInLoop.ql@main,github/codeql/go/ql/src/experimental/Unsafe/WrongUsageOfUnsafe.ql@main,github/codeql/go/ql/src/experimental/CWE-369/DivideByZero.ql@main - packs: +crypto-com/cosmos-sdk-codeql - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml deleted file mode 100644 index 606d5396da..0000000000 --- a/.github/workflows/container.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Push Testground Image - -on: - push: - branches: - - main - - release/** - tags: - - "v*.*.*" - -env: - IMAGE_NAME: cronos-testground - -jobs: - - push: - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - - steps: - - uses: actions/checkout@v4 - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-24.05 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - uses: cachix/cachix-action@v12 - with: - name: cronos - signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" - - name: build and push image - run: | - # login to ghcr.io - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - - VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,' | sed -e 's/^v//') - [ "$VERSION" == "main" ] && VERSION=latest - echo "VERSION: $VERSION" - - IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - echo "IMAGE_ID: $IMAGE_ID" - - BUILD_TAG="$(nix eval --raw .#testground-image.imageTag)" - echo "BUILD_TAG: $BUILD_TAG" - - docker load -i "$(nix build --no-link --print-out-paths .#testground-image)" - docker run --rm -e TEST_CASE=info $IMAGE_NAME:$BUILD_TAG - docker tag $IMAGE_NAME:$BUILD_TAG $IMAGE_ID:$VERSION - docker push $IMAGE_ID:$VERSION diff --git a/.github/workflows/gosec.yml b/.github/workflows/gosec.yml deleted file mode 100644 index f2ce269515..0000000000 --- a/.github/workflows/gosec.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Run Gosec -on: - pull_request: - push: - branches: - - main - - release/** - -jobs: - Gosec: - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - env: - GO111MODULE: on - steps: - - uses: actions/checkout@v3 - - uses: technote-space/get-diff-action@v3 - with: - SUFFIX_FILTER: | - .go - .mod - .sum - - name: Run Gosec Security Scanner - uses: informalsystems/gosec@master - with: - # we let the report trigger content trigger a failure using the GitHub Security features. - args: '-no-fail -fmt sarif -out results.sarif ./...' - if: "env.GIT_DIFF_FILTERED != ''" - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v2 - with: - # Path to SARIF file relative to the root of the repository - sarif_file: results.sarif - if: "env.GIT_DIFF_FILTERED != ''" diff --git a/.github/workflows/linkchecker.yml b/.github/workflows/linkchecker.yml deleted file mode 100644 index 14d1641c96..0000000000 --- a/.github/workflows/linkchecker.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Check Markdown links -on: - schedule: - - cron: "* */24 * * *" - pull_request: - push: - branches: - - main - - release/** -jobs: - markdown-link-check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: changed-files - uses: tj-actions/changed-files@v41 - with: - files: | - docs/**/*.md - - uses: gaurav-nelson/github-action-markdown-link-check@1.0.13 - if: steps.changed-files.outputs.any_changed == 'true' - with: - folder-path: "docs" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 9d30403bc2..0000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,106 +0,0 @@ -name: Run Lint -# Lint runs golangci-lint over the entire cronos repository This workflow is -# run on every pull request and push to main The `golangci` will pass without -# running if no *.{go, mod, sum} files have been changed. -on: - merge_group: - pull_request: - push: - branches: - - main - - release/** - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - golangci: - name: Run golangci-lint - runs-on: macos-latest - timeout-minutes: 60 - steps: - - uses: actions/setup-go@v3 - with: - go-version: '1.22.7' - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - id: changed-files - uses: tj-actions/changed-files@v41 - with: - files: | - **/*.go - *.mod - *.sum - - name: run golangci-lint - run: | - nix profile install -f ./nix golangci-lint - nix profile install -f ./nix rocksdb - export PKG_CONFIG_PATH=$HOME/.nix-profile/lib/pkgconfig - export CGO_CFLAGS="$(pkg-config --cflags rocksdb)" CGO_LDFLAGS="$(pkg-config --libs rocksdb)" - golangci-lint version - - BUILD_TAGS=rocksdb,grocksdb_clean_link,objstore - go build -tags $BUILD_TAGS ./cmd/cronosd - golangci-lint run --out-format=github-actions --path-prefix=./ --timeout 10m --build-tags $BUILD_TAGS - cd versiondb - golangci-lint run --out-format=github-actions --path-prefix=./versiondb --timeout 10m --build-tags $BUILD_TAGS - cd ../memiavl - golangci-lint run --out-format=github-actions --path-prefix=./memiavl --timeout 10m --build-tags objstore - cd ../store - golangci-lint run --out-format=github-actions --path-prefix=./store --timeout 10m --build-tags objstore - # Check only if there are differences in the source code - if: steps.changed-files.outputs.any_changed == 'true' - - lint-python: - name: Lint python - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: changed-files - uses: tj-actions/changed-files@v41 - with: - files: | - **/poetry.lock - **/pyproject.toml - **/*.py - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - if: steps.changed-files.outputs.any_changed == 'true' - - uses: cachix/cachix-action@v12 - if: steps.changed-files.outputs.any_changed == 'true' - with: - name: cronos - - run: nix-shell -I nixpkgs=./nix -p test-env --run "make lint-py" - if: steps.changed-files.outputs.any_changed == 'true' - - lint-nix: - name: Lint nix - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: changed-files - uses: tj-actions/changed-files@v41 - with: - files: | - *.nix - **/*.nix - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - if: steps.changed-files.outputs.any_changed == 'true' - - run: nix-shell -I nixpkgs=./nix -p nixpkgs-fmt --run "make lint-nix" - if: steps.changed-files.outputs.any_changed == 'true' diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml deleted file mode 100644 index 52e96b1b9e..0000000000 --- a/.github/workflows/proto.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Protobuf -# Protobuf runs buf (https://buf.build/) lint and check-breakage -# This workflow is only run when a .proto file has been changed -on: - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - lint: - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - uses: actions/checkout@v3 - - uses: technote-space/get-diff-action@v6 - with: - PATTERNS: | - **/**.proto - - name: lint - run: make proto-lint - if: env.GIT_DIFF - breakage: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: technote-space/get-diff-action@v6 - with: - PATTERNS: | - **/**.proto - - name: check-breakage - run: make proto-check-breaking - if: env.GIT_DIFF - protogen: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: technote-space/get-diff-action@v6 - with: - PATTERNS: | - **/**.proto - - name: proto-gen-ci - if: env.GIT_DIFF - run: | - make proto-gen-ci # proto-swagger-gen FIXME swagger-gen result is not reproducible in CI - git checkout -- go.mod go.sum # FIXME doc gen not reproducible in CI - - name: check working directory is clean - uses: numtide/clean-git-action@main diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 017b829b74..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,103 +0,0 @@ -name: release - -on: - push: - tags: - - "v*.*.*" - -permissions: - contents: write - -jobs: - release: - runs-on: ubuntu-latest - environment: release - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - uses: cachix/cachix-action@v12 - with: - name: cronos - signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" - - - name: build binaries - run: | - # install sha256sum - nix-env -i coreutils -f '' - - # build binaries - ./scripts/release.sh - - # update checksum and upload - sha256sum *.tar.gz > "checksums.txt" - echo 'FILES<> $GITHUB_ENV - ls -1 *.tar.gz >> $GITHUB_ENV - echo "checksums.txt" >> $GITHUB_ENV - echo 'EOF' >> $GITHUB_ENV - cat $GITHUB_ENV - - name: upload binaries - uses: softprops/action-gh-release@v1 - with: - draft: true - files: "${{ env.FILES }}" - - release-macos: - # runs sequentially to avoid creating duplicated release - needs: ["release"] - strategy: - matrix: - runner: [macos-13, macos-14] - runs-on: ${{ matrix.runner }} - environment: release - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - uses: apple-actions/import-codesign-certs@v1 - with: - p12-file-base64: ${{ secrets.MAC_CODE_SIGN_CERT }} - p12-password: ${{ secrets.MAC_CODE_SIGN_CERT_PASS }} - - uses: cachix/cachix-action@v12 - with: - name: cronos - signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" - - name: build binaries - env: - MAC_CODE_API_KEY: ${{ secrets.MAC_CODE_API_KEY }} - MAC_CODE_API_KEY_ID: ${{ secrets.MAC_CODE_API_KEY_ID }} - MAC_CODE_API_ISSUER_ID: ${{ secrets.MAC_CODE_API_ISSUER_ID }} - MAC_CODE_API_DEVELOPER_ID: ${{ secrets.MAC_CODE_API_DEVELOPER_ID }} - run: | - # install sha256sum - nix-env -i coreutils -f '' - - # build binaries - ./scripts/release.sh - - # codesign - for tarball in *.tar.gz; - do - ./scripts/codesign_macos.sh $tarball - mv signed.tar.gz $tarball - done - - # update checksum and upload - CHKFILE="checksums-darwin-$(uname -p).txt" - sha256sum *.tar.gz > "$CHKFILE" - echo 'FILES<> $GITHUB_ENV - ls -1 *.tar.gz >> $GITHUB_ENV - echo "$CHKFILE" >> $GITHUB_ENV - echo 'EOF' >> $GITHUB_ENV - cat $GITHUB_ENV - - name: upload binaries - uses: softprops/action-gh-release@v1 - with: - draft: true - files: "${{ env.FILES }}" diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml deleted file mode 100644 index c206c10220..0000000000 --- a/.github/workflows/semgrep.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Semgrep -on: - # Scan changed files in PRs, block on new issues only (existing issues ignored) - pull_request: {} - push: - branches: - - main - - release/** - paths: - - .github/workflows/semgrep.yml - schedule: - - cron: '0 0 * * 0' -jobs: - # Update from: https://semgrep.dev/docs/semgrep-ci/sample-ci-configs/#github-actions - semgrep: - name: Scan - runs-on: ubuntu-latest - container: - image: returntocorp/semgrep - if: (github.actor != 'dependabot[bot]') - steps: - # Fetch project source with GitHub Actions Checkout. - - uses: actions/checkout@v3 - with: - submodules: true - # Run the "semgrep ci" command on the command line of the docker image. - - run: semgrep ci - env: - # Add the rules that Semgrep uses by setting the SEMGREP_RULES environment variable. - SEMGREP_RULES: p/golang # more at semgrep.dev/explore - SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} - # Uncomment SEMGREP_TIMEOUT to set this job's timeout (in seconds): - # Default timeout is 1800 seconds (30 minutes). - # Set to 0 to disable the timeout. - # SEMGREP_TIMEOUT: 300 diff --git a/.github/workflows/sims.yml b/.github/workflows/sims.yml deleted file mode 100644 index 67c07dfbc8..0000000000 --- a/.github/workflows/sims.yml +++ /dev/null @@ -1,446 +0,0 @@ -name: Sims -# Sims workflow runs multiple types of simulations (nondeterminism, import-export, after-import, multi-seed-short) -# This workflow will run on main and release branches, if a .go, .mod or .sum file have been changed -on: - push: - paths-ignore: - - 'docs/**' - branches: - - main - - release/** - tags: - - "*" - pull_request: - types: auto_merge_enabled - issue_comment: - types: [created, edited] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - member: - name: Check whether it is triggered by team members with issue_comment or push or pull_request - runs-on: ubuntu-latest - permissions: - pull-requests: write - if: >- - (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/runsim')) || - github.event_name == 'push' || github.event_name == 'pull_request' - outputs: - valid: ${{ steps.setValid.outputs.valid }} - steps: - - uses: tspascoal/get-user-teams-membership@v1.0.2 - id: checkMember - if: github.event_name == 'issue_comment' - with: - username: ${{ github.actor }} - team: 'cronos-dev' - GITHUB_TOKEN: ${{ secrets.ORG_READ_BOT_PAT }} - - name: Comment PR for authentication failure - uses: crypto-org-chain/actions-pull-request-add-comment@master - if: (steps.checkMember.outputs.isTeamMember == 'false') && (github.event_name == 'issue_comment') - with: - message: | - Sorry only cronos-dev team member could run simulations by '/runsim'. - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: set valid if it is push/pull_request event or check if it is triggered by team members with issue_comment - id: setValid - run: | - if [[ "${{ steps.checkMember.outputs.isTeamMember }}" == "true" ]]; then - echo "valid=true" >> $GITHUB_OUTPUT - elif [[ "${{ github.event_name }}" == "push" || "${{ github.event_name }}" == "pull_request" ]]; then - echo "valid=true" >> $GITHUB_OUTPUT - else - echo "valid=false" >> $GITHUB_OUTPUT - fi - - build: - runs-on: ubuntu-latest - needs: member - permissions: - pull-requests: write - if: needs.member.outputs.valid == 'true' - outputs: - repo_name: ${{ steps.pr_data.outputs.repo_name }} - ref: ${{ steps.pr_data.outputs.ref }} - steps: - - name: Comment PR for Sim test started - uses: crypto-org-chain/actions-pull-request-add-comment@master - if: github.event_name == 'issue_comment' - with: - message: | - Simulation tests get triggered and started by `/runsim`. - Please check further progress [here](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Github API Request - id: request - uses: octokit/request-action@v2.0.0 - if: github.event_name == 'issue_comment' - with: - route: ${{ github.event.issue.pull_request.url }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Get Comment PR informations - id: pr_data - if: github.event_name == 'issue_comment' - env: - COMMENTBODY: ${{ github.event.comment.body }} - run: | - echo "repo_name=${{ fromJson(steps.request.outputs.data).head.repo.full_name }}" >> $GITHUB_OUTPUT - comment_hash=`echo "$COMMENTBODY" | cut -d' ' -f2` # get commit hash if any - if [[ "${comment_hash}" == "/runsim" ]]; then - echo "ref=${{ fromJson(steps.request.outputs.data).head.ref }}" >> $GITHUB_OUTPUT # use default head ref - else - echo "ref=${comment_hash}" >> $GITHUB_OUTPUT # use comment provided ref - fi - - name: Checkout Comment PR Branch - uses: actions/checkout@v3 - if: github.event_name == 'issue_comment' - with: - submodules: true - token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ steps.pr_data.outputs.repo_name }} - ref: ${{ steps.pr_data.outputs.ref }} - - name: Normal check out code - uses: actions/checkout@v3 - with: - submodules: true - if: github.event_name == 'push' || github.event_name == 'pull_request' - - uses: actions/setup-go@v3 - with: - go-version: '^1.22.0' - - name: Display go version - run: go version - - run: make build - - name: Create file status_build.txt and write the job status into it - if: github.event_name == 'issue_comment' - run: | - echo ${{ job.status }} > status_build.txt - - name: Upload file status_build.txt as an artifact - if: github.event_name == 'issue_comment' - uses: actions/upload-artifact@v3 - with: - name: pass_status_build - path: status_build.txt - - install-runsim: - runs-on: ubuntu-latest - needs: build - steps: - - uses: actions/setup-go@v3 - with: - go-version: '^1.22.0' - - name: Display go version - run: go version - - name: Install runsim - run: export GO111MODULE="on" && go install github.com/cosmos/tools/cmd/runsim@v1.0.0 - - uses: actions/cache@v2.1.6 - with: - path: ~/go/bin - key: ${{ runner.os }}-go-runsim-binary - - name: Create file status_install.txt and write the job status into it - if: github.event_name == 'issue_comment' - run: | - echo ${{ job.status }} > status_install.txt - - name: Upload file status_install.txt as an artifact - if: github.event_name == 'issue_comment' - uses: actions/upload-artifact@v3 - with: - name: pass_status_install - path: status_install.txt - - test-sim-nondeterminism: - runs-on: ubuntu-latest - timeout-minutes: 120 - needs: [build, install-runsim] - steps: - - uses: actions/setup-go@v3 - with: - go-version: '^1.22.0' - - name: Checkout Comment PR Branch - uses: actions/checkout@v3 - if: github.event_name == 'issue_comment' - with: - submodules: true - token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ needs.build.outputs.repo_name }} - ref: ${{ needs.build.outputs.ref }} - - name: Normal check out code - uses: actions/checkout@v3 - if: github.event_name == 'push' || github.event_name == 'pull_request' - with: - submodules: true - - name: Display go version - run: go version - # the original repo technote-space does not include auto_merge_enabled into target events - # we can move back after this pr merged: https://github.com/technote-space/get-diff-action/pull/193 - - uses: adu-crypto/get-diff-action@gh-actions - with: - PATTERNS: | - **/**.go - go.mod - go.sum - if: github.event_name == 'push' || github.event_name == 'pull_request' - - uses: actions/cache@v2.1.6 - with: - path: ~/go/bin - key: ${{ runner.os }}-go-runsim-binary - if: >- - (env.GIT_DIFF && (github.event_name == 'push' || github.event_name == 'pull_request')) || - (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/runsim')) - - name: test-sim-nondeterminism - run: | - make test-sim-nondeterminism - if: >- - (env.GIT_DIFF && (github.event_name == 'push' || github.event_name == 'pull_request')) || - (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/runsim')) - - name: Create file status_sim1.txt and write the job status into it - if: github.event_name == 'issue_comment' - run: | - echo ${{ job.status }} > status_sim1.txt - - name: Upload file status_sim1.txt as an artifact - if: github.event_name == 'issue_comment' - uses: actions/upload-artifact@v3 - with: - name: pass_status_sim1 - path: status_sim1.txt - - test-sim-import-export: - runs-on: ubuntu-latest - timeout-minutes: 120 - needs: [build, install-runsim] - steps: - - uses: actions/setup-go@v3 - with: - go-version: '^1.22.0' - - name: Checkout Comment PR Branch - uses: actions/checkout@v3 - if: github.event_name == 'issue_comment' - with: - submodules: true - token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ needs.build.outputs.repo_name }} - ref: ${{ needs.build.outputs.ref }} - - name: Normal check out code - uses: actions/checkout@v3 - if: github.event_name == 'push' || github.event_name == 'pull_request' - with: - submodules: true - - name: Display go version - run: go version - # the original repo technote-space does not include auto_merge_enabled into target events - # we can move back after this pr merged: https://github.com/technote-space/get-diff-action/pull/193 - - uses: adu-crypto/get-diff-action@gh-actions - with: - PATTERNS: | - **/**.go - go.mod - go.sum - if: github.event_name == 'push' || github.event_name == 'pull_request' - - uses: actions/cache@v2.1.6 - with: - path: ~/go/bin - key: ${{ runner.os }}-go-runsim-binary - if: >- - (env.GIT_DIFF && (github.event_name == 'push' || github.event_name == 'pull_request')) || - (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/runsim')) - - name: test-sim-import-export - run: | - make test-sim-import-export - if: >- - (env.GIT_DIFF && (github.event_name == 'push' || github.event_name == 'pull_request')) || - (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/runsim')) - - name: Create file status_sim2.txt and write the job status into it - if: github.event_name == 'issue_comment' - run: | - echo ${{ job.status }} > status_sim2.txt - - name: Upload file status_sim2.txt as an artifact - if: github.event_name == 'issue_comment' - uses: actions/upload-artifact@v3 - with: - name: pass_status_sim2 - path: status_sim2.txt - - test-sim-after-import: - runs-on: ubuntu-latest - timeout-minutes: 120 - needs: [build, install-runsim] - steps: - - uses: actions/setup-go@v3 - with: - go-version: '^1.22.0' - - name: Checkout Comment PR Branch - uses: actions/checkout@v3 - if: github.event_name == 'issue_comment' - with: - submodules: true - token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ needs.build.outputs.repo_name }} - ref: ${{ needs.build.outputs.ref }} - - name: Normal check out code - uses: actions/checkout@v3 - if: github.event_name == 'push' || github.event_name == 'pull_request' - with: - submodules: true - - name: Display go version - run: go version - # the original repo technote-space does not include auto_merge_enabled into target events - # we can move back after this pr merged: https://github.com/technote-space/get-diff-action/pull/193 - - uses: adu-crypto/get-diff-action@gh-actions - with: - PATTERNS: | - **/**.go - go.mod - go.sum - if: github.event_name == 'push' || github.event_name == 'pull_request' - - uses: actions/cache@v2.1.6 - with: - path: ~/go/bin - key: ${{ runner.os }}-go-runsim-binary - if: >- - (env.GIT_DIFF && (github.event_name == 'push' || github.event_name == 'pull_request')) || - (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/runsim')) - - name: test-sim-after-import - run: | - make test-sim-after-import - if: >- - (env.GIT_DIFF && (github.event_name == 'push' || github.event_name == 'pull_request')) || - (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/runsim')) - - name: Create file status_sim3.txt and write the job status into it - if: github.event_name == 'issue_comment' - run: | - echo ${{ job.status }} > status_sim3.txt - - name: Upload file status_sim3.txt as an artifact - if: github.event_name == 'issue_comment' - uses: actions/upload-artifact@v3 - with: - name: pass_status_sim3 - path: status_sim3.txt - - test-sim-multi-seed-short: - runs-on: ubuntu-latest - timeout-minutes: 120 - needs: [build, install-runsim] - steps: - - uses: actions/setup-go@v3 - with: - go-version: '^1.22.0' - - name: Checkout Comment PR Branch - uses: actions/checkout@v3 - if: github.event_name == 'issue_comment' - with: - submodules: true - token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ needs.build.outputs.repo_name }} - ref: ${{ needs.build.outputs.ref }} - - name: Normal check out code - uses: actions/checkout@v3 - if: github.event_name == 'push' || github.event_name == 'pull_request' - with: - submodules: true - - name: Display go version - run: go version - # the original repo technote-space does not include auto_merge_enabled into target events - # we can move back after this pr merged: https://github.com/technote-space/get-diff-action/pull/193 - - uses: adu-crypto/get-diff-action@gh-actions - with: - PATTERNS: | - **/**.go - go.mod - go.sum - if: github.event_name == 'push' || github.event_name == 'pull_request' - - uses: actions/cache@v2.1.6 - with: - path: ~/go/bin - key: ${{ runner.os }}-go-runsim-binary - if: >- - (env.GIT_DIFF && (github.event_name == 'push' || github.event_name == 'pull_request')) || - (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/runsim')) - - name: test-sim-multi-seed-short - run: | - make test-sim-multi-seed-short - if: >- - (env.GIT_DIFF && (github.event_name == 'push' || github.event_name == 'pull_request')) || - (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/runsim')) - - name: Create file status_sim4.txt and write the job status into it - if: github.event_name == 'issue_comment' - run: | - echo ${{ job.status }} > status_sim4.txt - - name: Upload file status_sim4.txt as an artifact - if: github.event_name == 'issue_comment' - uses: actions/upload-artifact@v3 - with: - name: pass_status_sim4 - path: status_sim4.txt - - report-status-pr: - runs-on: ubuntu-latest - needs: [member, test-sim-nondeterminism, test-sim-import-export, test-sim-after-import, test-sim-multi-seed-short] - permissions: - pull-requests: write - if: always() && github.event_name == 'issue_comment' && needs.member.outputs.valid == 'true' - steps: - - name: Download artifact pass_status_build - uses: actions/download-artifact@v4.1.7 - continue-on-error: true - with: - name: pass_status_build - - name: Download artifact pass_status_install - uses: actions/download-artifact@v4.1.7 - continue-on-error: true - with: - name: pass_status_install - - name: Download artifact pass_status_sim1 - uses: actions/download-artifact@v4.1.7 - continue-on-error: true - with: - name: pass_status_sim1 - - name: Download artifact pass_status_sim2 - uses: actions/download-artifact@v4.1.7 - continue-on-error: true - with: - name: pass_status_sim2 - - name: Download artifact pass_status_sim3 - uses: actions/download-artifact@v4.1.7 - continue-on-error: true - with: - name: pass_status_sim3 - - name: Download artifact pass_status_sim4 - uses: actions/download-artifact@v4.1.7 - continue-on-error: true - with: - name: pass_status_sim4 - - name: Set the statuses of Jobs as output parameters - id: set_outputs - continue-on-error: true - run: | - echo "status_job01=$(> $GITHUB_OUTPUT - echo "status_job02=$(> $GITHUB_OUTPUT - echo "status_job03=$(> $GITHUB_OUTPUT - echo "status_job04=$(> $GITHUB_OUTPUT - echo "status_job05=$(> $GITHUB_OUTPUT - echo "status_job06=$(> $GITHUB_OUTPUT - - name: The sim jobs has succeed - uses: crypto-org-chain/actions-pull-request-add-comment@master - if: >- - steps.set_outputs.outputs.status_job01 == 'success' && steps.set_outputs.outputs.status_job02 == 'success' - && steps.set_outputs.outputs.status_job03 == 'success' && steps.set_outputs.outputs.status_job04 == 'success' - && steps.set_outputs.outputs.status_job05 == 'success' && steps.set_outputs.outputs.status_job06 == 'success' - with: - message: | - ✅ `/runsim` simulation test has succeeded 🎉 - Please further check [here](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: The sim jobs has failed - uses: crypto-org-chain/actions-pull-request-add-comment@master - if: >- - steps.set_outputs.outputs.status_job01 != 'success' || steps.set_outputs.outputs.status_job02 != 'success' - || steps.set_outputs.outputs.status_job03 != 'success' || steps.set_outputs.outputs.status_job04 != 'success' - || steps.set_outputs.outputs.status_job05 != 'success' || steps.set_outputs.outputs.status_job06 != 'success' - with: - message: | - ❌ `/runsim` simulation test has failed 😅 - Please further check [here](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 34ab2aed83..2a7d61e1a5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ jobs: timeout-minutes: 240 strategy: matrix: - tests: [unmarked, ibc, ibc_rly_evm, ibc_rly_gas, ibc_timeout, ibc_update_client, ica, gov, upgrade, slow, gas] + tests: [unmarked] env: TESTS_TO_RUN: ${{ matrix.tests }} steps: @@ -73,61 +73,3 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} file: ./profile.txt flags: integration_tests - - upload-cache: - if: github.event_name == 'push' - needs: ["integration_tests"] - strategy: - matrix: - os: [macos-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: changed-files - uses: tj-actions/changed-files@v41 - with: - files: | - docs - *.md - **/*.md - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - if: steps.changed-files.outputs.only_changed == 'false' - - uses: cachix/cachix-action@v12 - if: steps.changed-files.outputs.only_changed == 'false' - with: - name: cronos - extraPullNames: dapp - # github don't pass secrets for pull request from fork repos, - # in that case the push is disabled naturally. - signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" - - name: 'instantiate integration test env' - if: steps.changed-files.outputs.only_changed == 'false' - run: nix-store -r $(nix-instantiate integration_tests/shell.nix) - - testground-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: cachix/install-nix-action@v23 - with: - nix_path: nixpkgs=channel:nixos-22.11 - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - uses: cachix/cachix-action@v12 - with: - name: cronos - # github don't pass secrets for pull request from fork repos, - # in that case the push is disabled naturally. - signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}" - - name: Run tests - run: | - cd testground/benchmark - nix develop -c pytest -vv -s diff --git a/integration_tests/test_bank_precompiles.py b/integration_tests/test_bank_precompiles.py deleted file mode 100644 index 40492168cf..0000000000 --- a/integration_tests/test_bank_precompiles.py +++ /dev/null @@ -1,86 +0,0 @@ -import pytest -import web3 - -from .utils import ( - ADDRS, - CONTRACTS, - KEYS, - deploy_contract, - eth_to_bech32, - module_address, - send_transaction, -) - -pytest.skip("skipping bank precompile tests", allow_module_level=True) - - -def get_balance(cli, addr, denom): - return cli.balance(eth_to_bech32(addr), denom) - - -def test_call(cronos): - w3 = cronos.w3 - cli = cronos.cosmos_cli() - addr = ADDRS["signer1"] - keys = KEYS["signer1"] - contract = deploy_contract(w3, CONTRACTS["TestBank"], (), keys) - denom = "evm/" + contract.address - - def assert_balance(tx, expect_status, amt): - balance = get_balance(cli, addr, denom) - assert balance == contract.caller.nativeBalanceOf(addr) - crc20_balance = contract.caller.balanceOf(addr) - receipt = send_transaction(w3, tx, keys) - assert receipt.status == expect_status - balance += amt - assert balance == get_balance(cli, addr, denom) - assert balance == contract.caller.nativeBalanceOf(addr) - assert crc20_balance - amt == contract.caller.balanceOf(addr) - - # test mint - amt1 = 100 - data = {"from": addr} - tx = contract.functions.moveToNative(amt1).build_transaction(data) - assert_balance(tx, 1, amt1) - - # test exception revert - tx = contract.functions.moveToNativeRevert(amt1).build_transaction( - {"from": addr, "gas": 210000} - ) - assert_balance(tx, 0, 0) - - # test burn - amt2 = 50 - tx = contract.functions.moveFromNative(amt2).build_transaction(data) - assert_balance(tx, 1, -amt2) - - # test transfer - amt3 = 10 - addr2 = ADDRS["signer2"] - tx = contract.functions.nativeTransfer(addr2, amt3).build_transaction(data) - balance = get_balance(cli, addr, denom) - assert balance == contract.caller.nativeBalanceOf(addr) - crc20_balance = contract.caller.balanceOf(addr) - - balance2 = get_balance(cli, addr2, denom) - assert balance2 == contract.caller.nativeBalanceOf(addr2) - crc20_balance2 = contract.caller.balanceOf(addr2) - - receipt = send_transaction(w3, tx, keys) - assert receipt.status == 1 - - balance -= amt3 - assert balance == get_balance(cli, addr, denom) - assert balance == contract.caller.nativeBalanceOf(addr) - assert crc20_balance - amt3 == contract.caller.balanceOf(addr) - - balance2 += amt3 - assert balance2 == get_balance(cli, addr2, denom) - assert balance2 == contract.caller.nativeBalanceOf(addr2) - assert crc20_balance2 + amt3 == contract.caller.balanceOf(addr2) - - # test transfer to blocked address - recipient = module_address("evm") - amt4 = 20 - with pytest.raises(web3.exceptions.ContractLogicError): - contract.functions.nativeTransfer(recipient, amt4).build_transaction(data) diff --git a/integration_tests/test_basic.py b/integration_tests/test_basic.py index 7089b6c9d1..b95be09832 100644 --- a/integration_tests/test_basic.py +++ b/integration_tests/test_basic.py @@ -896,111 +896,3 @@ def fn(cmd): assert num == block_nums[0] for num in block_nums[max_tx_in_block:]: assert num == block_nums[0] + 1 or num == block_nums[0] + 2 - - -def test_replay_protection(cronos): - w3 = cronos.w3 - # https://etherscan.io/tx/0x06d2fa464546e99d2147e1fc997ddb624cec9c8c5e25a050cc381ee8a384eed3 - raw = ( - ( - Path(__file__).parent / "configs/replay-tx-0x" - "06d2fa464546e99d2147e1fc997ddb62" - "4cec9c8c5e25a050cc381ee8a384eed3.tx" - ) - .read_text() - .strip() - ) - with pytest.raises( - Exception, - match=r"only replay-protected \(EIP-155\) transactions allowed over RPC", - ): - w3.eth.send_raw_transaction(HexBytes(raw)) - - -@pytest.mark.gov -def test_submit_any_proposal(cronos, tmp_path): - submit_any_proposal(cronos, tmp_path) - - -@pytest.mark.gov -def test_submit_send_enabled(cronos, tmp_path): - # check bank send enable - cli = cronos.cosmos_cli() - denoms = ["basetcro", "stake"] - assert len(cli.query_bank_send(*denoms)) == 0, "should be empty" - send_enable = [ - {"denom": "basetcro"}, - {"denom": "stake", "enabled": True}, - ] - authority = module_address("gov") - submit_gov_proposal( - cronos, - tmp_path, - messages=[ - { - "@type": "/cosmos.bank.v1beta1.MsgSetSendEnabled", - "authority": authority, - "sendEnabled": send_enable, - } - ], - ) - assert cli.query_bank_send(*denoms) == send_enable - - -def test_block_stm_delete(cronos): - """ - this test case revealed a bug in block-stm, - see: https://github.com/crypto-org-chain/go-block-stm/pull/11 - """ - w3 = cronos.w3 - cli = cronos.cosmos_cli() - acc = derive_new_account(3) - sender = acc.address - - # fund new sender - fund = 3000000000000000000 - tx = {"to": sender, "value": fund, "gasPrice": w3.eth.gas_price} - send_transaction(w3, tx) - assert w3.eth.get_balance(sender, "latest") == fund - nonce = w3.eth.get_transaction_count(sender) - wait_for_new_blocks(cli, 1) - txhashes = [] - total = 3 - for n in range(total): - tx = { - "to": "0x2956c404227Cc544Ea6c3f4a36702D0FD73d20A2", - "value": fund // total, - "gas": 21000, - "maxFeePerGas": 6556868066901, - "maxPriorityFeePerGas": 1500000000, - "nonce": nonce + n, - } - signed = sign_transaction(w3, tx, acc.key) - txhash = w3.eth.send_raw_transaction(signed.rawTransaction) - txhashes.append(txhash) - for txhash in txhashes[0 : total - 1]: - res = w3.eth.wait_for_transaction_receipt(txhash) - assert res.status == 1 - w3_wait_for_block(w3, w3.eth.block_number + 3, timeout=30) - - -def test_multi_acc(cronos): - cli = cronos.cosmos_cli() - cli.make_multisig("multitest1", "signer1", "signer2") - multi_addr = cli.address("multitest1") - signer1 = cli.address("signer1") - cli.transfer(signer1, multi_addr, "1basetcro") - acc = cli.account(multi_addr) - res = cli.account_by_num(acc["account"]["value"]["base_account"]["account_number"]) - assert res["account_address"] == multi_addr - - -def test_textual(cronos): - cli = cronos.cosmos_cli() - rsp = cli.transfer( - cli.address("validator"), - cli.address("signer2"), - "1basetcro", - sign_mode="textual", - ) - assert rsp["code"] == 0, rsp["raw_log"] diff --git a/integration_tests/test_broadcast.py b/integration_tests/test_broadcast.py deleted file mode 100644 index e063b092ac..0000000000 --- a/integration_tests/test_broadcast.py +++ /dev/null @@ -1,20 +0,0 @@ -from pathlib import Path - -import pytest - -from .network import setup_custom_cronos -from .utils import submit_any_proposal - -pytestmark = pytest.mark.gov - - -@pytest.fixture(scope="module") -def custom_cronos(tmp_path_factory): - path = tmp_path_factory.mktemp("cronos") - yield from setup_custom_cronos( - path, 26400, Path(__file__).parent / "configs/broadcast.jsonnet" - ) - - -def test_submit_any_proposal(custom_cronos, tmp_path): - submit_any_proposal(custom_cronos, tmp_path) diff --git a/integration_tests/test_e2ee.py b/integration_tests/test_e2ee.py deleted file mode 100644 index 93ed7e61cc..0000000000 --- a/integration_tests/test_e2ee.py +++ /dev/null @@ -1,152 +0,0 @@ -import json - -import pytest -from eth_utils import to_checksum_address -from hexbytes import HexBytes -from pystarport import ports - -from .network import Cronos -from .utils import ADDRS, bech32_to_eth, wait_for_new_blocks, wait_for_port - - -def test_register(cronos: Cronos): - cli = cronos.cosmos_cli() - pubkey0 = cli.e2ee_keygen(keyring_name="key0") - with pytest.raises(AssertionError) as exc: - cli.register_e2ee_key(pubkey0 + "malformed", _from="validator") - assert "malformed recipient" in str(exc.value) - assert not cli.query_e2ee_key(cli.address("validator")) - - -def gen_validator_identity(cronos: Cronos): - for i in range(len(cronos.config["validators"])): - cli = cronos.cosmos_cli(i) - if cli.query_e2ee_key(cli.address("validator")): - return - pubkey = cli.e2ee_keygen() - assert cli.e2ee_pubkey() == pubkey - cli.register_e2ee_key(pubkey, _from="validator") - assert cli.query_e2ee_key(cli.address("validator")) == pubkey - - cronos.supervisorctl("restart", f"cronos_777-1-node{i}") - - wait_for_new_blocks(cronos.cosmos_cli(), 1) - - -def test_encrypt_decrypt(cronos): - gen_validator_identity(cronos) - - cli0 = cronos.cosmos_cli() - cli1 = cronos.cosmos_cli(1) - - # query in batch - assert ( - len( - cli0.query_e2ee_keys( - cli0.address("validator"), - cli1.address("validator"), - ) - ) - == 2 - ) - - # prepare data file to encrypt - content = "Hello World!" - plainfile = cli0.data_dir / "plaintext" - plainfile.write_text(content) - cipherfile = cli0.data_dir / "ciphertext" - cli0.e2ee_encrypt( - plainfile, - cli0.address("validator"), - cli1.address("validator"), - output=cipherfile, - ) - - assert cli0.e2ee_decrypt(cipherfile) == content - assert cli1.e2ee_decrypt(cipherfile) == content - - -def encrypt_to_validators(cli, content): - blocklist = json.dumps(content) - plainfile = cli.data_dir / "plaintext" - plainfile.write_text(blocklist) - cipherfile = cli.data_dir / "ciphertext" - cli.e2ee_encrypt_to_validators(plainfile, output=cipherfile) - rsp = cli.store_blocklist(cipherfile, _from="validator") - assert rsp["code"] == 0, rsp["raw_log"] - - -def get_nonce(cli, user): - acc = cli.query_account(user)["account"]["value"] - return int(acc.get("sequence", 0)) - - -def test_block_list(cronos): - gen_validator_identity(cronos) - cli = cronos.cosmos_cli() - user = cli.address("signer2") - # set blocklist - encrypt_to_validators(cli, {"addresses": [user]}) - - # normal tx works - cli.transfer(cli.address("validator"), user, "1basetcro") - - # blocked tx can be included into mempool - rsp = cli.transfer( - user, cli.address("validator"), "1basetcro", event_query_tx=False - ) - assert rsp["code"] == 0, rsp["raw_log"] - - # but won't be included into block - txhash = rsp["txhash"] - with pytest.raises(AssertionError) as exc: - cli.event_query_tx_for(txhash) - assert "timed out waiting" in str(exc.value) - nonce = get_nonce(cli, user) - - # clear blocklist - encrypt_to_validators(cli, {}) - - # the blocked tx should be unblocked now - wait_for_new_blocks(cli, 1) - assert nonce + 1 == get_nonce(cli, user) - - -def test_block_list_evm(cronos): - gen_validator_identity(cronos) - cli = cronos.cosmos_cli() - user = cli.address("signer2") - # set blocklist - encrypt_to_validators(cli, {"addresses": [user]}) - tx = { - "from": to_checksum_address(bech32_to_eth(user)), - "to": ADDRS["community"], - "value": 1, - } - base_port = cronos.base_port(0) - wait_for_port(ports.evmrpc_ws_port(base_port)) - w3 = cronos.w3 - flt = w3.eth.filter("pending") - assert flt.get_new_entries() == [] - - txhash = w3.eth.send_transaction(tx).hex() - nonce = get_nonce(cli, user) - # check tx in mempool - assert HexBytes(txhash) in w3.eth.get_filter_changes(flt.filter_id) - - # clear blocklist - encrypt_to_validators(cli, {}) - - # the blocked tx should be unblocked now - wait_for_new_blocks(cli, 1) - assert nonce + 1 == get_nonce(cli, user) - assert w3.eth.get_filter_changes(flt.filter_id) == [] - - -def test_invalid_block_list(cronos): - cli = cronos.cosmos_cli() - cipherfile = cli.data_dir / "ciphertext" - cipherfile.write_text("{}") - with pytest.raises(AssertionError) as exc: - cli.store_blocklist(cipherfile, _from="validator") - assert "failed to read header" in str(exc.value) diff --git a/integration_tests/test_eip1559.py b/integration_tests/test_eip1559.py deleted file mode 100644 index 4d61fa86eb..0000000000 --- a/integration_tests/test_eip1559.py +++ /dev/null @@ -1,107 +0,0 @@ -import pytest - -from .utils import ADDRS, KEYS, send_transaction, w3_wait_for_block - -pytestmark = pytest.mark.gas - - -def adjust_base_fee(parent_fee, gas_limit, gas_used): - "spec: https://eips.ethereum.org/EIPS/eip-1559#specification" - change_denominator = 8 - elasticity_multiplier = 2 - gas_target = gas_limit // elasticity_multiplier - - delta = parent_fee * (gas_target - gas_used) // gas_target // change_denominator - return parent_fee - delta - - -def test_dynamic_fee_tx(cluster): - """ - test basic eip-1559 tx works: - - tx fee calculation is compliant to go-ethereum - - base fee adjustment is compliant to go-ethereum - """ - w3 = cluster.w3 - amount = 10000 - before = w3.eth.get_balance(ADDRS["community"]) - tip_price = 1 - max_price = 1000000000000 + tip_price - tx = { - "to": "0x0000000000000000000000000000000000000000", - "value": amount, - "gas": 21000, - "maxFeePerGas": max_price, - "maxPriorityFeePerGas": tip_price, - } - txreceipt = send_transaction(w3, tx, KEYS["community"]) - assert txreceipt.status == 1 - blk = w3.eth.get_block(txreceipt.blockNumber) - assert txreceipt.effectiveGasPrice == blk.baseFeePerGas + tip_price - - fee_expected = txreceipt.gasUsed * txreceipt.effectiveGasPrice - after = w3.eth.get_balance(ADDRS["community"]) - fee_deducted = before - after - amount - assert fee_deducted == fee_expected - - assert blk.gasUsed == txreceipt.gasUsed # we are the only tx in the block - - # check the next block's base fee is adjusted accordingly - w3_wait_for_block(w3, txreceipt.blockNumber + 1) - next_base_price = w3.eth.get_block(txreceipt.blockNumber + 1).baseFeePerGas - - assert next_base_price == adjust_base_fee( - blk.baseFeePerGas, blk.gasLimit, blk.gasUsed - ) - - -def test_base_fee_adjustment(cluster): - """ - verify base fee adjustment of three continuous empty blocks - """ - w3 = cluster.w3 - begin = w3.eth.block_number - w3_wait_for_block(w3, begin + 3) - - blk = w3.eth.get_block(begin) - parent_fee = blk.baseFeePerGas - - for i in range(3): - fee = w3.eth.get_block(begin + 1 + i).baseFeePerGas - assert fee == adjust_base_fee(parent_fee, blk.gasLimit, 0) - parent_fee = fee - - -def test_recommended_fee_per_gas(cluster): - """The recommended base fee per gas returned by eth_gasPrice is - base fee of the block just produced + eth_maxPriorityFeePerGas (the buffer).\n - Verify the calculation of recommended base fee per gas (eth_gasPrice) - """ - w3 = cluster.w3 - - recommended_base_fee_per_gas = w3.eth.gas_price - latest_block = w3.eth.get_block("latest") - base_fee = latest_block["baseFeePerGas"] - buffer_fee = w3.eth.max_priority_fee - - assert recommended_base_fee_per_gas == base_fee + buffer_fee, ( - f"eth_gasPrice is not the {latest_block['number']} block's " - "base fee plus eth_maxPriorityFeePerGas" - ) - - -def test_current_fee_per_gas_should_not_be_smaller_than_next_block_base_fee(cluster): - """The recommended base fee per gas returned by eth_gasPrice should - be bigger than or equal to the base fee per gas of the next block, \n - otherwise the tx does not meet the requirement to be included in the next block.\n - """ - w3 = cluster.w3 - - base_block = w3.eth.block_number - recommended_base_fee = w3.eth.gas_price - - w3_wait_for_block(w3, base_block + 1) - next_block = w3.eth.get_block(base_block + 1) - assert recommended_base_fee >= next_block["baseFeePerGas"], ( - f"recommended base fee: {recommended_base_fee} is smaller than " - f"next block {next_block['number']} base fee: {next_block['baseFeePerGas']}" - ) diff --git a/integration_tests/test_eip712.py b/integration_tests/test_eip712.py deleted file mode 100644 index bdc8917e24..0000000000 --- a/integration_tests/test_eip712.py +++ /dev/null @@ -1,82 +0,0 @@ -import base64 -import json - -import requests -from eth_account import Account -from eth_account.messages import encode_structured_data -from pystarport import ports - -from .eip712_utils import ( - create_message_send, - create_tx_raw_eip712, - signature_to_web3_extension, -) -from .utils import ADDRS, KEYS - - -def test_native_tx(cronos): - """ - test eip-712 tx works: - """ - cli = cronos.cosmos_cli() - w3 = cronos.w3 - chain_id = w3.eth.chain_id - chain = { - "chainId": chain_id, - "cosmosChainId": f"cronos_{chain_id}-1", - } - src = "community" - src_addr = cli.address(src) - src_account = cli.account(src_addr) - sender = { - "accountAddress": src_addr, - "sequence": w3.eth.get_transaction_count(ADDRS[src]), - "accountNumber": int(src_account["account"]["value"]["account_number"]), - "pubkey": json.loads(cli.address(src, "acc", "pubkey"))["key"], - } - denom = "basetcro" - dst_addr = cli.address("signer1") - gas = 200000 - gas_price = 100000000000 # default base fee - fee = { - "amount": str(gas * gas_price), - "denom": denom, - "gas": str(gas), - } - amount = "1" - params = { - "destinationAddress": dst_addr, - "amount": amount, - "denom": denom, - } - tx = create_message_send(chain, sender, fee, "", params) - structured_msg = encode_structured_data(tx["eipToSign"]) - signed = Account.sign_message(structured_msg, KEYS[src]) - extension = signature_to_web3_extension( - chain, - sender, - signed.signature, - ) - legacy_amino = tx["legacyAmino"] - signed_tx = create_tx_raw_eip712( - legacy_amino["body"], - legacy_amino["authInfo"], - extension, - ) - tx_bytes = base64.b64encode(signed_tx["message"].SerializeToString()) - body = { - "tx_bytes": tx_bytes.decode("utf-8"), - "mode": "BROADCAST_MODE_SYNC", - } - p = ports.api_port(cronos.base_port(0)) - url = f"http://127.0.0.1:{p}/cosmos/tx/v1beta1/txs" - response = requests.post(url, json=body) - if not response.ok: - raise Exception( - f"response code: {response.status_code}, " - f"{response.reason}, {response.json()}" - ) - rsp = response.json()["tx_response"] - assert rsp["code"] == 0, rsp["raw_log"] - rsp = cli.event_query_tx_for(rsp["txhash"]) - assert rsp["gas_wanted"] == str(gas) diff --git a/integration_tests/test_exported_genesis.py b/integration_tests/test_exported_genesis.py deleted file mode 100644 index b6f382747e..0000000000 --- a/integration_tests/test_exported_genesis.py +++ /dev/null @@ -1,55 +0,0 @@ -import json -from pathlib import Path - -import pytest -import requests -from pystarport import ports - -from .network import setup_custom_cronos -from .utils import ADDRS, CONTRACTS - -pytestmark = pytest.mark.slow - - -@pytest.fixture(scope="module") -def custom_cronos(tmp_path_factory): - path = tmp_path_factory.mktemp("cronos") - yield from setup_custom_cronos( - path, 26000, Path(__file__).parent / "configs/genesis_token_mapping.jsonnet" - ) - - -def test_exported_contract(custom_cronos): - "demonstrate that contract state can be deployed in genesis" - w3 = custom_cronos.w3 - abi = json.loads(CONTRACTS["TestERC20Utility"].read_text())["abi"] - erc20 = w3.eth.contract( - address="0x68542BD12B41F5D51D6282Ec7D91D7d0D78E4503", abi=abi - ) - assert erc20.caller.balanceOf(ADDRS["validator"]) == 100000000000000000000000000 - - -def test_exported_token_mapping(custom_cronos): - cli = custom_cronos.cosmos_cli(0) - port = ports.api_port(custom_cronos.base_port(0)) - for case in [ - { - "denom": "gravity0x0000000000000000000000000000000000000000", - "expected": { - "contract": "0x68542BD12B41F5D51D6282Ec7D91D7d0D78E4503", - "auto_contract": "0x68542BD12B41F5D51D6282Ec7D91D7d0D78E4503", - }, - }, - { - "denom": "ibc/6B5A664BF0AF4F71B2F0BAA33141E2F1321242FBD5D19762F541EC971ACB0865", # noqa: E501 - "expected": { - "contract": "0x0000000000000000000000000000000000000000", - "auto_contract": "", - }, - }, - ]: - denom = case["denom"] - expected = case["expected"] - assert cli.query_contract_by_denom(denom) == expected - url = f"http://127.0.0.1:{port}/cronos/v1/contract_by_denom?denom={denom}" - assert requests.get(url).json() == expected diff --git a/integration_tests/test_filters.py b/integration_tests/test_filters.py index ded6cd0482..d4ddcda00c 100644 --- a/integration_tests/test_filters.py +++ b/integration_tests/test_filters.py @@ -16,41 +16,3 @@ def test_pending_transaction_filter(cluster): receipt = send_transaction(w3, {"to": ADDRS["community"], "value": 1000}) assert receipt.status == 1 assert receipt["transactionHash"] in flt.get_new_entries() - - -def test_block_filter(cronos): - w3: Web3 = cronos.w3 - flt = w3.eth.filter("latest") - # new blocks - wait_for_new_blocks(cronos.cosmos_cli(), 1, sleep=0.1) - receipt = send_transaction(w3, {"to": ADDRS["community"], "value": 1000}) - assert receipt.status == 1 - blocks = flt.get_new_entries() - assert len(blocks) >= 1 - - -def test_event_log_filter(cronos): - w3: Web3 = cronos.w3 - mycontract = deploy_contract(w3, CONTRACTS["Greeter"]) - assert "Hello" == mycontract.caller.greet() - current_height = hex(w3.eth.get_block_number()) - event_filter = mycontract.events.ChangeGreeting.create_filter( - fromBlock=current_height - ) - - tx = mycontract.functions.setGreeting("world").build_transaction() - tx_receipt = send_transaction(w3, tx) - log = mycontract.events.ChangeGreeting().process_receipt(tx_receipt)[0] - assert log["event"] == "ChangeGreeting" - assert tx_receipt.status == 1 - new_entries = event_filter.get_new_entries() - assert len(new_entries) == 1 - print(f"get event: {new_entries}") - assert new_entries[0] == log - assert "world" == mycontract.caller.greet() - # without new txs since last call - assert event_filter.get_new_entries() == [] - assert event_filter.get_all_entries() == new_entries - # Uninstall - assert w3.eth.uninstall_filter(event_filter.filter_id) - assert not w3.eth.uninstall_filter(event_filter.filter_id) diff --git a/integration_tests/test_gov_update_params.py b/integration_tests/test_gov_update_params.py deleted file mode 100644 index 3aee62df7c..0000000000 --- a/integration_tests/test_gov_update_params.py +++ /dev/null @@ -1,65 +0,0 @@ -import pytest - -from .cosmoscli import module_address -from .utils import CONTRACTS, deploy_contract, submit_gov_proposal - -pytestmark = pytest.mark.gov - - -def test_evm_update_param(cronos, tmp_path): - contract = deploy_contract( - cronos.w3, - CONTRACTS["Random"], - ) - res = contract.caller.randomTokenId() - assert res > 0, res - cli = cronos.cosmos_cli() - p = cli.query_params("evm") - del p["chain_config"]["merge_netsplit_block"] - del p["chain_config"]["shanghai_time"] - authority = module_address("gov") - submit_gov_proposal( - cronos, - tmp_path, - messages=[ - { - "@type": "/ethermint.evm.v1.MsgUpdateParams", - "authority": authority, - "params": p, - } - ], - ) - p = cli.query_params("evm") - assert not p["chain_config"]["merge_netsplit_block"] - assert not p["chain_config"]["shanghai_time"] - invalid_msg = "invalid opcode: PUSH0" - with pytest.raises(ValueError) as e_info: - contract.caller.randomTokenId() - assert invalid_msg in str(e_info.value) - with pytest.raises(ValueError) as e_info: - deploy_contract(cronos.w3, CONTRACTS["Greeter"]) - assert invalid_msg in str(e_info.value) - - -def test_gov_update_params(cronos, tmp_path): - params = { - "cronos_admin": "crc12luku6uxehhak02py4rcz65zu0swh7wjsrw0pp", - "enable_auto_deployment": False, - "ibc_cro_denom": "ibc/6411AE2ADA1E73DB59DB151" - "A8988F9B7D5E7E233D8414DB6817F8F1A01600000", - "ibc_timeout": "96400000000000", - "max_callback_gas": "400000", - } - authority = module_address("gov") - submit_gov_proposal( - cronos, - tmp_path, - messages=[ - { - "@type": "/cronos.MsgUpdateParams", - "authority": authority, - "params": params, - } - ], - ) - assert cronos.cosmos_cli().query_params() == params diff --git a/integration_tests/test_gravity.py b/integration_tests/test_gravity.py deleted file mode 100644 index 98772bc83a..0000000000 --- a/integration_tests/test_gravity.py +++ /dev/null @@ -1,683 +0,0 @@ -import json - -import pytest -import requests -from eth_account.account import Account -from eth_utils import abi -from hexbytes import HexBytes -from pystarport import ports -from web3.exceptions import BadFunctionCallOutput - -from .gravity_utils import prepare_gravity, setup_cosmos_erc20_contract -from .network import setup_cronos, setup_geth -from .utils import ( - ACCOUNTS, - ADDRS, - CONTRACTS, - KEYS, - approve_proposal, - deploy_contract, - eth_to_bech32, - multiple_send_to_cosmos, - send_to_cosmos, - send_transaction, - setup_token_mapping, - w3_wait_for_new_blocks, - wait_for_fn, - wait_for_new_blocks, -) - -pytestmark = pytest.mark.gravity - -# skip gravity-bridge integration tests since it's not enabled by default. -pytest.skip("skipping gravity-bridge tests", allow_module_level=True) - -Account.enable_unaudited_hdwallet_features() - - -def cronos_crc21_abi(): - path = CONTRACTS["ModuleCRC21"] - return json.load(path.open())["abi"] - - -def check_auto_deployment(cli, denom, cronos_w3, recipient, amount): - "check crc21 contract auto deployed, and the crc21 balance" - try: - rsp = cli.query_contract_by_denom(denom) - except AssertionError: - # not deployed yet - return None - assert len(rsp["auto_contract"]) > 0 - crc21_contract = cronos_w3.eth.contract( - address=rsp["auto_contract"], abi=cronos_crc21_abi() - ) - try: - if crc21_contract.caller.balanceOf(recipient) == amount: - return crc21_contract - except BadFunctionCallOutput: - # there's a chance the contract is not ready for call, - # maybe due to inconsistency between different rpc services. - return None - return None - - -def get_id_from_receipt(receipt): - "check the id after sendToEvmChain call" - target = HexBytes( - abi.event_signature_to_log_topic("__CronosSendToEvmChainResponse(uint256)") - ) - for _, log in enumerate(receipt.logs): - if log.topics[0] == target: - return log.data - res = "0x0000000000000000000000000000000000000000000000000000000000000000" - return HexBytes(res) - - -@pytest.fixture(scope="module") -def custom_geth(tmp_path_factory): - yield from setup_geth(tmp_path_factory.mktemp("geth"), 8555) - - -@pytest.fixture(scope="module", params=[True, False]) -def custom_cronos(request, tmp_path_factory): - yield from setup_cronos(tmp_path_factory.mktemp("cronos"), 26600, request.param) - - -@pytest.fixture(scope="module") -def gravity(custom_cronos, custom_geth): - yield from prepare_gravity(custom_cronos, custom_geth) - - -def test_gravity_transfer(gravity): - geth = gravity.geth - cli = gravity.cronos.cosmos_cli() - cronos_w3 = gravity.cronos.w3 - - # deploy test erc20 contract - erc20 = deploy_contract( - geth, - CONTRACTS["TestERC20A"], - ) - - balance = erc20.caller.balanceOf(ADDRS["validator"]) - assert balance == 100000000000000000000000000 - amount = 1000 - - print("send to cronos crc20") - recipient = HexBytes(ADDRS["community"]) - txreceipt = send_to_cosmos( - gravity.contract, erc20, geth, recipient, amount, KEYS["validator"] - ) - assert txreceipt.status == 1, "should success" - assert erc20.caller.balanceOf(ADDRS["validator"]) == balance - amount - - denom = f"gravity{erc20.address}" - - def check_gravity_native_tokens(): - "check the balance of gravity native token" - return cli.balance(eth_to_bech32(recipient), denom=denom) == amount - - if gravity.cronos.enable_auto_deployment: - crc21_contract = None - - def local_check_auto_deployment(): - nonlocal crc21_contract - crc21_contract = check_auto_deployment( - cli, denom, cronos_w3, recipient, amount - ) - return crc21_contract - - wait_for_fn("send-to-crc21", local_check_auto_deployment) - - # send it back to erc20 - tx = crc21_contract.functions.send_to_evm_chain( - ADDRS["validator"], amount, 1, 0, b"" - ).build_transaction({"from": ADDRS["community"]}) - txreceipt = send_transaction(cronos_w3, tx, KEYS["community"]) - # CRC20 emit 3 logs for send_to_evm_chain: - # burn - # __CronosSendToEvmChain - # __CronosSendToEvmChainResponse - assert len(txreceipt.logs) == 3 - data = "0x0000000000000000000000000000000000000000000000000000000000000001" - match = get_id_from_receipt(txreceipt) == HexBytes(data) - assert match, "should be able to get id" - assert txreceipt.status == 1, "should success" - else: - wait_for_fn("send-to-gravity-native", check_gravity_native_tokens) - # send back the gravity native tokens - rsp = cli.send_to_ethereum( - ADDRS["validator"], f"{amount}{denom}", f"0{denom}", from_="community" - ) - assert rsp["code"] == 0, rsp["raw_log"] - - def check(): - v = erc20.caller.balanceOf(ADDRS["validator"]) - return v == balance - - wait_for_fn("send-to-ethereum", check) - - -def test_multiple_attestation_processing(gravity): - if not gravity.cronos.enable_auto_deployment: - geth = gravity.geth - cli = gravity.cronos.cosmos_cli() - - # deploy test erc20 contract - erc20 = deploy_contract( - geth, - CONTRACTS["TestERC20A"], - ) - - balance = erc20.caller.balanceOf(ADDRS["validator"]) - assert balance == 100000000000000000000000000 - - amount = 10 - # Send some eth and erc20 to all accounts - print("fund all accounts") - for name in ACCOUNTS: - address = ACCOUNTS[name].address - data = {"to": address, "value": 10**17} - send_transaction(geth, data, KEYS["validator"]) - tx = erc20.functions.transfer(address, amount).build_transaction( - {"from": ADDRS["validator"]} - ) - tx_receipt = send_transaction(geth, tx, KEYS["validator"]) - assert tx_receipt.status == 1, "should success" - - print("generate multiple send to cosmos") - recipient = HexBytes(ADDRS["community"]) - - denom = f"gravity{erc20.address}" - previous = cli.balance(eth_to_bech32(recipient), denom=denom) - height_to_check = cli.block_height() - - multiple_send_to_cosmos( - gravity.contract, erc20, geth, recipient, amount, KEYS.values() - ) - - def check_gravity_balance(): - """ - check the all attestation are processed at once by comparing - with previous block balance - """ - nonlocal previous - nonlocal height_to_check - current = cli.balance( - eth_to_bech32(recipient), denom=denom, height=height_to_check - ) - check = current == previous + (10 * len(ACCOUNTS)) - previous = current - height_to_check = height_to_check + 1 - return check - - # we are checking the difference of balance for each height to ensure - # attestation are processed within the same block - wait_for_fn( - "send-to-gravity-native", check_gravity_balance, timeout=600, interval=2 - ) - - -def submit_proposal(cli, tmp_path, is_legacy, denom, conctract): - if is_legacy: - return cli.gov_propose_token_mapping_change_legacy( - denom, conctract, "", 0, from_="community", deposit="1basetcro" - ) - proposal = tmp_path / "proposal.json" - # governance module account as signer - signer = "crc10d07y265gmmuvt4z0w9aw880jnsr700jdufnyd" - proposal_src = { - "messages": [ - { - "@type": "/cosmos.gov.v1.MsgExecLegacyContent", - "content": { - "@type": "/cronos.TokenMappingChangeProposal", - "denom": denom, - "contract": conctract, - "symbol": "", - "decimal": 0, - }, - "authority": signer, - } - ], - "deposit": "1basetcro", - "title": "title", - "summary": "summary", - } - proposal.write_text(json.dumps(proposal_src)) - return cli.submit_gov_proposal(proposal, from_="community") - - -@pytest.mark.parametrize("is_legacy", [True, False]) -def test_gov_token_mapping(gravity, tmp_path, is_legacy): - """ - Test adding a token mapping through gov module - - deploy test erc20 contract on geth - - deploy corresponding contract on cronos - - add the token mapping on cronos using gov module - - do a gravity transfer, check the balances - """ - geth = gravity.geth - cli = gravity.cronos.cosmos_cli() - cronos_w3 = gravity.cronos.w3 - - # deploy test erc20 contract - erc20 = deploy_contract( - geth, - CONTRACTS["TestERC20A"], - ) - print("erc20 contract", erc20.address) - crc21 = deploy_contract( - cronos_w3, - CONTRACTS["TestERC20Utility"], - ) - print("crc21 contract", crc21.address) - denom = f"gravity{erc20.address}" - - print("check the contract mapping not exists yet") - with pytest.raises(AssertionError): - cli.query_contract_by_denom(denom) - - rsp = submit_proposal(cli, tmp_path, is_legacy, denom, crc21.address) - assert rsp["code"] == 0, rsp["raw_log"] - - approve_proposal(gravity.cronos, rsp["events"]) - - print("check the contract mapping exists now") - rsp = cli.query_contract_by_denom(denom) - print("contract", rsp) - assert rsp["contract"] == crc21.address - - print("try to send token from ethereum to cronos") - txreceipt = send_to_cosmos( - gravity.contract, erc20, geth, ADDRS["community"], 10, KEYS["validator"] - ) - assert txreceipt.status == 1 - - def check(): - balance = crc21.caller.balanceOf(ADDRS["community"]) - print("crc20 balance", balance) - return balance == 10 - - wait_for_fn("check balance on cronos", check) - - # check duplicate end_block_events - height = cli.block_height() - port = ports.rpc_port(gravity.cronos.base_port(0)) - url = f"http://127.0.0.1:{port}/block_results?height={height}" - res = requests.get(url).json().get("result") - if res: - events = res["end_block_events"] - target = "ethereum_send_to_cosmos_handled" - count = sum(1 for evt in events if evt["type"] == target) - assert count <= 2, f"duplicate {target}" - - -def test_direct_token_mapping(gravity): - """ - Test adding a token mapping directly - - deploy test erc20 contract on geth - - deploy corresponding contract on cronos - - add the token mapping on cronos using gov module - - do a gravity transfer, check the balances - """ - geth = gravity.geth - cli = gravity.cronos.cosmos_cli() - cronos_w3 = gravity.cronos.w3 - - # deploy test erc20 contract - erc20 = deploy_contract( - geth, - CONTRACTS["TestERC20A"], - ) - print("erc20 contract", erc20.address) - crc21 = deploy_contract( - cronos_w3, - CONTRACTS["TestERC20Utility"], - ) - print("crc21 contract", crc21.address) - denom = f"gravity{erc20.address}" - - print("check the contract mapping not exists yet") - with pytest.raises(AssertionError): - cli.query_contract_by_denom(denom) - - rsp = cli.update_token_mapping(denom, crc21.address, "", 0, from_="community") - assert rsp["code"] != 0, "should not have the permission" - - rsp = cli.update_token_mapping(denom, crc21.address, "", 0, from_="validator") - assert rsp["code"] == 0, rsp["raw_log"] - wait_for_new_blocks(cli, 1) - - print("check the contract mapping exists now") - rsp = cli.query_contract_by_denom(denom) - print("contract", rsp) - assert rsp["contract"] == crc21.address - - print("try to send token from ethereum to cronos") - txreceipt = send_to_cosmos( - gravity.contract, erc20, geth, ADDRS["community"], 10, KEYS["validator"] - ) - assert txreceipt.status == 1 - - def check(): - balance = crc21.caller.balanceOf(ADDRS["community"]) - print("crc20 balance", balance) - return balance == 10 - - wait_for_fn("check balance on cronos", check) - - -def test_gravity_cancel_transfer(gravity): - if gravity.cronos.enable_auto_deployment: - geth = gravity.geth - cli = gravity.cronos.cosmos_cli() - cronos_w3 = gravity.cronos.w3 - - # deploy test erc20 contract - erc20 = deploy_contract( - geth, - CONTRACTS["TestERC20A"], - ) - - # deploy gravity cancellation contract - cancel_contract = deploy_contract( - cronos_w3, - CONTRACTS["CronosGravityCancellation"], - ) - - balance = erc20.caller.balanceOf(ADDRS["validator"]) - assert balance == 100000000000000000000000000 - amount = 1000 - - print("send to cronos crc21") - community = HexBytes(ADDRS["community"]) - key = KEYS["validator"] - send_to_cosmos(gravity.contract, erc20, geth, community, amount, key) - assert erc20.caller.balanceOf(ADDRS["validator"]) == balance - amount - - denom = f"gravity{erc20.address}" - crc21_contract = None - - def local_check_auto_deployment(): - nonlocal crc21_contract - crc21_contract = check_auto_deployment( - cli, denom, cronos_w3, community, amount - ) - return crc21_contract - - wait_for_fn("send-to-crc21", local_check_auto_deployment) - - # batch are created every 10 blocks, wait til block number reaches - # a multiple of 10 to lower the chance to have the transaction include - # in the batch right away - current_block = cronos_w3.eth.get_block_number() - print("current_block: ", current_block) - batch_block = 10 - diff_block = batch_block - current_block % batch_block - wait_for_new_blocks(cli, diff_block) - - # send it back to erc20 - tx = crc21_contract.functions.send_to_evm_chain( - ADDRS["validator"], amount, 1, 0, b"" - ).build_transaction({"from": community}) - txreceipt = send_transaction(cronos_w3, tx, KEYS["community"]) - # CRC20 emit 3 logs for send_to_evm_chain: - # burn - # __CronosSendToEvmChain - # __CronosSendToEvmChainResponse - assert len(txreceipt.logs) == 3 - tx_id = get_id_from_receipt(txreceipt) - assert txreceipt.status == 1, "should success" - - # Check_deduction - balance_after_send = crc21_contract.caller.balanceOf(community) - assert balance_after_send == 0 - - # Cancel the send_to_evm_chain from another contract - canceltx = cancel_contract.functions.cancelTransaction( - int.from_bytes(tx_id, "big") - ).build_transaction({"from": community}) - canceltxreceipt = send_transaction(cronos_w3, canceltx, KEYS["community"]) - # Should fail because it was not called from the CRC21 contract - assert canceltxreceipt.status == 0, "should fail" - - canceltx = crc21_contract.functions.cancel_send_to_evm_chain( - int.from_bytes(tx_id, "big") - ).build_transaction({"from": community}) - canceltxreceipt = send_transaction(cronos_w3, canceltx, KEYS["community"]) - assert canceltxreceipt.status == 1, "should success" - - def check_refund(): - v = crc21_contract.caller.balanceOf(community) - return v == amount - - wait_for_fn("cancel-send-to-ethereum", check_refund) - - -def test_gravity_source_tokens(gravity): - if not gravity.cronos.enable_auto_deployment: - # deploy contracts - w3 = gravity.cronos.w3 - symbol = "DOG" - contract, denom = setup_token_mapping(gravity.cronos, "TestERC21Source", symbol) - cosmos_erc20_contract = setup_cosmos_erc20_contract( - gravity, - denom, - symbol, - ) - # Send token to ethereum - amount = 1000 - ethereum_receiver = ADDRS["validator"] - balance_before_send_to_ethereum = cosmos_erc20_contract.caller.balanceOf( - ethereum_receiver - ) - - print("send to ethereum") - tx = contract.functions.send_to_evm_chain( - ethereum_receiver, amount, 1, 0, b"" - ).build_transaction({"from": ADDRS["validator"]}) - txreceipt = send_transaction(w3, tx) - assert txreceipt.status == 1, "should success" - - balance_after_send_to_ethereum = balance_before_send_to_ethereum - - def check_ethereum_balance_change(): - nonlocal balance_after_send_to_ethereum - balance_after_send_to_ethereum = cosmos_erc20_contract.caller.balanceOf( - ethereum_receiver - ) - return balance_before_send_to_ethereum != balance_after_send_to_ethereum - - wait_for_fn("check ethereum balance change", check_ethereum_balance_change) - assert ( - balance_after_send_to_ethereum == balance_before_send_to_ethereum + amount - ) - - # Send back token to cronos - cronos_receiver = "0x0000000000000000000000000000000000000001" - balance_before_send_to_cosmos = contract.caller.balanceOf(cronos_receiver) - amount = 15 - txreceipt = send_to_cosmos( - gravity.contract, - cosmos_erc20_contract, - gravity.geth, - HexBytes(cronos_receiver), - amount, - KEYS["validator"], - ) - assert txreceipt.status == 1, "should success" - - balance_after_send_to_cosmos = balance_before_send_to_cosmos - - def check_cronos_balance_change(): - nonlocal balance_after_send_to_cosmos - balance_after_send_to_cosmos = contract.caller.balanceOf(cronos_receiver) - return balance_before_send_to_cosmos != balance_after_send_to_cosmos - - wait_for_fn("check cronos balance change", check_cronos_balance_change) - assert balance_after_send_to_cosmos == balance_before_send_to_cosmos + amount - - -def test_gravity_blacklisted_contract(gravity): - if gravity.cronos.enable_auto_deployment: - geth = gravity.geth - cli = gravity.cronos.cosmos_cli() - cronos_w3 = gravity.cronos.w3 - - # deploy test blacklisted contract with signer1 as blacklisted - erc20 = deploy_contract( - geth, - CONTRACTS["TestBlackListERC20"], - (ADDRS["signer1"],), - ) - - balance = erc20.caller.balanceOf(ADDRS["validator"]) - assert balance == 100000000000000000000000000 - amount = 1000 - - print("send to cronos crc20") - recipient = HexBytes(ADDRS["community"]) - txreceipt = send_to_cosmos( - gravity.contract, erc20, geth, recipient, amount, KEYS["validator"] - ) - assert txreceipt.status == 1, "should success" - assert erc20.caller.balanceOf(ADDRS["validator"]) == balance - amount - - denom = f"gravity{erc20.address}" - crc21_contract = None - - def local_check_auto_deployment(): - nonlocal crc21_contract - crc21_contract = check_auto_deployment( - cli, denom, cronos_w3, recipient, amount - ) - return crc21_contract - - wait_for_fn("send-to-crc21", local_check_auto_deployment) - - # get voucher nonce - old_nonce = gravity.contract.caller.state_lastRevertedNonce() - old_balance1 = erc20.caller.balanceOf(ADDRS["signer1"]) - - # send it back to blacklisted address - tx = crc21_contract.functions.send_to_evm_chain( - ADDRS["signer1"], amount, 1, 0, b"" - ).build_transaction({"from": ADDRS["community"]}) - txreceipt = send_transaction(cronos_w3, tx, KEYS["community"]) - assert txreceipt.status == 1, "should success" - - def check(): - nonce = gravity.contract.caller.state_lastRevertedNonce() - return old_nonce + 1 == nonce - - wait_for_fn("send-to-ethereum", check) - - # check that voucher has been created - voucher = gravity.contract.caller.state_RevertedVouchers(old_nonce) - assert voucher[0] == erc20.address - assert voucher[1] == ADDRS["signer1"] - assert voucher[2] == amount - - # check balance is the same - new_balance1 = erc20.caller.balanceOf(ADDRS["signer1"]) - assert old_balance1 == new_balance1 - - old_balance2 = erc20.caller.balanceOf(ADDRS["signer2"]) - - # try to redeem voucher with non recipient address - with pytest.raises(Exception): - gravity.contract.functions.redeemVoucher( - old_nonce, ADDRS["signer2"] - ).build_transaction({"from": ADDRS["validator"]}) - - # send user1 some fund for gas - send_transaction( - geth, {"to": ADDRS["signer1"], "value": 10**17}, KEYS["validator"] - ) - # redeem voucher - tx = gravity.contract.functions.redeemVoucher( - old_nonce, ADDRS["signer2"] - ).build_transaction({"from": ADDRS["signer1"]}) - txreceipt = send_transaction(geth, tx, KEYS["signer1"]) - assert txreceipt.status == 1, "should success" - w3_wait_for_new_blocks(geth, 1) - new_balance2 = erc20.caller.balanceOf(ADDRS["signer2"]) - assert old_balance2 + amount == new_balance2 - - # asset cannot redeem twice - with pytest.raises(Exception): - gravity.contract.functions.redeemVoucher( - old_nonce, ADDRS["signer2"] - ).build_transaction({"from": ADDRS["signer1"]}) - - -def test_gravity_turn_bridge(gravity): - geth = gravity.geth - cli = gravity.cronos.cosmos_cli() - cronos_w3 = gravity.cronos.w3 - - # deploy test erc20 contract - erc20 = deploy_contract( - geth, - CONTRACTS["TestERC20A"], - ) - - balance = erc20.caller.balanceOf(ADDRS["validator"]) - assert balance == 100000000000000000000000000 - amount = 1000 - - print("send to cronos crc20") - recipient = HexBytes(ADDRS["community"]) - txreceipt = send_to_cosmos( - gravity.contract, erc20, geth, recipient, amount, KEYS["validator"] - ) - assert txreceipt.status == 1, "should success" - assert erc20.caller.balanceOf(ADDRS["validator"]) == balance - amount - - denom = f"gravity{erc20.address}" - - def check_gravity_native_tokens(): - "check the balance of gravity native token" - return cli.balance(eth_to_bech32(recipient), denom=denom) == amount - - if gravity.cronos.enable_auto_deployment: - crc21_contract = None - - def local_check_auto_deployment(): - nonlocal crc21_contract - crc21_contract = check_auto_deployment( - cli, denom, cronos_w3, recipient, amount - ) - return crc21_contract - - wait_for_fn("send-to-crc21", local_check_auto_deployment) - else: - wait_for_fn("send-to-gravity-native", check_gravity_native_tokens) - - # turn off bridge - rsp = cli.turn_bridge("false", from_="community") - assert rsp["code"] != 0, "should not have the permission" - - rsp = cli.turn_bridge("false", from_="validator") - assert rsp["code"] == 0, rsp["raw_log"] - wait_for_new_blocks(cli, 1) - - if gravity.cronos.enable_auto_deployment: - # send it back to erc20, should fail - tx = crc21_contract.functions.send_to_evm_chain( - ADDRS["validator"], amount, 1, 0, b"" - ).build_transaction({"from": ADDRS["community"]}) - txreceipt = send_transaction(cronos_w3, tx, KEYS["community"]) - assert txreceipt.status == 0, "should fail" - else: - # send back the gravity native tokens, should fail - rsp = cli.send_to_ethereum( - ADDRS["validator"], f"{amount}{denom}", f"0{denom}", from_="community" - ) - assert rsp["code"] == 3, rsp["raw_log"] - - wait_for_new_blocks(cli, 10) - # check no new batch is created - rsp = cli.query_batches() - assert len(rsp["batches"]) == 0 diff --git a/integration_tests/test_gravity_2.py b/integration_tests/test_gravity_2.py deleted file mode 100644 index fa682bb33f..0000000000 --- a/integration_tests/test_gravity_2.py +++ /dev/null @@ -1,422 +0,0 @@ -import pytest -from eth_account.account import Account -from hexbytes import HexBytes - -from .gravity_utils import prepare_gravity, setup_cosmos_erc20_contract -from .network import setup_cronos, setup_geth -from .utils import ( - ADDRS, - CONTRACTS, - KEYS, - deploy_contract, - deploy_erc20, - eth_to_bech32, - send_to_cosmos, - send_transaction, - setup_token_mapping, - wait_for_fn, - wait_for_new_blocks, -) - -pytestmark = pytest.mark.gravity - -# skip gravity-bridge integration tests since it's not enabled by default. -pytest.skip("skipping gravity-bridge tests", allow_module_level=True) - -Account.enable_unaudited_hdwallet_features() - - -@pytest.fixture(scope="module") -def custom_geth(tmp_path_factory): - yield from setup_geth(tmp_path_factory.mktemp("geth"), 8555) - - -@pytest.fixture(scope="module", params=[True, False]) -def custom_cronos(request, tmp_path_factory): - yield from setup_cronos(tmp_path_factory.mktemp("cronos"), 26600, request.param) - - -@pytest.fixture(scope="module") -def gravity(custom_cronos, custom_geth): - yield from prepare_gravity(custom_cronos, custom_geth) - - -def test_gravity_proxy_contract(gravity): - if not gravity.cronos.enable_auto_deployment: - geth = gravity.geth - - # deploy test erc20 contract - erc20 = deploy_contract( - geth, - CONTRACTS["TestERC20A"], - ) - balance = erc20.caller.balanceOf(ADDRS["validator"]) - assert balance == 100000000000000000000000000 - - denom = f"gravity{erc20.address}" - - # deploy crc20 contract - w3 = gravity.cronos.w3 - crc20 = deploy_contract(w3, CONTRACTS["TestCRC20"]) - - print("crc20 contract deployed at address: ", crc20.address) - - # setup the contract mapping - cronos_cli = gravity.cronos.cosmos_cli() - - print("check the contract mapping not exists yet") - with pytest.raises(AssertionError): - cronos_cli.query_contract_by_denom(denom) - - rsp = cronos_cli.update_token_mapping( - denom, crc20.address, "TEST", 18, from_="validator" - ) - assert rsp["code"] == 0, rsp["raw_log"] - wait_for_new_blocks(cronos_cli, 1) - - print("check the contract mapping exists now") - rsp = cronos_cli.query_denom_by_contract(crc20.address) - assert rsp["denom"] == denom - - # Send some tokens - print("send to cronos crc20") - amount = 1000 - recipient = HexBytes(ADDRS["community"]) - txreceipt = send_to_cosmos( - gravity.contract, erc20, geth, recipient, amount, KEYS["validator"] - ) - assert txreceipt.status == 1, "should success" - assert erc20.caller.balanceOf(ADDRS["validator"]) == balance - amount - - def check_gravity_tokens(): - "check the balance of gravity native token" - return crc20.caller.balanceOf(ADDRS["community"]) == amount - - wait_for_fn("check_gravity_tokens", check_gravity_tokens) - - # deploy crc20 proxy contract - proxycrc20 = deploy_contract( - w3, - CONTRACTS["TestCRC20Proxy"], - (crc20.address, False), - ) - - print("proxycrc20 contract deployed at address: ", proxycrc20.address) - assert not proxycrc20.caller.is_source() - assert proxycrc20.caller.crc20() == crc20.address - - # change token mapping - rsp = cronos_cli.update_token_mapping( - denom, proxycrc20.address, "DOG", 18, from_="validator" - ) - assert rsp["code"] == 0, rsp["raw_log"] - wait_for_new_blocks(cronos_cli, 1) - - print("check the contract mapping exists now") - rsp = cronos_cli.query_denom_by_contract(proxycrc20.address) - assert rsp["denom"] == denom - - # Fund the proxy contract cosmos account with original supply - # by sending tokens to dead address - # (because mint to zero address is forbidden in ERC20 contract) - print("restore original supply crc20 by sending token to dead address") - amount = 1000 - balance = erc20.caller.balanceOf(ADDRS["validator"]) - dead_address = "0x000000000000000000000000000000000000dEaD" - cosmos_dead_address = HexBytes(dead_address) - txreceipt = send_to_cosmos( - gravity.contract, - erc20, - geth, - cosmos_dead_address, - amount, - KEYS["validator"], - ) - assert txreceipt.status == 1, "should success" - assert erc20.caller.balanceOf(ADDRS["validator"]) == balance - amount - - def check_dead_gravity_tokens(): - "check the balance of gravity token" - return crc20.caller.balanceOf(dead_address) == amount - - wait_for_fn("check_dead_gravity_tokens", check_dead_gravity_tokens) - - # Try to send back token to ethereum - amount = 500 - ethereum_receiver = ADDRS["validator2"] - # community_balance_before_send = crc20.caller.balanceOf(community) - balance_before_send_to_ethereum = erc20.caller.balanceOf(ethereum_receiver) - - print("send to ethereum") - # First we need to approve the proxy contract to move asset - tx = crc20.functions.approve(proxycrc20.address, amount).build_transaction( - {"from": ADDRS["community"]} - ) - txreceipt = send_transaction(w3, tx, key=KEYS["community"]) - assert txreceipt.status == 1, "should success" - assert crc20.caller.allowance(ADDRS["community"], proxycrc20.address) == amount - - # Then trigger the send to evm chain - sender = ADDRS["community"] - community_balance_before_send = crc20.caller.balanceOf(sender) - print( - "sender address : ", - ) - tx2 = proxycrc20.functions.send_to_evm_chain( - ethereum_receiver, amount, 1, 0, b"" - ).build_transaction({"from": ADDRS["community"]}) - txreceipt2 = send_transaction(w3, tx2, key=KEYS["community"]) - print("receipt : ", txreceipt2) - assert txreceipt2.status == 1, "should success" - # Check deduction - assert crc20.caller.balanceOf(sender) == community_balance_before_send - amount - - balance_after_send_to_ethereum = balance_before_send_to_ethereum - - def check_ethereum_balance_change(): - nonlocal balance_after_send_to_ethereum - balance_after_send_to_ethereum = erc20.caller.balanceOf(ethereum_receiver) - print("balance dead address", crc20.caller.balanceOf(dead_address)) - return balance_before_send_to_ethereum != balance_after_send_to_ethereum - - wait_for_fn( - "ethereum balance change", check_ethereum_balance_change, timeout=60 - ) - assert ( - balance_after_send_to_ethereum == balance_before_send_to_ethereum + amount - ) - - -def test_gravity_proxy_contract_source_token(gravity): - if not gravity.cronos.enable_auto_deployment: - # deploy contracts - w3 = gravity.cronos.w3 - symbol = "TEST" - contract, denom = setup_token_mapping(gravity.cronos, "TestCRC20", symbol) - cosmos_erc20_contract = setup_cosmos_erc20_contract( - gravity, - denom, - symbol, - ) - # setup the contract mapping - cronos_cli = gravity.cronos.cosmos_cli() - - # deploy crc20 proxy contract - proxycrc20 = deploy_contract( - w3, - CONTRACTS["TestCRC20Proxy"], - (contract.address, True), - ) - - print("proxycrc20 contract deployed at address: ", proxycrc20.address) - assert proxycrc20.caller.is_source() - assert proxycrc20.caller.crc20() == contract.address - - # change token mapping - rsp = cronos_cli.update_token_mapping( - denom, proxycrc20.address, symbol, 6, from_="validator" - ) - assert rsp["code"] == 0, rsp["raw_log"] - wait_for_new_blocks(cronos_cli, 1) - - print("check the contract mapping exists now") - rsp = cronos_cli.query_denom_by_contract(proxycrc20.address) - assert rsp["denom"] == denom - - # Try to send token to ethereum - amount = 500 - ethereum_receiver = ADDRS["validator"] - sender = ADDRS["validator"] - # community_balance_before_send = crc20.caller.balanceOf(community) - balance_before_send_to_ethereum = cosmos_erc20_contract.caller.balanceOf( - ethereum_receiver - ) - - print("send to ethereum") - # First we need to approve the proxy contract to move asset - tx = contract.functions.approve(proxycrc20.address, amount).build_transaction( - {"from": sender} - ) - txreceipt = send_transaction(w3, tx, key=KEYS["validator"]) - assert txreceipt.status == 1, "should success" - assert ( - contract.caller.allowance(ADDRS["validator"], proxycrc20.address) == amount - ) - - # Then trigger the send to evm chain - community_balance_before_send = contract.caller.balanceOf(sender) - tx2 = proxycrc20.functions.send_to_evm_chain( - ethereum_receiver, amount, 1, 0, b"" - ).build_transaction({"from": sender}) - txreceipt2 = send_transaction(w3, tx2, key=KEYS["validator"]) - print("receipt : ", txreceipt2) - assert txreceipt2.status == 1, "should success" - # Check deduction - assert ( - contract.caller.balanceOf(sender) == community_balance_before_send - amount - ) - - balance_after_send_to_ethereum = balance_before_send_to_ethereum - - def check_ethereum_balance_change(): - nonlocal balance_after_send_to_ethereum - balance_after_send_to_ethereum = cosmos_erc20_contract.caller.balanceOf( - ethereum_receiver - ) - return balance_before_send_to_ethereum != balance_after_send_to_ethereum - - wait_for_fn( - "ethereum balance change", check_ethereum_balance_change, timeout=60 - ) - assert ( - balance_after_send_to_ethereum == balance_before_send_to_ethereum + amount - ) - - # Send back token to cronos - cronos_receiver = ADDRS["community"] - balance_before_send_to_cosmos = contract.caller.balanceOf(cronos_receiver) - amount = 15 - txreceipt = send_to_cosmos( - gravity.contract, - cosmos_erc20_contract, - gravity.geth, - HexBytes(cronos_receiver), - amount, - KEYS["validator"], - ) - assert txreceipt.status == 1, "should success" - - balance_after_send_to_cosmos = balance_before_send_to_cosmos - - def check_cronos_balance_change(): - nonlocal balance_after_send_to_cosmos - balance_after_send_to_cosmos = contract.caller.balanceOf(cronos_receiver) - return balance_before_send_to_cosmos != balance_after_send_to_cosmos - - wait_for_fn("check cronos balance change", check_cronos_balance_change) - assert balance_after_send_to_cosmos == balance_before_send_to_cosmos + amount - - -def test_gravity_detect_malicious_supply(gravity): - if not gravity.cronos.enable_auto_deployment: - geth = gravity.geth - cli = gravity.cronos.cosmos_cli() - - # deploy fake contract to trigger the malicious supply - # any transfer made with this contract will send an amount of token - # equal to max uint256 - erc20 = deploy_contract( - geth, - CONTRACTS["TestMaliciousSupply"], - ) - denom = f"gravity{erc20.address}" - print(denom) - - # check that the bridge is activated - activate = cli.query_gravity_params()["bridge_active"] - assert activate is True - - max_int = 2**256 - 1 - print("send max_int to community address using gravity bridge") - recipient = HexBytes(ADDRS["community"]) - txreceipt = send_to_cosmos( - gravity.contract, erc20, geth, recipient, max_int, KEYS["validator"] - ) - assert txreceipt.status == 1, "should success" - - # check that amount has been received - def check_gravity_native_tokens(): - "check the balance of gravity native token" - return cli.balance(eth_to_bech32(recipient), denom=denom) == max_int - - wait_for_fn("balance", check_gravity_native_tokens) - - # check that the bridge is still activated - activate = cli.query_gravity_params()["bridge_active"] - assert activate is True - - # need a random transferFrom to increment the counter in the contract - # (see logic) to be able to redo a max uint256 transfer - print("do a random send to increase contract nonce") - txtransfer = erc20.functions.transferFrom( - ADDRS["validator"], ADDRS["validator2"], 1 - ).build_transaction({"from": ADDRS["validator"]}) - txreceipt = send_transaction(geth, txtransfer, KEYS["validator"]) - assert txreceipt.status == 1, "should success" - - print("send again max_int to community address using gravity bridge") - txreceipt = send_to_cosmos( - gravity.contract, erc20, geth, recipient, max_int, KEYS["validator"] - ) - assert txreceipt.status == 1, "should success" - - # Wait enough for orchestrator to relay the event - wait_for_new_blocks(cli, 30) - - # check that the bridge has not been deactivated - activate = cli.query_gravity_params()["bridge_active"] - assert activate is True - - # check that balance is still same - assert cli.balance(eth_to_bech32(recipient), denom=denom) == max_int - - -def test_gravity_non_cosmos_denom(gravity): - if gravity.cronos.enable_auto_deployment: - return - - cronos_cli = gravity.cronos.cosmos_cli() - # deploy test erc20 contract - erc20 = deploy_contract( - gravity.geth, - CONTRACTS["TestERC20A"], - ) - print("send to cronos crc20") - recipient = HexBytes(ADDRS["community"]) - balance = erc20.caller.balanceOf(ADDRS["validator"]) - assert balance == 100000000000000000000000000 - amount = 100 - txreceipt = send_to_cosmos( - gravity.contract, erc20, gravity.geth, recipient, amount, KEYS["validator"] - ) - assert txreceipt.status == 1, "should success" - assert erc20.caller.balanceOf(ADDRS["validator"]) == balance - amount - - denom = f"gravity{erc20.address}" - - def check_gravity_native_tokens(): - "check the balance of gravity native token" - return cronos_cli.balance(eth_to_bech32(recipient), denom=denom) == amount - - wait_for_fn("send-to-gravity-native", check_gravity_native_tokens) - - # Deploy a bad cosmos erc20 token with single character - # Cosmos denom must be 3 ~ 128 characters long and support letters, - # followed by either a letter, a number or a separator - # ('/', ':', '.', '_' or '-'). - print("Deploy cosmos erc20 contract on ethereum") - tx_receipt = deploy_erc20( - gravity.contract, gravity.geth, "A", "A", "DOG", 6, KEYS["validator"] - ) - assert tx_receipt.status == 1, "should success" - - # Wait enough for orchestrator to relay the event - wait_for_new_blocks(cronos_cli, 30) - - # Send again token to cronos and verify that the network is not stopped - print("send to cronos crc20") - recipient = HexBytes(ADDRS["community"]) - balance = erc20.caller.balanceOf(ADDRS["validator"]) - txreceipt = send_to_cosmos( - gravity.contract, erc20, gravity.geth, recipient, amount, KEYS["validator"] - ) - assert txreceipt.status == 1, "should success" - assert erc20.caller.balanceOf(ADDRS["validator"]) == balance - amount - - denom = f"gravity{erc20.address}" - - def check_gravity_native_tokens(): - "check the balance of gravity native token" - return cronos_cli.balance(eth_to_bech32(recipient), denom=denom) == 2 * amount - - wait_for_fn("send-to-gravity-native", check_gravity_native_tokens) diff --git a/integration_tests/test_ibc.py b/integration_tests/test_ibc.py deleted file mode 100644 index 56edf919c3..0000000000 --- a/integration_tests/test_ibc.py +++ /dev/null @@ -1,218 +0,0 @@ -import json - -import pytest - -from .cosmoscli import module_address -from .ibc_utils import ( - RATIO, - assert_ready, - cronos_transfer_source_tokens, - cronos_transfer_source_tokens_with_proxy, - find_duplicate, - get_balance, - ibc_incentivized_transfer, - ibc_transfer, - prepare_network, - register_fee_payee, - wait_for_check_channel_ready, -) -from .utils import ( - ADDRS, - CONTRACTS, - approve_proposal, - deploy_contract, - parse_events_rpc, - send_transaction, - wait_for_fn, -) - -pytestmark = pytest.mark.ibc - - -@pytest.fixture(scope="module", params=[True, False]) -def ibc(request, tmp_path_factory): - "prepare-network" - incentivized = request.param - name = "ibc" - path = tmp_path_factory.mktemp(name) - yield from prepare_network(path, name, incentivized=incentivized) - - -def test_ibc_transfer(ibc): - """ - test ibc transfer tokens with hermes cli - """ - ibc_transfer(ibc) - dst_denom = "basetcro" - # assert that the relayer transactions do enables the dynamic fee extension option. - cli = ibc.cronos.cosmos_cli() - criteria = "message.action='/ibc.core.channel.v1.MsgChannelOpenInit'" - tx = cli.tx_search(criteria)["txs"][0] - events = parse_events_rpc(tx["events"]) - fee = int(events["tx"]["fee"].removesuffix(dst_denom)) - gas = int(tx["gas_wanted"]) - # the effective fee is decided by the max_priority_fee (base fee is zero) - # rather than the normal gas price - assert fee == gas * 1000000 - - # check duplicate OnRecvPacket events - criteria = "message.action='/ibc.core.channel.v1.MsgRecvPacket'" - tx = cli.tx_search(criteria)["txs"][0] - events = tx["events"] - for event in events: - dup = find_duplicate(event["attributes"]) - assert not dup, f"duplicate {dup} in {event['type']}" - - -def test_ibc_incentivized_transfer(ibc, tmp_path): - if not ibc.incentivized: - # upgrade to incentivized - src_chain = ibc.cronos.cosmos_cli() - dst_chain = ibc.chainmain.cosmos_cli() - version = {"fee_version": "ics29-1", "app_version": "ics20-1"} - community = "community" - authority = module_address("gov") - connid = "connection-0" - channel_id = "channel-0" - deposit = "1basetcro" - proposal_src = src_chain.ibc_upgrade_channels( - version, - community, - deposit=deposit, - title="channel-upgrade-title", - summary="summary", - port_pattern="transfer", - channel_ids=channel_id, - ) - proposal_src["deposit"] = deposit - proposal_src["proposer"] = authority - proposal_src["messages"][0]["signer"] = authority - proposal = tmp_path / "proposal.json" - proposal.write_text(json.dumps(proposal_src)) - rsp = src_chain.submit_gov_proposal(proposal, from_=community) - assert rsp["code"] == 0, rsp["raw_log"] - approve_proposal(ibc.cronos, rsp["events"]) - wait_for_check_channel_ready( - src_chain, connid, channel_id, "STATE_FLUSHCOMPLETE" - ) - wait_for_check_channel_ready(src_chain, connid, channel_id) - register_fee_payee(src_chain, dst_chain) - ibc_incentivized_transfer(ibc) - - -def test_cronos_transfer_tokens(ibc): - """ - test sending basetcro from cronos to crypto-org-chain using cli transfer_tokens. - depends on `test_ibc` to send the original coins. - """ - assert_ready(ibc) - dst_addr = ibc.chainmain.cosmos_cli().address("signer2") - dst_amount = 2 - dst_denom = "basecro" - cli = ibc.cronos.cosmos_cli() - src_amount = dst_amount * RATIO # the decimal places difference - src_addr = cli.address("signer2") - src_denom = "basetcro" - - # case 1: use cronos cli - old_src_balance = get_balance(ibc.cronos, src_addr, src_denom) - old_dst_balance = get_balance(ibc.chainmain, dst_addr, dst_denom) - rsp = cli.transfer_tokens( - src_addr, - dst_addr, - f"{src_amount}{src_denom}", - ) - assert rsp["code"] == 0, rsp["raw_log"] - new_dst_balance = 0 - - def check_balance_change(): - nonlocal new_dst_balance - new_dst_balance = get_balance(ibc.chainmain, dst_addr, dst_denom) - return old_dst_balance != new_dst_balance - - wait_for_fn("balance change", check_balance_change) - assert old_dst_balance + dst_amount == new_dst_balance - new_src_balance = get_balance(ibc.cronos, src_addr, src_denom) - assert old_src_balance - src_amount == new_src_balance - - -def test_cronos_transfer_tokens_acknowledgement_error(ibc): - """ - test sending basetcro from cronos to crypto-org-chain using cli transfer_tokens - with invalid receiver for acknowledgement error. - depends on `test_ibc` to send the original coins. - """ - assert_ready(ibc) - dst_addr = "invalid_address" - dst_amount = 2 - cli = ibc.cronos.cosmos_cli() - src_amount = dst_amount * RATIO # the decimal places difference - src_addr = cli.address("signer2") - src_denom = "basetcro" - - old_src_balance = get_balance(ibc.cronos, src_addr, src_denom) - rsp = cli.transfer_tokens( - src_addr, - dst_addr, - f"{src_amount}{src_denom}", - ) - assert rsp["code"] == 0, rsp["raw_log"] - new_src_balance = 0 - - def check_balance_change(): - nonlocal new_src_balance - new_src_balance = get_balance(ibc.cronos, src_addr, src_denom) - return old_src_balance == new_src_balance - - wait_for_fn("balance no change", check_balance_change) - new_src_balance = get_balance(ibc.cronos, src_addr, src_denom) - - -def test_cro_bridge_contract(ibc): - """ - test sending basetcro from cronos to crypto-org-chain using CroBridge contract. - depends on `test_ibc` to send the original coins. - """ - dst_addr = ibc.chainmain.cosmos_cli().address("signer2") - dst_amount = 2 - dst_denom = "basecro" - src_amount = dst_amount * RATIO # the decimal places difference - old_dst_balance = get_balance(ibc.chainmain, dst_addr, dst_denom) - - # case 2: use CroBridge contract - w3 = ibc.cronos.w3 - contract = deploy_contract(w3, CONTRACTS["CroBridge"]) - tx = contract.functions.send_cro_to_crypto_org(dst_addr).build_transaction( - { - "from": ADDRS["signer2"], - "value": src_amount, - } - ) - receipt = send_transaction(w3, tx) - assert receipt.status == 1 - - new_dst_balance = 0 - - def check_balance_change(): - nonlocal new_dst_balance - new_dst_balance = get_balance(ibc.chainmain, dst_addr, dst_denom) - return old_dst_balance != new_dst_balance - - wait_for_fn("check balance change", check_balance_change) - assert old_dst_balance + dst_amount == new_dst_balance - - -def test_cronos_transfer_source_tokens(ibc): - """ - test sending crc20 tokens originated from cronos to crypto-org-chain - """ - assert_ready(ibc) - cronos_transfer_source_tokens(ibc) - - -def test_cronos_transfer_source_tokens_with_proxy(ibc): - """ - test sending crc20 tokens originated from cronos to crypto-org-chain - """ - assert_ready(ibc) - cronos_transfer_source_tokens_with_proxy(ibc) diff --git a/integration_tests/test_ibc_rly.py b/integration_tests/test_ibc_rly.py deleted file mode 100644 index 22f69a7f2f..0000000000 --- a/integration_tests/test_ibc_rly.py +++ /dev/null @@ -1,364 +0,0 @@ -import json - -import pytest -from eth_utils import keccak, to_checksum_address -from pystarport import cluster -from web3.datastructures import AttributeDict - -from .ibc_utils import ( - RATIO, - RELAYER_CALLER, - assert_duplicate, - cronos_transfer_source_tokens, - cronos_transfer_source_tokens_with_proxy, - ibc_denom, - ibc_incentivized_transfer, - ibc_multi_transfer, - ibc_transfer, - prepare_network, -) -from .utils import ( - ADDRS, - CONTRACT_ABIS, - bech32_to_eth, - get_logs_since, - get_method_map, - get_topic_data, - module_address, - parse_events_rpc, - wait_for_new_blocks, -) - -pytestmark = pytest.mark.ibc_rly_evm - -CONTRACT = "0x0000000000000000000000000000000000000065" -contract_info = json.loads(CONTRACT_ABIS["IRelayerModule"].read_text()) -method_map = get_method_map(contract_info) -method_name_map = get_method_map(contract_info, by_name=True) -method_with_seq = ["RecvPacket", "WriteAcknowledgement", "AcknowledgePacket"] -cronos_signer2 = ADDRS["signer2"] -src_amount = 10 -src_denom = "basecro" -dst_amount = src_amount * RATIO # the decimal places difference -dst_denom = "basetcro" -channel = "channel-0" - - -@pytest.fixture(scope="module") -def ibc(request, tmp_path_factory): - "prepare-network" - name = "ibc_rly_evm" - path = tmp_path_factory.mktemp(name) - yield from prepare_network( - path, - name, - relayer=cluster.Relayer.HERMES.value, - ) - - -def amount_dict(amt, denom): - if amt == 0: - return [] - return [ - AttributeDict( - { - "amount": amt, - "denom": denom, - } - ) - ] - - -def coin_received(receiver, amt, denom): - return { - "receiver": receiver, - "amount": amount_dict(amt, denom), - } - - -def coin_base(minter, amt, denom): - return { - "minter": minter, - "amount": amount_dict(amt, denom), - } - - -def coin_spent(spender, amt, denom): - return { - "spender": spender, - "amount": amount_dict(amt, denom), - } - - -def distribute_fee(receiver, fee): - return { - "receiver": receiver, - "fee": keccak(text=fee), - } - - -def fungible(dst, src, amt, denom): - return { - "receiver": dst, - "sender": src, - "denom": keccak(text=denom), - "amount": amt, - } - - -def transfer(src, dst, amt, denom): - return { - "recipient": dst, - "sender": src, - "amount": amount_dict(amt, denom), - } - - -def burn(burner, amt, denom): - return { - "burner": burner, - "amount": amount_dict(amt, denom), - } - - -def recv_packet(seq, src, dst, amt, denom): - return { - "packetSequence": keccak(text=f"{seq}"), - "packetSrcPort": keccak(text="transfer"), - "packetSrcChannel": keccak(text=channel), - "packetDstPort": "transfer", - "packetDstChannel": channel, - "connectionId": "connection-0", - "packetDataHex": AttributeDict( - { - "receiver": dst, - "sender": src, - "amount": amount_dict(amt, denom), - } - ), - } - - -def acknowledge_packet(seq): - return { - "packetSequence": keccak(text=f"{seq}"), - "packetSrcPort": keccak(text="transfer"), - "packetSrcChannel": keccak(text=channel), - "packetDstPort": "transfer", - "packetDstChannel": channel, - "connectionId": "connection-0", - } - - -def denom_trace(denom): - return { - "denom": keccak(text=denom), - } - - -def write_ack(seq, src, dst, amt, denom): - return { - "packetSequence": keccak(text=f"{seq}"), - "packetSrcPort": keccak(text="transfer"), - "packetSrcChannel": keccak(text=channel), - "packetDstPort": "transfer", - "packetDstChannel": channel, - "connectionId": "connection-0", - "packetDataHex": AttributeDict( - { - "receiver": dst, - "sender": src, - "amount": amount_dict(amt, denom), - } - ), - } - - -def send_coins(src, dst, amt, denom): - return [ - coin_spent(src, amt, denom), - coin_received(dst, amt, denom), - transfer(src, dst, amt, denom), - ] - - -def send_from_module_to_acc(src, dst, amt, denom): - return [ - coin_received(src, amt, denom), - coin_base(src, amt, denom), - *send_coins(src, dst, amt, denom), - ] - - -def send_from_acc_to_module(src, dst, amt, denom): - return [ - *send_coins(src, dst, amt, denom), - ] - - -def get_send_packet_seq( - cli, - criteria="message.action='/ibc.applications.transfer.v1.MsgTransfer'", -): - txs = cli.tx_search_rpc( - criteria, - order="desc", - ) - for tx in txs: - res = tx["tx_result"] - events = parse_events_rpc(res["events"]) - target = events.get("send_packet") - if target and target["packet_sequence"]: - return target["packet_sequence"] - return None - - -def filter_logs_since(w3, start, name, seq): - topic = method_name_map.get(name) - assert topic - return w3.eth.get_logs( - { - "fromBlock": start, - "address": [CONTRACT], - "topics": [topic, "0x" + keccak(text=f"{seq}").hex()], - } - ) - - -def test_ibc(ibc): - # chainmain-1 relayer -> cronos_777-1 signer2 - w3 = ibc.cronos.w3 - wait_for_new_blocks(ibc.cronos.cosmos_cli(), 1) - start = w3.eth.get_block_number() - ibc_transfer(ibc) - denom = ibc_denom(channel, src_denom) - logs = get_logs_since(w3, CONTRACT, start) - chainmain_cli = ibc.chainmain.cosmos_cli() - relayer0 = chainmain_cli.address("relayer") - relayer = to_checksum_address(bech32_to_eth(relayer0)) - cronos_addr = module_address("cronos") - transfer_addr = module_address("transfer") - seq = get_send_packet_seq(chainmain_cli) - expected = [ - recv_packet(seq, relayer0, cronos_signer2, src_amount, src_denom), - denom_trace(denom), - *send_from_module_to_acc(transfer_addr, cronos_signer2, src_amount, denom), - fungible(cronos_signer2, relayer, src_amount, src_denom), - *send_from_acc_to_module(cronos_signer2, cronos_addr, src_amount, denom), - *send_from_module_to_acc(cronos_addr, cronos_signer2, dst_amount, dst_denom), - write_ack(seq, relayer0, cronos_signer2, src_amount, src_denom), - ] - assert len(logs) == len(expected) - height = logs[0]["blockNumber"] - assert_duplicate(ibc.cronos.base_port(0), height) - for i, log in enumerate(logs): - method_name, topic = get_topic_data(w3, method_map, contract_info, log) - assert topic == AttributeDict(expected[i]), [i, method_name] - # test filter by seq - if method_name in method_with_seq: - flogs = filter_logs_since(w3, start, method_name, seq)[0] - _, ftopic = get_topic_data(w3, method_map, contract_info, flogs) - assert ftopic == topic, method_name - - -def get_escrow_address(cli, channel): - return to_checksum_address( - bech32_to_eth(cli.ibc_escrow_address("transfer", channel)), - ) - - -def test_ibc_incentivized_transfer(ibc): - w3 = ibc.cronos.w3 - cli = ibc.cronos.cosmos_cli() - wait_for_new_blocks(cli, 1) - start = w3.eth.get_block_number() - amount, seq0 = ibc_incentivized_transfer(ibc) - logs = get_logs_since(w3, CONTRACT, start) - fee_denom = "ibcfee" - fee = f"{src_amount}{fee_denom}" - transfer_denom = "transfer/channel-0/basetcro" - dst_adr = ibc.chainmain.cosmos_cli().address("signer2") - src_relayer = ADDRS["signer1"] - checksum_dst_adr = to_checksum_address(bech32_to_eth(dst_adr)) - feeibc_addr = module_address("feeibc") - escrow = get_escrow_address(cli, channel) - seq1 = get_send_packet_seq(ibc.chainmain.cosmos_cli()) - expected = [ - acknowledge_packet(seq0), - distribute_fee(src_relayer, fee), - *send_coins(feeibc_addr, src_relayer, src_amount, fee_denom), - distribute_fee(RELAYER_CALLER, fee), - *send_coins(feeibc_addr, RELAYER_CALLER, src_amount, fee_denom), - distribute_fee(cronos_signer2, ""), - *send_coins(feeibc_addr, cronos_signer2, 0, fee_denom), - fungible(checksum_dst_adr, cronos_signer2, amount, dst_denom), - recv_packet(seq1, dst_adr, cronos_signer2, amount, transfer_denom), - *send_coins(escrow, cronos_signer2, amount, dst_denom), - fungible(cronos_signer2, checksum_dst_adr, amount, transfer_denom), - write_ack(seq1, dst_adr, cronos_signer2, amount, transfer_denom), - ] - assert len(logs) == len(expected) - for i, log in enumerate(logs): - method_name, topic = get_topic_data(w3, method_map, contract_info, log) - assert topic == AttributeDict(expected[i]), [i, method_name] - # test filter by seq - if method_name in method_with_seq: - seq = seq0 if method_name == "AcknowledgePacket" else seq1 - flogs = filter_logs_since(w3, start, method_name, seq)[0] - _, ftopic = get_topic_data(w3, method_map, contract_info, flogs) - assert ftopic == topic, method_name - - -def assert_transfer_source_tokens_topics(ibc, fn): - cli = ibc.cronos.cosmos_cli() - wait_for_new_blocks(cli, 1) - w3 = ibc.cronos.w3 - start = w3.eth.get_block_number() - amount, contract = fn(ibc) - logs = get_logs_since(w3, CONTRACT, start) - escrow = get_escrow_address(cli, channel) - dst_adr = ibc.chainmain.cosmos_cli().address("signer2") - seq0 = get_send_packet_seq( - ibc.cronos.cosmos_cli(), - criteria="message.action='/ethermint.evm.v1.MsgEthereumTx'", - ) - seq1 = get_send_packet_seq(ibc.chainmain.cosmos_cli()) - checksum_dst_adr = to_checksum_address(bech32_to_eth(dst_adr)) - cronos_addr = module_address("cronos") - cronos_denom = f"cronos{contract}" - transfer_denom = f"transfer/{channel}/{cronos_denom}" - expected = [ - acknowledge_packet(seq0), - fungible(checksum_dst_adr, ADDRS["validator"], amount, cronos_denom), - recv_packet(seq1, dst_adr, cronos_signer2, amount, transfer_denom), - *send_coins(escrow, cronos_signer2, amount, cronos_denom), - fungible(cronos_signer2, checksum_dst_adr, amount, transfer_denom), - *send_coins(cronos_signer2, cronos_addr, amount, cronos_denom), - coin_spent(cronos_addr, amount, cronos_denom), - burn(cronos_addr, amount, cronos_denom), - write_ack(seq1, dst_adr, cronos_signer2, amount, transfer_denom), - ] - assert len(logs) == len(expected) - height = logs[0]["blockNumber"] - assert_duplicate(ibc.cronos.base_port(0), height) - for i, log in enumerate(logs): - method_name, topic = get_topic_data(w3, method_map, contract_info, log) - assert topic == AttributeDict(expected[i]), [i, method_name] - # test filter by seq - if method_name in method_with_seq: - seq = seq0 if method_name == "AcknowledgePacket" else seq1 - flogs = filter_logs_since(w3, start, method_name, seq)[0] - _, ftopic = get_topic_data(w3, method_map, contract_info, flogs) - assert ftopic == topic, method_name - - -def test_cronos_transfer_source_tokens(ibc): - assert_transfer_source_tokens_topics(ibc, cronos_transfer_source_tokens) - - -def test_cronos_transfer_source_tokens_with_proxy(ibc): - assert_transfer_source_tokens_topics(ibc, cronos_transfer_source_tokens_with_proxy) - - -def test_ibc_multi(ibc): - ibc_multi_transfer(ibc) diff --git a/integration_tests/test_ibc_rly_gas.py b/integration_tests/test_ibc_rly_gas.py deleted file mode 100644 index ce1f206895..0000000000 --- a/integration_tests/test_ibc_rly_gas.py +++ /dev/null @@ -1,40 +0,0 @@ -import pytest -from pystarport import cluster - -from .ibc_utils import ( - ibc_incentivized_transfer, - ibc_multi_transfer, - ibc_transfer, - log_gas_records, - prepare_network, -) -from .utils import wait_for_new_blocks - -pytestmark = pytest.mark.ibc_rly_gas - - -@pytest.fixture(scope="module", params=["ibc_rly_evm", "ibc_rly"]) -def ibc(request, tmp_path_factory): - "prepare-network" - name = request.param - path = tmp_path_factory.mktemp(name) - yield from prepare_network(path, name, relayer=cluster.Relayer.HERMES.value) - - -records = [] - - -def test_ibc(ibc): - # chainmain-1 relayer -> cronos_777-1 signer2 - cli = ibc.cronos.cosmos_cli() - wait_for_new_blocks(cli, 1) - ibc_transfer(ibc) - ibc_incentivized_transfer(ibc) - ibc_multi_transfer(ibc) - diff = 0.1 - record = log_gas_records(cli) - if record: - records.append(record) - if len(records) == 2: - res = float(sum(records[0]) / sum(records[1])) - assert 1 - diff <= res <= 1 + diff, res diff --git a/integration_tests/test_ibc_timeout.py b/integration_tests/test_ibc_timeout.py deleted file mode 100644 index ed9a3dbe79..0000000000 --- a/integration_tests/test_ibc_timeout.py +++ /dev/null @@ -1,59 +0,0 @@ -import pytest - -from .ibc_utils import RATIO, assert_ready, get_balance, ibc_transfer, prepare_network -from .utils import wait_for_fn - -pytestmark = pytest.mark.ibc_timeout - - -@pytest.fixture(scope="module") -def ibc(request, tmp_path_factory): - "prepare-network" - name = "ibc_timeout" - path = tmp_path_factory.mktemp(name) - yield from prepare_network(path, name, grantee="signer3") - - -def test_ibc(ibc): - ibc_transfer(ibc) - - -def test_cronos_transfer_timeout(ibc): - """ - test sending basetcro from cronos to crypto-org-chain using cli transfer_tokens. - depends on `test_ibc` to send the original coins. - """ - assert_ready(ibc) - dst_addr = ibc.chainmain.cosmos_cli().address("signer2") - dst_amount = 2 - dst_denom = "basecro" - cli = ibc.cronos.cosmos_cli() - src_amount = dst_amount * RATIO # the decimal places difference - src_addr = cli.address("signer2") - src_denom = "basetcro" - - # case 1: use cronos cli - old_src_balance = get_balance(ibc.cronos, src_addr, src_denom) - old_dst_balance = get_balance(ibc.chainmain, dst_addr, dst_denom) - rsp = cli.transfer_tokens( - src_addr, - dst_addr, - f"{src_amount}{src_denom}", - ) - assert rsp["code"] == 0, rsp["raw_log"] - - def check_balance_change(): - new_src_balance = get_balance(ibc.cronos, src_addr, src_denom) - get_balance(ibc.chainmain, dst_addr, dst_denom) - return old_src_balance != new_src_balance - - wait_for_fn("balance has change", check_balance_change) - - def check_no_change(): - new_src_balance = get_balance(ibc.cronos, src_addr, src_denom) - get_balance(ibc.chainmain, dst_addr, dst_denom) - return old_src_balance == new_src_balance - - wait_for_fn("balance no change", check_no_change) - new_dst_balance = get_balance(ibc.chainmain, dst_addr, dst_denom) - assert old_dst_balance == new_dst_balance diff --git a/integration_tests/test_ibc_update_client.py b/integration_tests/test_ibc_update_client.py deleted file mode 100644 index f4f5fa7686..0000000000 --- a/integration_tests/test_ibc_update_client.py +++ /dev/null @@ -1,133 +0,0 @@ -import json -import subprocess - -import pytest - -from .ibc_utils import prepare_network -from .utils import approve_proposal, wait_for_fn - -pytestmark = pytest.mark.ibc_update_client - - -@pytest.fixture(scope="module") -def ibc(request, tmp_path_factory): - "prepare-network" - name = "ibc" - path = tmp_path_factory.mktemp(name) - yield from prepare_network(path, name, is_relay=False) - - -def test_ibc_update_client(ibc, tmp_path): - """ - test client via chain header - """ - cli = ibc.cronos.cosmos_cli() - cli1 = ibc.chainmain.cosmos_cli() - client_id = "07-tendermint-0" - state = cli.ibc_query_client_consensus_states(client_id)["consensus_states"] - trusted_height = state[-1]["height"] - h = int(trusted_height["revision_height"]) - validators = cli1.ibc_query_client_header(h)["validator_set"] - header = cli1.ibc_query_client_header(h + 1) - header["trusted_validators"] = validators - header["trusted_height"] = trusted_height - header_json = header | { - "@type": "/ibc.lightclients.tendermint.v1.Header", - } - header_file = tmp_path / "header.json" - header_file.write_text(json.dumps(header_json)) - rsp = cli.ibc_update_client_with_header(client_id, header_file, from_="community") - assert rsp["code"] == 0, rsp["raw_log"] - - -def test_ibc_update_client_via_proposal(ibc): - """ - test update expire subject client with new active client via proposal - """ - cli = ibc.cronos.cosmos_cli() - cmd0 = ["hermes", "--config", ibc.hermes.configpath] - # create new client with small trust in cronos - cmd = cmd0 + [ - "create", - "client", - "--host-chain", - "cronos_777-1", - "--reference-chain", - "chainmain-1", - ] - trust_period = "45s" - subprocess.check_call(cmd + ["--trusting-period", trust_period]) - # create new connection with new client - cmd = cmd0 + [ - "create", - "connection", - "--a-chain", - "cronos_777-1", - "--a-client", - "07-tendermint-1", - "--b-client", - "07-tendermint-0", - ] - subprocess.check_call(cmd) - # create new channel with new connection - port_id = "transfer" - cmd = cmd0 + [ - "create", - "channel", - "--a-chain", - "cronos_777-1", - "--a-connection", - "connection-1", - "--a-port", - port_id, - "--b-port", - port_id, - ] - subprocess.check_call(cmd) - - def assert_trust_period(period): - key = "trusting_period" - res = cli.ibc_query_client_state(port_id, "channel-1")["client_state"][key] - assert res == period, res - - assert_trust_period(trust_period) - # create new client with default trust in cronos - cmd = cmd0 + [ - "create", - "client", - "--host-chain", - "cronos_777-1", - "--reference-chain", - "chainmain-1", - ] - subprocess.check_call(cmd) - cmd = cmd0 + [ - "query", - "client", - "status", - "--chain", - "cronos_777-1", - "--client", - "07-tendermint-1", - ] - - def check_status(): - raw = subprocess.check_output(cmd).decode("utf-8") - status = raw.split()[1] - return status != "Active" - - wait_for_fn("status change", check_status) - rsp = cli.ibc_recover_client( - { - "subject_client_id": "07-tendermint-1", - "substitute_client_id": "07-tendermint-2", - "from": "validator", - "title": "update-client-title", - "summary": "summary", - "deposit": "1basetcro", - }, - ) - assert rsp["code"] == 0, rsp["raw_log"] - approve_proposal(ibc.cronos, rsp["events"]) - default_trust_period = "1209600s" - assert_trust_period(default_trust_period) diff --git a/integration_tests/test_ica.py b/integration_tests/test_ica.py deleted file mode 100644 index 768091dcbc..0000000000 --- a/integration_tests/test_ica.py +++ /dev/null @@ -1,181 +0,0 @@ -import json - -import pytest -from pystarport import cluster - -from .cosmoscli import module_address -from .ibc_utils import ( - ChannelOrder, - Status, - deploy_contract, - funds_ica, - gen_query_balance_packet, - gen_send_msg, - ica_send_tx, - parse_events_rpc, - prepare_network, - register_acc, - wait_for_check_channel_ready, - wait_for_check_tx, - wait_for_status_change, -) -from .utils import CONTRACTS, approve_proposal, wait_for_fn - -pytestmark = pytest.mark.ica - - -@pytest.fixture(scope="module") -def ibc(request, tmp_path_factory): - "prepare-network" - name = "ibc_rly" - path = tmp_path_factory.mktemp(name) - yield from prepare_network( - path, - name, - incentivized=False, - connection_only=True, - relayer=cluster.Relayer.HERMES.value, - ) - - -@pytest.mark.parametrize( - "order", [ChannelOrder.ORDERED.value, ChannelOrder.UNORDERED.value] -) -def test_ica(ibc, order, tmp_path): - signer = "signer2" if order == ChannelOrder.ORDERED.value else "community" - connid = "connection-0" - cli_host = ibc.chainmain.cosmos_cli() - cli_controller = ibc.cronos.cosmos_cli() - ica_address, _, channel_id = register_acc( - cli_controller, connid, ordering=order, signer=signer - ) - balance = funds_ica(cli_host, ica_address, signer=signer) - to = cli_host.address(signer) - amount = 1000 - denom = "basecro" - jsonfile = CONTRACTS["TestICA"] - tcontract = deploy_contract(ibc.cronos.w3, jsonfile) - timeout_in_ns = 6000000000 - seq = 1 - msg_num = 10 - assert tcontract.caller.getStatus(channel_id, seq) == Status.PENDING - res = ica_send_tx( - cli_host, - cli_controller, - connid, - ica_address, - msg_num, - to, - denom, - amount, - memo={"src_callback": {"address": tcontract.address}}, - signer=signer, - ) - assert res == seq, res - balance -= amount * msg_num - assert cli_host.balance(ica_address, denom=denom) == balance - wait_for_status_change(tcontract, channel_id, seq, timeout_in_ns / 1e9) - assert tcontract.caller.getStatus(channel_id, seq) == Status.PENDING - - def check_for_ack(): - criteria = "message.action='/ibc.core.channel.v1.MsgAcknowledgement'" - return cli_controller.tx_search(criteria)["txs"] - - txs = wait_for_fn("ack change", check_for_ack) - events = parse_events_rpc(txs[0]["events"]) - err = events.get("ibc_src_callback")["callback_error"] - assert "sender is not authenticated" in err, err - - no_timeout = 60 - - def submit_msgs(msg_num, timeout_in_s=no_timeout, gas="200000"): - num_txs = len(cli_host.query_all_txs(ica_address)["txs"]) - # generate a transaction to send to host chain - m = gen_send_msg(ica_address, to, denom, amount) - msgs = [] - for i in range(msg_num): - msgs.append(m) - data = json.dumps(msgs) - packet = cli_controller.ica_generate_packet_data(data) - # submit transaction on host chain on behalf of interchain account - rsp = cli_controller.ica_send_tx( - connid, - json.dumps(packet), - timeout_in_ns=int(timeout_in_s * 1e9), - gas=gas, - from_=signer, - ) - assert rsp["code"] == 0, rsp["raw_log"] - timeout = timeout_in_s + 3 if timeout_in_s < no_timeout else None - wait_for_check_tx(cli_host, ica_address, num_txs, timeout) - - # submit large txs to trigger close channel with small timeout for order channel - msg_num = 140 - submit_msgs(msg_num, 0.005, "600000") - assert cli_host.balance(ica_address, denom=denom) == balance - if order == ChannelOrder.UNORDERED.value: - with pytest.raises(AssertionError) as exc: - register_acc(cli_controller, connid) - assert "existing active channel" in str(exc.value) - else: - wait_for_check_channel_ready(cli_controller, connid, channel_id, "STATE_CLOSED") - # reopen ica account after channel get closed - ica_address2, port_id2, channel_id2 = register_acc(cli_controller, connid) - assert ica_address2 == ica_address, ica_address2 - assert channel_id2 != channel_id, channel_id2 - # upgrade to unordered channel - channel = cli_controller.ibc_query_channel(port_id2, channel_id2) - version_data = json.loads(channel["channel"]["version"]) - community = "community" - authority = module_address("gov") - deposit = "1basetcro" - proposal_src = cli_controller.ibc_upgrade_channels( - json.loads(version_data["app_version"]), - community, - deposit=deposit, - title="channel-upgrade-title", - summary="summary", - port_pattern=port_id2, - channel_ids=channel_id2, - ) - proposal_src["deposit"] = deposit - proposal_src["proposer"] = authority - proposal_src["messages"][0]["signer"] = authority - proposal_src["messages"][0]["fields"]["ordering"] = ChannelOrder.UNORDERED.value - proposal = tmp_path / "proposal.json" - proposal.write_text(json.dumps(proposal_src)) - rsp = cli_controller.submit_gov_proposal(proposal, from_=community) - assert rsp["code"] == 0, rsp["raw_log"] - approve_proposal(ibc.cronos, rsp["events"]) - wait_for_check_channel_ready( - cli_controller, connid, channel_id2, "STATE_FLUSHCOMPLETE" - ) - wait_for_check_channel_ready(cli_controller, connid, channel_id2) - # submit large txs to trigger close channel with small timeout for order channel - msg_num = 140 - submit_msgs(msg_num, 0.005, "600000") - assert cli_host.balance(ica_address, denom=denom) == balance - with pytest.raises(AssertionError) as exc: - register_acc(cli_controller, connid) - assert "existing active channel" in str(exc.value) - - # submit normal txs should work - msg_num = 2 - submit_msgs(msg_num) - balance -= amount * msg_num - # check if the funds are reduced in interchain account - assert cli_host.balance(ica_address, denom=denom) == balance - call_module_safe_query(cli_controller, connid, signer, ica_address) - - -def call_module_safe_query(cli, connid, signer, ica_address): - packet = gen_query_balance_packet(cli, ica_address) - timeout = 60 # in seconds - rsp = cli.ica_send_tx( - connid, - json.dumps(packet), - timeout_in_ns=int(timeout * 1e9), - gas=200000, - from_=signer, - ) - assert rsp["code"] == 0, rsp diff --git a/integration_tests/test_ica_incentivized.py b/integration_tests/test_ica_incentivized.py deleted file mode 100644 index 4aa53e575a..0000000000 --- a/integration_tests/test_ica_incentivized.py +++ /dev/null @@ -1,100 +0,0 @@ -import time - -import pytest - -from .ibc_utils import ( - funds_ica, - get_balance, - ica_send_tx, - prepare_network, - register_acc, -) -from .utils import wait_for_fn - -pytestmark = pytest.mark.ica - - -@pytest.fixture(scope="module") -def ibc(request, tmp_path_factory): - "prepare-network" - name = "ibc" - path = tmp_path_factory.mktemp(name) - yield from prepare_network(path, name) - - -def test_incentivized(ibc): - connid = "connection-0" - cli_host = ibc.chainmain.cosmos_cli() - cli_controller = ibc.cronos.cosmos_cli() - ica_address, _, channel_id = register_acc(cli_controller, connid) - relayer = cli_controller.address("signer1") - balance = funds_ica(cli_host, ica_address) - ibc.cronos.supervisorctl("stop", "relayer-demo") - time.sleep(3) - port_id = "icahost" - rsp = cli_host.register_counterparty_payee( - port_id, - channel_id, - cli_host.address("relayer"), - relayer, - from_="relayer", - fees="100000000basecro", - ) - assert rsp["code"] == 0, rsp["raw_log"] - ibc.cronos.supervisorctl("start", "relayer-demo") - to = cli_host.address("signer2") - amount = 1000 - denom = "basecro" - sender = cli_controller.address("signer2") - fee_denom = "ibcfee" - old_amt_fee = cli_controller.balance(relayer, fee_denom) - old_amt_sender_fee = cli_controller.balance(sender, fee_denom) - msg_num = 2 - fee = f"10{fee_denom}" - - def incentivized_cb(seq): - rsp = cli_controller.pay_packet_fee( - f"icacontroller-{sender}", - channel_id, - seq, - recv_fee=fee, - ack_fee=fee, - timeout_fee=fee, - from_=sender, - ) - assert rsp["code"] == 0, rsp["raw_log"] - - ica_send_tx( - cli_host, - cli_controller, - connid, - ica_address, - msg_num, - to, - denom, - amount, - fees="0basecro", - incentivized_cb=incentivized_cb, - ) - balance -= amount * msg_num - - # fee is locked - # https://github.com/cosmos/ibc-go/pull/5571 - assert cli_controller.balance(sender, fee_denom) == old_amt_sender_fee - 20 - # check if the funds are reduced in interchain account - assert cli_host.balance(ica_address, denom=denom) == balance - - # wait for relayer receive the fee - def check_fee(): - amount = cli_controller.balance(relayer, fee_denom) - if amount > old_amt_fee: - assert amount == old_amt_fee + 20 - return True - else: - return False - - wait_for_fn("wait for relayer to receive the fee", check_fee) - - # timeout fee is refunded - actual = get_balance(ibc.cronos, sender, fee_denom) - assert actual == old_amt_sender_fee - 20, actual diff --git a/integration_tests/test_ica_precompile.py b/integration_tests/test_ica_precompile.py deleted file mode 100644 index d3ddba1078..0000000000 --- a/integration_tests/test_ica_precompile.py +++ /dev/null @@ -1,480 +0,0 @@ -import base64 -import json -from enum import Enum - -import pytest -from eth_utils import keccak -from pystarport import cluster -from web3.datastructures import AttributeDict - -from .ibc_utils import ( - Status, - funds_ica, - gen_query_balance_packet, - gen_send_msg, - get_next_channel, - prepare_network, - wait_for_check_channel_ready, - wait_for_check_tx, - wait_for_status_change, -) -from .utils import ( - ADDRS, - CONTRACT_ABIS, - CONTRACTS, - KEYS, - deploy_contract, - eth_to_bech32, - send_transaction, - wait_for_fn, -) - -pytestmark = pytest.mark.ica - -CONTRACT = "0x0000000000000000000000000000000000000066" -connid = "connection-0" -no_timeout = 300000000000 -denom = "basecro" -validator = "validator" -amt = 1000 - - -class Ordering(Enum): - NONE = 0 - UNORDERED = 1 - ORDERED = 2 - - -@pytest.fixture(scope="module") -def ibc(request, tmp_path_factory): - "prepare-network" - name = "ibc_rly_evm" - path = tmp_path_factory.mktemp(name) - yield from prepare_network( - path, - name, - incentivized=False, - connection_only=True, - relayer=cluster.Relayer.RLY.value, - ) - - -def register_acc( - cli, - w3, - register, - query, - data, - channel_id, - order, - signer="signer2", - expect_status=1, - contract_addr=None, -): - addr = contract_addr if contract_addr else ADDRS[signer] - keys = KEYS[signer] - print(f"register ica account with {channel_id}") - tx = register(connid, "", order).build_transaction(data) - receipt = send_transaction(w3, tx, keys) - assert receipt.status == expect_status - owner = eth_to_bech32(addr) - if expect_status == 1: - wait_for_check_channel_ready(cli, connid, channel_id) - res = cli.ica_query_account(connid, owner) - ica_address = res["address"] - print("query ica account", ica_address) - res = query(connid, addr).call() - assert ica_address == res, res - return ica_address - - -def submit_msgs( - ibc, - func, - data, - ica_address, - add_delegate, - expected_seq, - event, - channel_id, - timeout=no_timeout, - amount=amt, - need_wait=True, - msg_num=2, - with_channel_id=True, - signer="signer2", -): - cli_host = ibc.chainmain.cosmos_cli() - cli_controller = ibc.cronos.cosmos_cli() - w3 = ibc.cronos.w3 - to = cli_host.address(validator) - # generate msgs send to host chain - m = gen_send_msg(ica_address, to, denom, amount) - msgs = [] - diff_amt = 0 - for i in range(msg_num): - msgs.append(m) - diff_amt += amount - if add_delegate: - to = cli_host.address(validator, bech="val") - # generate msg delegate to host chain - amt1 = 100 - msgs.append( - { - "@type": "/cosmos.staking.v1beta1.MsgDelegate", - "delegator_address": ica_address, - "validator_address": to, - "amount": {"denom": denom, "amount": f"{amt1}"}, - } - ) - diff_amt += amt1 - generated_packet = cli_controller.ica_generate_packet_data(json.dumps(msgs)) - num_txs = len(cli_host.query_all_txs(ica_address)["txs"]) - str = base64.b64decode(generated_packet["data"]) - # submit transaction on host chain on behalf of interchain account - if with_channel_id: - tx = func(connid, channel_id, str, timeout).build_transaction(data) - else: - tx = func(connid, str, timeout).build_transaction(data) - receipt = send_transaction(w3, tx, KEYS[signer]) - assert receipt.status == 1 - if timeout < no_timeout: - timeout_in_s = timeout / 1e9 + 1 - print(f"wait for {timeout_in_s}s") - wait_for_check_tx(cli_host, ica_address, num_txs, timeout_in_s) - else: - logs = event.get_logs() - assert len(logs) > 0 - assert logs[0].args == AttributeDict( - { - "packetSrcChannel": keccak(text=channel_id), - "seq": expected_seq, - } - ) - if need_wait: - wait_for_check_tx(cli_host, ica_address, num_txs) - return str, diff_amt - - -@pytest.mark.parametrize("order", [Ordering.ORDERED.value, Ordering.UNORDERED.value]) -def test_call(ibc, order): - signer = "signer2" if order == Ordering.ORDERED.value else "community" - cli_host = ibc.chainmain.cosmos_cli() - cli_controller = ibc.cronos.cosmos_cli() - w3 = ibc.cronos.w3 - contract_info = json.loads(CONTRACT_ABIS["IICAModule"].read_text()) - contract = w3.eth.contract(address=CONTRACT, abi=contract_info) - data = {"from": ADDRS[signer]} - channel_id = get_next_channel(cli_controller, connid) - ica_address = register_acc( - cli_controller, - w3, - contract.functions.registerAccount, - contract.functions.queryAccount, - data, - channel_id, - order, - signer=signer, - ) - balance = funds_ica(cli_host, ica_address, signer=signer) - expected_seq = 1 - _, diff = submit_msgs( - ibc, - contract.functions.submitMsgs, - data, - ica_address, - False, - expected_seq, - contract.events.SubmitMsgsResult, - channel_id, - with_channel_id=False, - signer=signer, - ) - balance -= diff - assert cli_host.balance(ica_address, denom=denom) == balance - expected_seq += 1 - _, diff = submit_msgs( - ibc, - contract.functions.submitMsgs, - data, - ica_address, - True, - expected_seq, - contract.events.SubmitMsgsResult, - channel_id, - with_channel_id=False, - signer=signer, - ) - balance -= diff - assert cli_host.balance(ica_address, denom=denom) == balance - - -def wait_for_packet_log(start, event, channel_id, seq, status): - print("wait for log arrive", seq, status) - expected = AttributeDict( - { - "packetSrcChannel": keccak(text=channel_id), - "seq": seq, - "status": status, - } - ) - - def check_log(): - logs = event.get_logs(fromBlock=start) - return len(logs) > 0 and logs[-1].args == expected - - wait_for_fn("packet log", check_log) - - -@pytest.mark.parametrize("order", [Ordering.ORDERED.value, Ordering.UNORDERED.value]) -def test_sc_call(ibc, order): - cli_host = ibc.chainmain.cosmos_cli() - cli_controller = ibc.cronos.cosmos_cli() - w3 = ibc.cronos.w3 - contract_info = json.loads(CONTRACT_ABIS["IICAModule"].read_text()) - contract = w3.eth.contract(address=CONTRACT, abi=contract_info) - jsonfile = CONTRACTS["TestICA"] - tcontract = deploy_contract(w3, jsonfile) - contract_addr = tcontract.address - signer = "signer2" if order == Ordering.ORDERED.value else "community" - addr = ADDRS[signer] - keys = KEYS[signer] - default_gas = 500000 - data = {"from": addr, "gas": default_gas} - channel_id = get_next_channel(cli_controller, connid) - ica_address = register_acc( - cli_controller, - w3, - tcontract.functions.callRegister, - contract.functions.queryAccount, - data, - channel_id, - order, - signer=signer, - contract_addr=contract_addr, - ) - assert tcontract.caller.getAccount() == addr - assert ( - tcontract.functions.callQueryAccount(connid, contract_addr).call() - == ica_address - ) - - # register from another user should fail - signer1 = "signer1" - data = {"from": ADDRS[signer1], "gas": default_gas} - version = "" - tx = tcontract.functions.callRegister( - connid, - version, - order, - ).build_transaction(data) - res = send_transaction(w3, tx, KEYS[signer1]) - assert res.status == 0 - assert tcontract.caller.getAccount() == addr - - assert ( - tcontract.functions.delegateQueryAccount(connid, contract_addr).call() - == ica_address - ) - assert ( - tcontract.functions.staticQueryAccount(connid, contract_addr).call() - == ica_address - ) - - # readonly call should fail - def register_ro(func): - tx = func(connid, version, order).build_transaction(data) - assert send_transaction(w3, tx, keys).status == 0 - - register_ro(tcontract.functions.delegateRegister) - register_ro(tcontract.functions.staticRegister) - - # readonly call should fail - def submit_msgs_ro(func, str): - tx = func(connid, str, no_timeout).build_transaction(data) - assert send_transaction(w3, tx, keys).status == 0 - - expected_seq = 1 - packet_event = tcontract.events.OnPacketResult - start = w3.eth.get_block_number() - str, diff = submit_msgs( - ibc, - tcontract.functions.callSubmitMsgs, - data, - ica_address, - False, - expected_seq, - contract.events.SubmitMsgsResult, - channel_id, - need_wait=False, - signer=signer, - ) - submit_msgs_ro(tcontract.functions.delegateSubmitMsgs, str) - submit_msgs_ro(tcontract.functions.staticSubmitMsgs, str) - last_seq = tcontract.caller.getLastSeq() - wait_for_status_change(tcontract, channel_id, last_seq) - status = tcontract.caller.getStatus(channel_id, last_seq) - assert expected_seq == last_seq - assert status == Status.FAIL - wait_for_packet_log(start, packet_event, channel_id, last_seq, status) - - expected_seq += 1 - balance = funds_ica(cli_host, ica_address, signer=signer) - start = w3.eth.get_block_number() - str, diff = submit_msgs( - ibc, - tcontract.functions.callSubmitMsgs, - data, - ica_address, - False, - expected_seq, - contract.events.SubmitMsgsResult, - channel_id, - signer=signer, - ) - last_seq = tcontract.caller.getLastSeq() - wait_for_status_change(tcontract, channel_id, last_seq) - status = tcontract.caller.getStatus(channel_id, last_seq) - assert expected_seq == last_seq - assert status == Status.SUCCESS - wait_for_packet_log(start, packet_event, channel_id, last_seq, status) - balance -= diff - assert cli_host.balance(ica_address, denom=denom) == balance - - expected_seq += 1 - start = w3.eth.get_block_number() - str, diff = submit_msgs( - ibc, - tcontract.functions.callSubmitMsgs, - data, - ica_address, - True, - expected_seq, - contract.events.SubmitMsgsResult, - channel_id, - signer=signer, - ) - submit_msgs_ro(tcontract.functions.delegateSubmitMsgs, str) - submit_msgs_ro(tcontract.functions.staticSubmitMsgs, str) - last_seq = tcontract.caller.getLastSeq() - wait_for_status_change(tcontract, channel_id, last_seq) - status = tcontract.caller.getStatus(channel_id, last_seq) - assert expected_seq == last_seq - assert status == Status.SUCCESS - wait_for_packet_log(start, packet_event, channel_id, last_seq, status) - balance -= diff - assert cli_host.balance(ica_address, denom=denom) == balance - - expected_seq += 1 - start = w3.eth.get_block_number() - # balance should not change on fail - submit_msgs( - ibc, - tcontract.functions.callSubmitMsgs, - data, - ica_address, - False, - expected_seq, - contract.events.SubmitMsgsResult, - channel_id, - amount=100000001, - need_wait=False, - signer=signer, - ) - last_seq = tcontract.caller.getLastSeq() - wait_for_status_change(tcontract, channel_id, last_seq) - status = tcontract.caller.getStatus(channel_id, last_seq) - assert expected_seq == last_seq - assert status == Status.FAIL - wait_for_packet_log(start, packet_event, channel_id, last_seq, status) - assert cli_host.balance(ica_address, denom=denom) == balance - - # balance should not change on timeout - expected_seq += 1 - start = w3.eth.get_block_number() - timeout = 5000000000 - data["gas"] = 800000 - submit_msgs( - ibc, - tcontract.functions.callSubmitMsgs, - data, - ica_address, - False, - expected_seq, - contract.events.SubmitMsgsResult, - channel_id, - timeout, - msg_num=100, - signer=signer, - ) - last_seq = tcontract.caller.getLastSeq() - wait_for_status_change(tcontract, channel_id, last_seq) - status = tcontract.caller.getStatus(channel_id, last_seq) - assert expected_seq == last_seq - assert status == Status.FAIL - wait_for_packet_log(start, packet_event, channel_id, last_seq, status) - assert cli_host.balance(ica_address, denom=denom) == balance - - if order == Ordering.UNORDERED.value: - channel_id2 = get_next_channel(cli_controller, connid) - register_acc( - cli_controller, - w3, - tcontract.functions.callRegister, - contract.functions.queryAccount, - data, - channel_id2, - order, - expect_status=0, - signer=signer, - contract_addr=contract_addr, - ) - channel_id2 = channel_id - expected_seq += 1 - else: - wait_for_check_channel_ready(cli_controller, connid, channel_id, "STATE_CLOSED") - data["gas"] = default_gas - channel_id2 = get_next_channel(cli_controller, connid) - ica_address2 = register_acc( - cli_controller, - w3, - tcontract.functions.callRegister, - contract.functions.queryAccount, - data, - channel_id2, - order, - signer=signer, - contract_addr=contract_addr, - ) - assert channel_id2 != channel_id, channel_id2 - assert ica_address2 == ica_address, ica_address2 - expected_seq = 1 - start = w3.eth.get_block_number() - str, diff = submit_msgs( - ibc, - tcontract.functions.callSubmitMsgs, - data, - ica_address, - False, - expected_seq, - contract.events.SubmitMsgsResult, - channel_id2, - signer=signer, - ) - last_seq = tcontract.caller.getLastSeq() - wait_for_status_change(tcontract, channel_id2, last_seq) - status = tcontract.caller.getStatus(channel_id2, last_seq) - assert expected_seq == last_seq - assert status == Status.SUCCESS - # wait for ack to add log from call evm - wait_for_packet_log(start, packet_event, channel_id2, last_seq, status) - balance -= diff - assert cli_host.balance(ica_address, denom=denom) == balance - - packet = gen_query_balance_packet(cli_controller, ica_address) - str = base64.b64decode(packet["data"]) - tx = tcontract.functions.callSubmitMsgs( - connid, channel_id, str, no_timeout - ).build_transaction(data) - receipt = send_transaction(w3, tx, KEYS[signer]) - assert receipt.status == 1 diff --git a/integration_tests/test_mempool.py b/integration_tests/test_mempool.py deleted file mode 100644 index bdd921cab1..0000000000 --- a/integration_tests/test_mempool.py +++ /dev/null @@ -1,82 +0,0 @@ -from pathlib import Path - -import pytest -from web3 import Web3 - -from .network import setup_custom_cronos -from .utils import ( - ADDRS, - CONTRACTS, - KEYS, - deploy_contract, - send_txs, - sign_transaction, - wait_for_new_blocks, -) - -pytestmark = pytest.mark.slow - - -@pytest.fixture(scope="module") -def cronos_mempool(tmp_path_factory): - path = tmp_path_factory.mktemp("cronos-mempool") - yield from setup_custom_cronos( - path, 26300, Path(__file__).parent / "configs/long_timeout_commit.jsonnet" - ) - - -@pytest.mark.flaky(max_runs=5) -def test_mempool(cronos_mempool): - w3: Web3 = cronos_mempool.w3 - filter = w3.eth.filter("pending") - assert filter.get_new_entries() == [] - - cli = cronos_mempool.cosmos_cli(0) - # test contract - wait_for_new_blocks(cli, 1, sleep=0.1) - block_num_2 = w3.eth.get_block_number() - print(f"block number contract begin at height: {block_num_2}") - contract = deploy_contract(w3, CONTRACTS["Greeter"]) - tx = contract.functions.setGreeting("world").build_transaction() - signed = sign_transaction(w3, tx) - txhash = w3.eth.send_raw_transaction(signed.rawTransaction) - w3.eth.wait_for_transaction_receipt(txhash) - # check tx in mempool - new_txs = filter.get_new_entries() - assert txhash in new_txs - - greeter_call_result = contract.caller.greet() - assert "world" == greeter_call_result - - # check mempool - all_pending = w3.eth.get_filter_changes(filter.filter_id) - print(f"all pending tx hash after block: {all_pending}") - assert len(all_pending) == 0 - - to = ADDRS["community"] - params = {"gasPrice": w3.eth.gas_price} - block_num_0, sended_hash_set = send_txs( - w3, cli, to, [v for k, v in KEYS.items() if k != "signer1"], params - ) - print(f"all send tx hash: {sended_hash_set} at {block_num_0}") - - all_pending = w3.eth.get_filter_changes(filter.filter_id) - assert len(all_pending) == 4 - - block_num_1 = w3.eth.get_block_number() - print(f"block_num_1 {block_num_1}") - - # check after max 10 blocks - for i in range(10): - all_pending = w3.eth.get_filter_changes(filter.filter_id) - if len(all_pending) == 0: - break - wait_for_new_blocks(cli, 1, sleep=0.1) - assert len(all_pending) == 0 - - -def test_blocked_address(cronos_mempool): - cli = cronos_mempool.cosmos_cli(0) - rsp = cli.transfer("signer1", cli.address("validator"), "1basecro") - assert rsp["code"] != 0 - assert "signer is blocked" in rsp["raw_log"] diff --git a/integration_tests/test_min_gas_price.py b/integration_tests/test_min_gas_price.py deleted file mode 100644 index 2fa727ac5f..0000000000 --- a/integration_tests/test_min_gas_price.py +++ /dev/null @@ -1,123 +0,0 @@ -from pathlib import Path - -import pytest - -from .network import setup_custom_cronos -from .utils import ADDRS, KEYS, send_transaction, w3_wait_for_block, wait_for_new_blocks - -pytestmark = pytest.mark.gas - - -@pytest.fixture(scope="module") -def custom_cronos_eq(tmp_path_factory): - path = tmp_path_factory.mktemp("min-gas-price-eq") - yield from setup_custom_cronos( - path, 26500, Path(__file__).parent / "configs/min_gas_price_eq.jsonnet" - ) - - -@pytest.fixture(scope="module") -def custom_cronos(tmp_path_factory): - path = tmp_path_factory.mktemp("min-gas-price") - yield from setup_custom_cronos( - path, 26530, Path(__file__).parent / "configs/min_gas_price.jsonnet" - ) - - -@pytest.fixture(scope="module") -def custom_cronos_lte(tmp_path_factory): - path = tmp_path_factory.mktemp("min-gas-price-lte") - yield from setup_custom_cronos( - path, 26560, Path(__file__).parent / "configs/min_gas_price_lte.jsonnet" - ) - - -@pytest.fixture( - scope="module", - params=["custom_cronos_eq", "custom_cronos", "custom_cronos_lte"], -) -def custom_cluster(request, custom_cronos_eq, custom_cronos_lte, custom_cronos): - if request.param == "custom_cronos_eq": - return custom_cronos_eq - elif request.param == "custom_cronos_lte": - return custom_cronos_lte - return custom_cronos - - -def adjust_base_fee(parent_fee, gas_limit, gas_used, params): - "spec: https://eips.ethereum.org/EIPS/eip-1559#specification" - change_denominator = params["base_fee_change_denominator"] - elasticity_multiplier = params["elasticity_multiplier"] - gas_target = gas_limit // elasticity_multiplier - if gas_used == gas_target: - return parent_fee - delta = parent_fee * abs(gas_target - gas_used) // gas_target // change_denominator - # https://github.com/crypto-org-chain/ethermint/blob/develop/x/feemarket/keeper/eip1559.go#L104 - if gas_target > gas_used: - return max(parent_fee - delta, params["min_gas_price"]) - else: - return parent_fee + max(delta, 1) - - -def get_params(cli): - params = cli.query_params("feemarket") - return {k: int(float(v)) for k, v in params.items()} - - -def test_dynamic_fee_tx(custom_cluster): - wait_for_new_blocks(custom_cluster.cosmos_cli(), 1) - w3 = custom_cluster.w3 - amount = 10000 - before = w3.eth.get_balance(ADDRS["community"]) - tip_price = 1 - max_price = 10000000000000 + tip_price - tx = { - "to": "0x0000000000000000000000000000000000000000", - "value": amount, - "gas": 21000, - "maxFeePerGas": max_price, - "maxPriorityFeePerGas": tip_price, - } - txreceipt = send_transaction(w3, tx, KEYS["community"]) - assert txreceipt.status == 1 - blk = w3.eth.get_block(txreceipt.blockNumber) - assert txreceipt.effectiveGasPrice == blk.baseFeePerGas + tip_price - - fee_expected = txreceipt.gasUsed * txreceipt.effectiveGasPrice - after = w3.eth.get_balance(ADDRS["community"]) - fee_deducted = before - after - amount - assert fee_deducted == fee_expected - - assert blk.gasUsed == txreceipt.gasUsed # we are the only tx in the block - - # check the next block's base fee is adjusted accordingly - w3_wait_for_block(w3, txreceipt.blockNumber + 1) - fee = w3.eth.get_block(txreceipt.blockNumber + 1).baseFeePerGas - params = get_params(custom_cluster.cosmos_cli()) - assert fee == adjust_base_fee( - blk.baseFeePerGas, blk.gasLimit, blk.gasUsed, params - ), fee - - -def test_base_fee_adjustment(custom_cluster): - """ - verify base fee adjustment of three continuous empty blocks - """ - wait_for_new_blocks(custom_cluster.cosmos_cli(), 1) - w3 = custom_cluster.w3 - begin = w3.eth.block_number - w3_wait_for_block(w3, begin + 3) - - blk = w3.eth.get_block(begin) - parent_fee = blk.baseFeePerGas - params = get_params(custom_cluster.cosmos_cli()) - - for i in range(3): - fee = w3.eth.get_block(begin + 1 + i).baseFeePerGas - assert fee == adjust_base_fee(parent_fee, blk.gasLimit, 0, params) - parent_fee = fee - - call = w3.provider.make_request - res = call("eth_feeHistory", [2, "latest", []])["result"]["baseFeePerGas"] - # nextBaseFee should align max with minGasPrice in eth_feeHistory - assert all(fee == hex(10000000000000) for fee in res), res diff --git a/integration_tests/test_permissions.py b/integration_tests/test_permissions.py deleted file mode 100644 index 90c4b88bbf..0000000000 --- a/integration_tests/test_permissions.py +++ /dev/null @@ -1,23 +0,0 @@ -from .utils import ADDRS, eth_to_bech32, wait_for_new_blocks - - -def test_permissions_updates(cronos): - acc = eth_to_bech32(ADDRS["signer1"]) - cli = cronos.cosmos_cli() - rsp = cli.query_permissions(acc) - print("permissions", rsp) - assert rsp["can_change_token_mapping"] is False - assert rsp["can_turn_bridge"] is False - - # update permissions - rsp = cli.update_permissions(acc, 3, from_="community") - assert rsp["code"] != 0, "should not have the permission" - - rsp = cli.update_permissions(acc, 3, from_="validator") - assert rsp["code"] == 0, rsp["raw_log"] - wait_for_new_blocks(cli, 1) - - rsp = cli.query_permissions(acc) - print("permissions", rsp) - assert rsp["can_change_token_mapping"] is True - assert rsp["can_turn_bridge"] is True diff --git a/integration_tests/test_pruned_node.py b/integration_tests/test_pruned_node.py deleted file mode 100644 index b21140ae76..0000000000 --- a/integration_tests/test_pruned_node.py +++ /dev/null @@ -1,122 +0,0 @@ -from pathlib import Path - -import pytest -from eth_bloom import BloomFilter -from eth_utils import abi, big_endian_to_int -from hexbytes import HexBytes -from web3.datastructures import AttributeDict - -from .network import setup_custom_cronos -from .utils import ( - ADDRS, - CONTRACTS, - KEYS, - deploy_contract, - sign_transaction, - wait_for_new_blocks, -) - -pytestmark = pytest.mark.slow - - -@pytest.fixture(scope="module") -def cronos(request, tmp_path_factory): - """start-cronos - params: enable_auto_deployment - """ - yield from setup_custom_cronos( - tmp_path_factory.mktemp("pruned"), - 26900, - Path(__file__).parent / "configs/pruned-node.jsonnet", - ) - - -def test_pruned_node(cronos): - """ - test basic json-rpc apis works in pruned node - """ - w3 = cronos.w3 - erc20 = deploy_contract( - w3, - CONTRACTS["TestERC20A"], - key=KEYS["validator"], - ) - tx = erc20.functions.transfer(ADDRS["community"], 10).build_transaction( - {"from": ADDRS["validator"]} - ) - signed = sign_transaction(w3, tx, KEYS["validator"]) - txhash = w3.eth.send_raw_transaction(signed.rawTransaction) - exp_gas_used = 51384 - - print("wait for prunning happens") - wait_for_new_blocks(cronos.cosmos_cli(0), 10) - - print("wait for transaction receipt", txhash.hex()) - txreceipt = w3.eth.wait_for_transaction_receipt(txhash) - assert txreceipt.gasUsed == exp_gas_used - assert len(txreceipt.logs) == 1 - data = "0x000000000000000000000000000000000000000000000000000000000000000a" - expect_log = { - "address": erc20.address, - "topics": [ - HexBytes( - abi.event_signature_to_log_topic("Transfer(address,address,uint256)") - ), - HexBytes(b"\x00" * 12 + HexBytes(ADDRS["validator"])), - HexBytes(b"\x00" * 12 + HexBytes(ADDRS["community"])), - ], - "data": HexBytes(data), - "transactionIndex": 0, - "logIndex": 0, - "removed": False, - } - assert expect_log.items() <= txreceipt.logs[0].items() - - # check get_balance and eth_call don't work on pruned state - with pytest.raises(Exception): - w3.eth.get_balance(ADDRS["validator"], block_identifier=txreceipt.blockNumber) - with pytest.raises(Exception): - erc20.caller(block_identifier=txreceipt.blockNumber).balanceOf( - ADDRS["validator"] - ) - - # check block bloom - block = w3.eth.get_block(txreceipt.blockNumber) - assert "baseFeePerGas" in block - assert block.miner == "0x0000000000000000000000000000000000000000" - bloom = BloomFilter(big_endian_to_int(block.logsBloom)) - assert HexBytes(erc20.address) in bloom - for topic in expect_log["topics"]: - assert topic in bloom - - tx1 = w3.eth.get_transaction(txhash) - tx2 = w3.eth.get_transaction_by_block( - txreceipt.blockNumber, txreceipt.transactionIndex - ) - exp_tx = AttributeDict( - { - "from": "0x57f96e6B86CdeFdB3d412547816a82E3E0EbF9D2", - "gas": exp_gas_used, - "input": HexBytes( - "0xa9059cbb000000000000000000000000378c50d9264c63f3f92b806d4ee56e" - "9d86ffb3ec000000000000000000000000000000000000000000000000000000" - "000000000a" - ), - "nonce": 2, - "to": erc20.address, - "transactionIndex": 0, - "value": 0, - "type": 2, - "accessList": [], - "chainId": 777, - } - ) - assert tx1 == tx2 - for name in exp_tx.keys(): - assert tx1[name] == tx2[name] == exp_tx[name] - - print( - w3.eth.get_logs( - {"fromBlock": txreceipt.blockNumber, "toBlock": txreceipt.blockNumber} - ) - ) diff --git a/integration_tests/test_replay_block.py b/integration_tests/test_replay_block.py deleted file mode 100644 index a7a65eccc7..0000000000 --- a/integration_tests/test_replay_block.py +++ /dev/null @@ -1,141 +0,0 @@ -from pathlib import Path - -import pytest -import web3 -from web3._utils.method_formatters import receipt_formatter -from web3.datastructures import AttributeDict - -from .network import setup_custom_cronos -from .utils import ( - ADDRS, - CONTRACTS, - KEYS, - deploy_contract, - send_raw_transactions, - sign_transaction, - wait_for_new_blocks, -) - -pytestmark = pytest.mark.slow - - -@pytest.fixture(scope="module") -def custom_cronos(tmp_path_factory): - path = tmp_path_factory.mktemp("cronos") - yield from setup_custom_cronos( - path, 26000, Path(__file__).parent / "configs/low_block_gas_limit.jsonnet" - ) - - -@pytest.mark.skip(reason="block gas limit is disabled") -def test_block_overflow(custom_cronos): - w3: web3.Web3 = custom_cronos.w3 - contract = deploy_contract( - w3, - CONTRACTS["TestMessageCall"], - key=KEYS["community"], - ) - iterations = 400 - gas_limit = 800000 - gas_price = 200000000000 - names = ["validator", "validator2"] - addrs = [ADDRS[names[0]], ADDRS[names[1]]] - keys = [KEYS[names[0]], KEYS[names[1]]] - - gas_limits = {} - blks = [] - success = None - fail = None - for i in range(10): - raw_transactions = [] - nonces = {} - begin_balances = {} - for i, key_from in enumerate(keys): - addr = addrs[i] - nonces[addr] = w3.eth.get_transaction_count(addr) - begin_balances[addr] = w3.eth.get_balance(addr) - gas_limits[addr] = gas_limit + i - tx = contract.functions.test(iterations).build_transaction( - { - "nonce": nonces[addr], - "gas": gas_limits[addr], - "gasPrice": gas_price, - } - ) - signed = sign_transaction(w3, tx, key_from) - raw_transactions.append(signed.rawTransaction) - - # wait block update - block_num_0 = wait_for_new_blocks(custom_cronos.cosmos_cli(), 1, sleep=0.1) - print(f"block number start: {block_num_0}") - sended_hash_set = send_raw_transactions(w3, raw_transactions) - for h in sended_hash_set: - res = w3.eth.wait_for_transaction_receipt(h) - addr = res["from"] - - # check sender's nonce is increased once, which means both txs are executed. - assert nonces[addr] + 1 == w3.eth.get_transaction_count(addr) - # check sender's balance is deducted as expected - diff = begin_balances[addr] - w3.eth.get_balance(addr) - assert res["gasUsed"] * gas_price == diff - - blks.append(res.blockNumber) - if res.status == 1: - success = res - elif res.status == 0: - fail = res - - if all(blk == blks[0] for blk in blks): - break - print( - "tx1 and tx2 are included in two different blocks, retry now.", - blks, - ) - else: - assert False, "timeout" - - # the first tx succeeds. - assert success.status == 1 - assert success.gasUsed < gas_limits[success["from"]] - assert success.cumulativeGasUsed == success.gasUsed - - # the second tx should fail and cost the whole gasLimit - assert fail.status == 0 - assert fail.gasUsed == gas_limits[fail["from"]] - assert fail.cumulativeGasUsed == success.cumulativeGasUsed + fail.gasUsed - - # check get block apis - assert w3.eth.get_block(success.blockNumber).transactions == [ - success.transactionHash, - fail.transactionHash, - ] - res = w3.eth.get_transaction_by_block(fail.blockNumber, fail.transactionIndex) - assert res.hash == fail.transactionHash - - rsp = w3.provider.make_request( - "cronos_replayBlock", [hex(success.blockNumber), False] - ) - assert "error" not in rsp, rsp["error"] - assert 2 == len(rsp["result"]) - - # check the replay receipts are the same - replay_receipts = [AttributeDict(receipt_formatter(item)) for item in rsp["result"]] - assert replay_receipts[0].gasUsed == replay_receipts[1].gasUsed == success.gasUsed - assert replay_receipts[0].status == replay_receipts[1].status == success.status - assert ( - replay_receipts[0].logsBloom - == replay_receipts[1].logsBloom - == success.logsBloom - ) - assert replay_receipts[0].cumulativeGasUsed == success.cumulativeGasUsed - assert replay_receipts[1].cumulativeGasUsed == success.cumulativeGasUsed * 2 - - # check the postUpgrade mode - rsp = w3.provider.make_request( - "cronos_replayBlock", [hex(success.blockNumber), True] - ) - assert "error" not in rsp, rsp["error"] - assert 2 == len(rsp["result"]) - replay_receipts = [AttributeDict(receipt_formatter(item)) for item in rsp["result"]] - assert replay_receipts[1].status == 0 - assert replay_receipts[1].gasUsed == gas_limits[replay_receipts[1]["from"]] diff --git a/integration_tests/test_rollback.py b/integration_tests/test_rollback.py deleted file mode 100644 index 1ae2ea9ebb..0000000000 --- a/integration_tests/test_rollback.py +++ /dev/null @@ -1,96 +0,0 @@ -import configparser -import subprocess -from pathlib import Path - -import pytest -from pystarport import ports -from pystarport.cluster import SUPERVISOR_CONFIG_FILE - -from .network import setup_custom_cronos -from .utils import supervisorctl, wait_for_block, wait_for_port - -pytestmark = pytest.mark.slow - - -def update_node2_cmd(path, cmd, i): - ini_path = path / SUPERVISOR_CONFIG_FILE - ini = configparser.RawConfigParser() - ini.read(ini_path) - for section in ini.sections(): - if section == f"program:cronos_777-1-node{i}": - ini[section].update( - { - "command": f"{cmd} start --home %(here)s/node{i}", - "autorestart": "false", # don't restart when stopped - } - ) - with ini_path.open("w") as fp: - ini.write(fp) - - -def post_init(broken_binary): - def inner(path, base_port, config): - chain_id = "cronos_777-1" - update_node2_cmd(path / chain_id, broken_binary, 2) - - return inner - - -@pytest.fixture(scope="module") -def custom_cronos(tmp_path_factory): - path = tmp_path_factory.mktemp("rollback") - - cmd = [ - "nix-build", - "--no-out-link", - Path(__file__).parent / "configs/broken-cronosd.nix", - ] - print(*cmd) - broken_binary = Path(subprocess.check_output(cmd).strip().decode()) / "bin/cronosd" - print(broken_binary) - - # init with genesis binary - yield from setup_custom_cronos( - path, - 26400, - Path(__file__).parent / "configs/rollback.jsonnet", - post_init=post_init(broken_binary), - wait_port=False, - ) - - -def test_rollback(custom_cronos): - """ - test using rollback command to fix app-hash mismatch situation. - - the broken node will sync up to block 10 then crash. - - use rollback command to rollback the db. - - switch to correct binary should make the node syncing again. - """ - wait_for_port(ports.rpc_port(custom_cronos.base_port(2))) - - print("wait for node2 to sync the first 10 blocks") - cli2 = custom_cronos.cosmos_cli(2) - wait_for_block(cli2, 10) - - print("wait for a few more blocks on the healthy nodes") - cli = custom_cronos.cosmos_cli(0) - wait_for_block(cli, 13) - - # (app hash mismatch happens after the 10th block, detected in the 11th block) - print("check node2 get stuck at block 10") - assert cli2.block_height() == 10 - - print("stop node2") - supervisorctl(custom_cronos.base_dir / "../tasks.ini", "stop", "cronos_777-1-node2") - - print("do rollback on node2") - cli2.rollback() - - print("switch to normal binary") - update_node2_cmd(custom_cronos.base_dir, "cronosd", 2) - supervisorctl(custom_cronos.base_dir / "../tasks.ini", "update") - wait_for_port(ports.rpc_port(custom_cronos.base_port(2))) - - print("check node2 sync again") - cli2 = custom_cronos.cosmos_cli(2) - wait_for_block(cli2, 15) diff --git a/integration_tests/test_streamer.py b/integration_tests/test_streamer.py deleted file mode 100644 index c7c4f31d76..0000000000 --- a/integration_tests/test_streamer.py +++ /dev/null @@ -1,63 +0,0 @@ -import pytest -from cprotobuf import Field, ProtoEntity, decode_primitive -from hexbytes import HexBytes - -from .utils import ADDRS - - -class StoreKVPairs(ProtoEntity): - # the store key for the KVStore this pair originates from - store_key = Field("string", 1) - # true indicates a delete operation - delete = Field("bool", 2) - key = Field("bytes", 3) - value = Field("bytes", 4) - - -def decode_stream_file(data, entry_cls=StoreKVPairs): - """ - StoreKVPairs, StoreKVPairs, ... - """ - assert int.from_bytes(data[:8], "big") + 8 == len(data), "incomplete file" - - items = [] - offset = 8 - while offset < len(data): - size, n = decode_primitive(data[offset:], "uint64") - offset += n - item = entry_cls() - item.ParseFromString(data[offset : offset + size]) - items.append(item) - offset += size - return items - - -@pytest.mark.skip(reason="file streamer is not useful for now") -def test_streamers(cronos): - """ - - check the streaming files are created - - try to parse the state change sets - """ - # inspect the first state change of the first tx in genesis - # the InitChainer is committed together with the first block. - path = cronos.node_home(0) / "data/file_streamer/block-1-data" - items = decode_stream_file(open(path, "rb").read()) - # creation of the validator account - assert items[0].store_key == "acc" - # the writes are sorted by key, find the minimal address - min_addr = min(ADDRS.values()) - assert items[0].key == b"\x01" + HexBytes(min_addr) - - -if __name__ == "__main__": - import binascii - import sys - - items = decode_stream_file(open(sys.argv[1], "rb").read()) - for item in items: - print( - item.store_key, - item.delete, - binascii.hexlify(item.key).decode(), - binascii.hexlify(item.value).decode(), - ) diff --git a/integration_tests/test_subscribe.py b/integration_tests/test_subscribe.py deleted file mode 100644 index 29c52c36f7..0000000000 --- a/integration_tests/test_subscribe.py +++ /dev/null @@ -1,169 +0,0 @@ -import asyncio -import json -import time -from collections import defaultdict - -import websockets -from eth_utils import abi -from hexbytes import HexBytes -from pystarport import ports -from web3 import Web3 - -from .network import Cronos -from .utils import ( - ADDRS, - CONTRACTS, - KEYS, - deploy_contract, - send_raw_transactions, - send_transaction, - sign_transaction, - wait_for_new_blocks, - wait_for_port, -) - - -class Client: - def __init__(self, ws): - self._ws = ws - self._gen_id = 0 - self._subs = defaultdict(asyncio.Queue) - self._rsps = defaultdict(asyncio.Queue) - - def gen_id(self): - self._gen_id += 1 - return self._gen_id - - async def receive_loop(self): - while True: - msg = json.loads(await self._ws.recv()) - if "id" in msg: - # responses - await self._rsps[msg["id"]].put(msg) - else: - # subscriptions - assert msg["method"] == "eth_subscription" - sub_id = msg["params"]["subscription"] - await self._subs[sub_id].put(msg["params"]["result"]) - - async def recv_response(self, rpcid): - rsp = await self._rsps[rpcid].get() - del self._rsps[rpcid] - return rsp - - async def recv_subscription(self, sub_id): - return await self._subs[sub_id].get() - - async def subscribe(self, *args): - rpcid = self.gen_id() - await self._ws.send( - json.dumps({"id": rpcid, "method": "eth_subscribe", "params": args}) - ) - rsp = await self.recv_response(rpcid) - assert "error" not in rsp - return rsp["result"] - - def sub_qsize(self, sub_id): - return self._subs[sub_id].qsize() - - async def unsubscribe(self, sub_id): - rpcid = self.gen_id() - await self._ws.send( - json.dumps({"id": rpcid, "method": "eth_unsubscribe", "params": [sub_id]}) - ) - rsp = await self.recv_response(rpcid) - assert "error" not in rsp - return rsp["result"] - - -# TestEvent topic from TestMessageCall contract calculated from event signature -TEST_EVENT_TOPIC = Web3.keccak(text="TestEvent(uint256)") - - -def test_subscribe_basic(cronos: Cronos): - """ - test basic subscribe and unsubscribe - """ - wait_for_port(ports.evmrpc_ws_port(cronos.base_port(0))) - cli = cronos.cosmos_cli() - loop = asyncio.get_event_loop() - - async def assert_unsubscribe(c: Client, sub_id): - assert await c.unsubscribe(sub_id) - # check no more messages - await loop.run_in_executor(None, wait_for_new_blocks, cli, 2) - assert c.sub_qsize(sub_id) == 0 - # unsubscribe again return False - assert not await c.unsubscribe(sub_id) - - async def subscriber_test(c: Client): - sub_id = await c.subscribe("newHeads") - # wait for three new blocks - msgs = [await c.recv_subscription(sub_id) for i in range(3)] - # check blocks are consecutive - assert int(msgs[1]["number"], 0) == int(msgs[0]["number"], 0) + 1 - assert int(msgs[2]["number"], 0) == int(msgs[1]["number"], 0) + 1 - await assert_unsubscribe(c, sub_id) - - async def transfer_test(c: Client, w3, contract, address): - sub_id = await c.subscribe("logs", {"address": address}) - to = ADDRS["community"] - _from = ADDRS["validator"] - total = 5 - topic = abi.event_signature_to_log_topic("Transfer(address,address,uint256)") - for i in range(total): - amt = 10 + i - tx = contract.functions.transfer(to, amt).build_transaction({"from": _from}) - txreceipt = send_transaction(w3, tx) - assert len(txreceipt.logs) == 1 - expect_log = { - "address": address, - "topics": [ - HexBytes(topic), - HexBytes(b"\x00" * 12 + HexBytes(_from)), - HexBytes(b"\x00" * 12 + HexBytes(to)), - ], - "data": HexBytes(b"\x00" * 31 + HexBytes(amt)), - } - assert expect_log.items() <= txreceipt.logs[0].items() - msgs = [await c.recv_subscription(sub_id) for i in range(total)] - assert len(msgs) == total - await assert_unsubscribe(c, sub_id) - - async def logs_test(c: Client, w3, contract, address): - sub_id = await c.subscribe("logs", {"address": address}) - iterations = 10000 - tx = contract.functions.test(iterations).build_transaction() - raw_transactions = [] - for key_from in KEYS.values(): - signed = sign_transaction(w3, tx, key_from) - raw_transactions.append(signed.rawTransaction) - send_raw_transactions(w3, raw_transactions) - total = len(KEYS) * iterations - msgs = [await c.recv_subscription(sub_id) for i in range(total)] - assert len(msgs) == total - assert all(msg["topics"] == [TEST_EVENT_TOPIC.hex()] for msg in msgs) - await assert_unsubscribe(c, sub_id) - - async def async_test(): - async with websockets.connect(cronos.w3_ws_endpoint()) as ws: - c = Client(ws) - t = asyncio.create_task(c.receive_loop()) - # run three subscribers concurrently - await asyncio.gather(*[subscriber_test(c) for i in range(3)]) - contract = deploy_contract(cronos.w3, CONTRACTS["TestERC20A"]) - address = contract.address - await transfer_test(c, cronos.w3, contract, address) - contract = deploy_contract(cronos.w3, CONTRACTS["TestMessageCall"]) - inner = contract.caller.inner() - begin = time.time() - await logs_test(c, cronos.w3, contract, inner) - print("msg call time", time.time() - begin) - t.cancel() - try: - await t - except asyncio.CancelledError: - pass - - timeout = 100 - loop.run_until_complete(asyncio.wait_for(async_test(), timeout)) diff --git a/integration_tests/test_upgrade.py b/integration_tests/test_upgrade.py deleted file mode 100644 index 1b1729d8e0..0000000000 --- a/integration_tests/test_upgrade.py +++ /dev/null @@ -1,296 +0,0 @@ -import json -import shutil -import stat -import subprocess -from contextlib import contextmanager -from datetime import datetime, timedelta -from pathlib import Path - -import pytest -import requests -from pystarport import ports -from pystarport.cluster import SUPERVISOR_CONFIG_FILE - -from .network import Cronos, setup_custom_cronos -from .utils import ( - ADDRS, - CONTRACTS, - approve_proposal, - assert_gov_params, - deploy_contract, - edit_ini_sections, - get_consensus_params, - get_send_enable, - send_transaction, - wait_for_block, - wait_for_new_blocks, - wait_for_port, -) - -pytestmark = pytest.mark.upgrade - - -@pytest.fixture(scope="module") -def custom_cronos(tmp_path_factory): - yield from setup_cronos_test(tmp_path_factory) - - -def get_txs(base_port, end): - port = ports.rpc_port(base_port) - res = [] - for h in range(1, end): - url = f"http://127.0.0.1:{port}/block_results?height={h}" - res.append(requests.get(url).json().get("result")["txs_results"]) - return res - - -def init_cosmovisor(home): - """ - build and setup cosmovisor directory structure in each node's home directory - """ - cosmovisor = home / "cosmovisor" - cosmovisor.mkdir() - (cosmovisor / "upgrades").symlink_to("../../../upgrades") - (cosmovisor / "genesis").symlink_to("./upgrades/genesis") - - -def post_init(path, base_port, config): - """ - prepare cosmovisor for each node - """ - chain_id = "cronos_777-1" - data = path / chain_id - cfg = json.loads((data / "config.json").read_text()) - for i, _ in enumerate(cfg["validators"]): - home = data / f"node{i}" - init_cosmovisor(home) - - edit_ini_sections( - chain_id, - data / SUPERVISOR_CONFIG_FILE, - lambda i, _: { - "command": f"cosmovisor run start --home %(here)s/node{i}", - "environment": ( - "DAEMON_NAME=cronosd," - "DAEMON_SHUTDOWN_GRACE=1m," - "UNSAFE_SKIP_BACKUP=true," - f"DAEMON_HOME=%(here)s/node{i}" - ), - }, - ) - - -def setup_cronos_test(tmp_path_factory): - path = tmp_path_factory.mktemp("upgrade") - port = 26200 - nix_name = "upgrade-test-package" - cfg_name = "cosmovisor" - configdir = Path(__file__).parent - cmd = [ - "nix-build", - configdir / f"configs/{nix_name}.nix", - ] - print(*cmd) - subprocess.run(cmd, check=True) - - # copy the content so the new directory is writable. - upgrades = path / "upgrades" - shutil.copytree("./result", upgrades) - mod = stat.S_IRWXU - upgrades.chmod(mod) - for d in upgrades.iterdir(): - d.chmod(mod) - - # init with genesis binary - with contextmanager(setup_custom_cronos)( - path, - port, - configdir / f"configs/{cfg_name}.jsonnet", - post_init=post_init, - chain_binary=str(upgrades / "genesis/bin/cronosd"), - ) as cronos: - yield cronos - - -def assert_evm_params(cli, expected, height): - params = cli.query_params("evm", height=height) - del params["header_hash_num"] - assert expected == params - - -def check_basic_tx(c): - # check basic tx works - wait_for_port(ports.evmrpc_port(c.base_port(0))) - receipt = send_transaction( - c.w3, - { - "to": ADDRS["community"], - "value": 1000, - "maxFeePerGas": 10000000000000, - "maxPriorityFeePerGas": 10000, - }, - ) - assert receipt.status == 1 - - -def exec(c, tmp_path_factory): - """ - - propose an upgrade and pass it - - wait for it to happen - - it should work transparently - """ - cli = c.cosmos_cli() - base_port = c.base_port(0) - port = ports.api_port(base_port) - send_enable = [ - {"denom": "basetcro", "enabled": False}, - {"denom": "stake", "enabled": True}, - ] - p = get_send_enable(port) - assert sorted(p, key=lambda x: x["denom"]) == send_enable - - # export genesis from old version - c.supervisorctl("stop", "all") - migrate = tmp_path_factory.mktemp("migrate") - file_path0 = Path(migrate / "old.json") - with open(file_path0, "w") as fp: - json.dump(json.loads(cli.export()), fp) - fp.flush() - - c.supervisorctl("start", "cronos_777-1-node0", "cronos_777-1-node1") - wait_for_port(ports.evmrpc_port(base_port)) - wait_for_new_blocks(cli, 1) - - def do_upgrade(plan_name, target, mode=None): - rsp = cli.gov_propose_legacy( - "community", - "software-upgrade", - { - "name": plan_name, - "title": "upgrade test", - "description": "ditto", - "upgrade-height": target, - "deposit": "10000basetcro", - }, - mode=mode, - ) - assert rsp["code"] == 0, rsp["raw_log"] - approve_proposal(c, rsp["logs"][0]["events"]) - - # update cli chain binary - c.chain_binary = ( - Path(c.chain_binary).parent.parent.parent / f"{plan_name}/bin/cronosd" - ) - # block should pass the target height - wait_for_block(c.cosmos_cli(), target + 2, timeout=480) - wait_for_port(ports.rpc_port(base_port)) - return c.cosmos_cli() - - # test migrate keystore - cli.migrate_keystore() - height = cli.block_height() - target_height0 = height + 15 - print("upgrade v1.1 height", target_height0) - - cli = do_upgrade("v1.1.0", target_height0, "block") - check_basic_tx(c) - - height = cli.block_height() - target_height1 = height + 15 - print("upgrade v1.2 height", target_height1) - - w3 = c.w3 - random_contract = deploy_contract( - w3, - CONTRACTS["Random"], - ) - with pytest.raises(ValueError) as e_info: - random_contract.caller.randomTokenId() - assert "invalid memory address or nil pointer dereference" in str(e_info.value) - contract = deploy_contract(w3, CONTRACTS["TestERC20A"]) - old_height = w3.eth.block_number - old_balance = w3.eth.get_balance(ADDRS["validator"], block_identifier=old_height) - old_base_fee = w3.eth.get_block(old_height).baseFeePerGas - old_erc20_balance = contract.caller(block_identifier=old_height).balanceOf( - ADDRS["validator"] - ) - print("old values", old_height, old_balance, old_base_fee) - - cli = do_upgrade("v1.2", target_height1) - check_basic_tx(c) - - # deploy contract should still work - deploy_contract(w3, CONTRACTS["Greeter"]) - # random should work - res = random_contract.caller.randomTokenId() - assert res > 0, res - - # query json-rpc on older blocks should success - assert old_balance == w3.eth.get_balance( - ADDRS["validator"], block_identifier=old_height - ) - assert old_base_fee == w3.eth.get_block(old_height).baseFeePerGas - - # check eth_call works on older blocks - assert old_erc20_balance == contract.caller(block_identifier=old_height).balanceOf( - ADDRS["validator"] - ) - # check consensus params - port = ports.rpc_port(base_port) - res = get_consensus_params(port, w3.eth.get_block_number()) - assert res["block"]["max_gas"] == "60000000" - - # check bank send enable - p = cli.query_bank_send() - assert sorted(p, key=lambda x: x["denom"]) == send_enable - - rsp = cli.query_params("icaauth") - assert rsp["min_timeout_duration"] == "3600s", rsp - max_callback_gas = cli.query_params()["max_callback_gas"] - assert max_callback_gas == "50000", max_callback_gas - - e0 = cli.query_params("evm", height=target_height0 - 1) - e1 = cli.query_params("evm", height=target_height1 - 1) - f0 = cli.query_params("feemarket", height=target_height0 - 1) - f1 = cli.query_params("feemarket", height=target_height1 - 1) - assert e0["evm_denom"] == e1["evm_denom"] == "basetcro" - - # update the genesis time = current time + 5 secs - newtime = datetime.utcnow() + timedelta(seconds=5) - newtime = newtime.replace(tzinfo=None).isoformat("T") + "Z" - config = c.config - config["genesis-time"] = newtime - for i, _ in enumerate(config["validators"]): - genesis = json.load(open(file_path0)) - genesis["genesis_time"] = config.get("genesis-time") - file = c.cosmos_cli(i).data_dir / "config/genesis.json" - file.write_text(json.dumps(genesis)) - c.supervisorctl("start", "cronos_777-1-node0", "cronos_777-1-node1") - wait_for_new_blocks(c.cosmos_cli(), 1) - - height = cli.block_height() - target_height2 = height + 15 - print("upgrade v1.3 height", target_height2) - txs = get_txs(base_port, height) - do_upgrade("v1.3", target_height2) - assert txs == get_txs(base_port, height) - - height = cli.block_height() - target_height3 = height + 15 - print("upgrade v1.4 height", target_height2) - gov_param = cli.query_params("gov") - - cli = do_upgrade("v1.4", target_height3) - - assert_evm_params(cli, e0, target_height0 - 1) - assert_evm_params(cli, e1, target_height1 - 1) - assert f0 == cli.query_params("feemarket", height=target_height0 - 1) - assert f1 == cli.query_params("feemarket", height=target_height1 - 1) - assert cli.query_params("evm")["header_hash_num"] == "256", p - with pytest.raises(AssertionError): - cli.query_params("icaauth") - assert_gov_params(cli, gov_param) - - -def test_cosmovisor_upgrade(custom_cronos: Cronos, tmp_path_factory): - exec(custom_cronos, tmp_path_factory) diff --git a/integration_tests/test_versiondb.py b/integration_tests/test_versiondb.py deleted file mode 100644 index d79dfa5ac3..0000000000 --- a/integration_tests/test_versiondb.py +++ /dev/null @@ -1,102 +0,0 @@ -import shutil -import tempfile - -import tomlkit -from pystarport import ports - -from .network import Cronos -from .utils import ADDRS, send_transaction, wait_for_port - - -def test_versiondb_migration(cronos: Cronos): - """ - test versiondb migration commands. - node0 has memiavl and versiondb enabled while node1 don't, - - stop all the nodes - - dump change set from node1's application.db - - verify change set and save snapshot - - restore pruned application.db from the snapshot - - replace node1's application.db with the restored one - - rebuild versiondb for node0 - - start the nodes, now check: - - the network can grow - - node0 do support historical queries - - node1 don't support historical queries - """ - w3 = cronos.w3 - community = ADDRS["community"] - balance0 = w3.eth.get_balance(community) - block0 = w3.eth.block_number - - tx = { - "from": ADDRS["validator"], - "to": community, - "value": 1000, - } - send_transaction(w3, tx) - balance1 = w3.eth.get_balance(community) - block1 = w3.eth.block_number - - # stop the network first - print("stop all nodes") - print(cronos.supervisorctl("stop", "all")) - cli0 = cronos.cosmos_cli(i=0) - cli1 = cronos.cosmos_cli(i=1) - - changeset_dir = tempfile.mkdtemp(dir=cronos.base_dir) - print("dump to:", changeset_dir) - print(cli1.changeset_dump(changeset_dir)) - snapshot_dir = tempfile.mkdtemp(dir=cronos.base_dir) - print("verify and save to snapshot:", snapshot_dir) - _, commit_info = cli0.changeset_verify(changeset_dir, save_snapshot=snapshot_dir) - latest_version = commit_info["version"] - - # replace existing `application.db` - app_db1 = cli1.data_dir / "data/application.db" - print("replace node db:", app_db1) - shutil.rmtree(app_db1) - print(cli1.changeset_restore_app_db(snapshot_dir, app_db1)) - - print("restore versiondb for node0") - sst_dir = tempfile.mkdtemp(dir=cronos.base_dir) - print(cli0.changeset_build_versiondb_sst(changeset_dir, sst_dir)) - # ingest-versiondb-sst expects an empty database - shutil.rmtree(cli0.data_dir / "data/versiondb") - print( - cli0.changeset_ingest_versiondb_sst( - cli0.data_dir / "data/versiondb", sst_dir, maximum_version=latest_version - ) - ) - - # force node1's app-db-backend to be rocksdb - patch_app_db_backend(cli1.data_dir / "config/app.toml", "rocksdb") - - print("start all nodes") - print(cronos.supervisorctl("start", "cronos_777-1-node0", "cronos_777-1-node1")) - wait_for_port(ports.evmrpc_port(cronos.base_port(0))) - wait_for_port(ports.evmrpc_port(cronos.base_port(1))) - - assert w3.eth.get_balance(community, block_identifier=block0) == balance0 - assert w3.eth.get_balance(community, block_identifier=block1) == balance1 - assert w3.eth.get_balance(community) == balance1 - - # check query still works, node1 don't enable versiondb, - # so we are testing iavl query here. - w3_1 = cronos.node_w3(1) - assert w3_1.eth.get_balance(community) == balance1 - - # check the chain is still growing - send_transaction( - w3, - { - "from": community, - "to": ADDRS["validator"], - "value": 1000, - }, - ) - - -def patch_app_db_backend(path, backend): - cfg = tomlkit.parse(path.read_text()) - cfg["app-db-backend"] = backend - path.write_text(tomlkit.dumps(cfg)) diff --git a/integration_tests/test_vesting.py b/integration_tests/test_vesting.py deleted file mode 100644 index 28f97a316d..0000000000 --- a/integration_tests/test_vesting.py +++ /dev/null @@ -1,21 +0,0 @@ -import time - - -def test_create_account(cronos): - """ - test create vesting account is disabled: - """ - cli = cronos.cosmos_cli() - src = "vesting" - addr = cli.create_account(src)["address"] - denom = "basetcro" - balance = cli.balance(addr, denom) - assert balance == 0 - amount = 10000 - fee = 4000000000000000 - amt = f"{amount}{denom}" - end_time = int(time.time()) + 3000 - fees = f"{fee}{denom}" - res = cli.create_vesting_account(addr, amt, end_time, from_="validator", fees=fees) - assert res["code"] != 0 - assert "vesting messages are not supported" in res["raw_log"] diff --git a/integration_tests/utils.py b/integration_tests/utils.py index adbdaa2bf9..c4474d8ce6 100644 --- a/integration_tests/utils.py +++ b/integration_tests/utils.py @@ -122,11 +122,14 @@ def wait_for_block(cli, height, timeout=240): raise TimeoutError(f"wait for block {height} timeout") -def wait_for_new_blocks(cli, n, sleep=0.5): +def wait_for_new_blocks(cli, n, sleep=0.5, timeout=240): cur_height = begin_height = int(get_sync_info(cli.status())["latest_block_height"]) + start_time = time.time() while cur_height - begin_height < n: time.sleep(sleep) cur_height = int(get_sync_info(cli.status())["latest_block_height"]) + if time.time() - start_time > timeout: + raise TimeoutError(f"wait for block {begin_height + n} timeout") return cur_height diff --git a/testground/benchmark/compositions/docker-compose.jsonnet b/testground/benchmark/compositions/docker-compose.jsonnet index 946ce54d86..5bc1fdc193 100644 --- a/testground/benchmark/compositions/docker-compose.jsonnet +++ b/testground/benchmark/compositions/docker-compose.jsonnet @@ -1,7 +1,7 @@ std.manifestYamlDoc({ services: { ['testplan-' + i]: { - image: 'cronos-testground:latest', + image: 'cronos-testground:qbnc62swkxv8kjlrhn8pqimv3b5qmi5r', command: 'stateless-testcase run', container_name: 'testplan-' + i, volumes: [