├── .dockerignore
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ ├── config.yml
│ ├── documentation.yml
│ ├── feature_request.yml
│ └── questions.yml
├── pull_request_template.md
└── workflows
│ ├── branch.yml
│ ├── cosmovisor.yml
│ ├── goreleaser.yml
│ ├── pull-request.yml
│ ├── release.yml
│ └── unit-coverage.yml
├── .gitignore
├── .golangci.yml
├── .goreleaser.yml
├── .testcoverage.yml
├── Dockerfile
├── Makefile
├── app
├── ante.go
├── app.go
├── encoding.go
├── export.go
├── genesis.go
├── precompiles.go
├── simulation_test.go
├── upgrades.go
├── upgrades
│ ├── v4
│ │ ├── constants.go
│ │ └── upgrades.go
│ ├── v5
│ │ ├── constants.go
│ │ └── upgrades.go
│ ├── v6
│ │ ├── constants.go
│ │ └── upgrades.go
│ ├── v7
│ │ ├── constants.go
│ │ └── upgrades.go
│ └── v8
│ │ ├── constants.go
│ │ └── upgrades.go
└── utils.go
├── buf.work.yaml
├── cmd
└── exrpd
│ ├── cmd
│ ├── config.go
│ ├── genaccounts.go
│ └── root.go
│ └── main.go
├── docs
├── docs.go
├── static
│ └── openapi.yml
└── template
│ └── index.tpl
├── go.mod
├── go.sum
├── local-node.sh
├── proto
├── buf.gen.gogo.yaml
├── buf.lock
├── buf.yaml
├── poa
│ ├── genesis.proto
│ ├── params.proto
│ ├── query.proto
│ └── tx.proto
└── scripts
│ ├── protoc-swagger-gen.sh
│ └── protocgen.sh
├── readme.md
├── scripts
└── mockgen.sh
├── tests
├── integration
│ ├── network.go
│ ├── poa_test.go
│ ├── slashing_test.go
│ ├── suite.go
│ └── suite_test.go
├── sim
│ └── params.json
└── upgrade
│ ├── README.md
│ ├── network.go
│ ├── suite.go
│ ├── suite_test.go
│ └── upgrade-state.json
├── testutil
├── integration
│ ├── common
│ │ ├── factory
│ │ │ ├── base.go
│ │ │ ├── distribution.go
│ │ │ ├── factory.go
│ │ │ ├── fund.go
│ │ │ ├── helper.go
│ │ │ ├── sign.go
│ │ │ ├── staking.go
│ │ │ └── types.go
│ │ ├── grpc
│ │ │ ├── account.go
│ │ │ ├── authz.go
│ │ │ ├── bank.go
│ │ │ ├── distribution.go
│ │ │ ├── feemarket.go
│ │ │ ├── gov.go
│ │ │ ├── grpc.go
│ │ │ └── staking.go
│ │ ├── keyring
│ │ │ └── keyring.go
│ │ └── network
│ │ │ └── network.go
│ └── exrp
│ │ ├── common
│ │ ├── clients.go
│ │ ├── config.go
│ │ ├── consensus.go
│ │ ├── network.go
│ │ └── setup.go
│ │ ├── integration
│ │ ├── abci.go
│ │ ├── config.go
│ │ ├── ibc.go
│ │ ├── keepers.go
│ │ ├── network.go
│ │ ├── setup.go
│ │ └── unit_network.go
│ │ ├── upgrade
│ │ ├── abci.go
│ │ ├── config.go
│ │ ├── ibc.go
│ │ ├── keepers.go
│ │ ├── network.go
│ │ └── unit_network.go
│ │ └── utils
│ │ ├── abci.go
│ │ └── gov.go
└── sample
│ └── sample.go
├── tools
├── cosmovisor
│ ├── Dockerfile
│ └── init.sh
└── tools.go
└── x
└── poa
├── ante
├── poa.go
└── poa_test.go
├── keeper
├── common_test.go
├── genesis.go
├── keeper.go
├── keeper_test.go
├── msg_server.go
├── msg_server_add_validator.go
├── msg_server_add_validator_test.go
├── msg_server_remove_validator.go
├── msg_server_remove_validator_test.go
├── params.go
├── query.go
└── query_params.go
├── module.go
├── module_simulation.go
├── simulation
├── proposals.go
└── proposals_test.go
├── testutil
├── expected_keepers_mock.go
├── expected_msg_server.go
├── expected_msg_server_mock.go
├── keys.go
├── keys_mock.go
├── staking_hooks.go
├── staking_hooks_mock.go
├── tx.go
└── tx_mock.go
└── types
├── codec.go
├── errors.go
├── events.go
├── expected_keepers.go
├── genesis.go
├── genesis.pb.go
├── keys.go
├── message_add_validator.go
├── message_remove_validator.go
├── params.go
├── params.pb.go
├── query.pb.go
├── query.pb.gw.go
├── tx.pb.go
└── types.go
/.dockerignore:
--------------------------------------------------------------------------------
1 | .github
2 | .gitignore
3 | .idea
4 | Dockerfile
5 | release
6 | build
7 | .dockerignore
8 |
9 | vue/node_modules
10 | vue/dist
11 | build/
12 | release/
13 | .idea/
14 | .vscode/
15 | .DS_Store
16 |
17 |
18 | .exrpd/
19 |
20 | bin/
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # CODEOWNERS: https://help.github.com/articles/about-codeowners/
2 |
3 | * @xrplevm/core
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: "🐞 Bug Report"
2 | description: "Report a reproducible bug"
3 | labels: ["bug"]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: Thank you for reporting a bug! Your feedback helps us improve. Please complete the form below with as much detail as possible.
8 | - type: textarea
9 | attributes:
10 | label: Steps to reproduce
11 | description: Provide a detailed list of steps to reproduce the bug.
12 | placeholder: "1. 2. 3. 4."
13 | value: "Bug steps"
14 | validations:
15 | required: true
16 | - type: textarea
17 | attributes:
18 | label: Expected behavior
19 | description: Describe what you expected to happen.
20 | placeholder: "Expected behavior"
21 | value: "Expected behavior"
22 | validations:
23 | required: true
24 | - type: textarea
25 | attributes:
26 | label: Actual behavior
27 | description: Describe what actually happened.
28 | placeholder: "Actual behavior"
29 | value: "Actual behavior"
30 | validations:
31 | required: true
32 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: EVM Sidechain docs
4 | url: https://opensource.ripple.com/docs/evm-sidechain/intro-to-evm-sidechain/
5 | about: Learn more about the EVM Sidechain.
6 | - name: Peersyst
7 | url: https://peersyst.com
8 | about: Contact us for any questions or support.
9 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/documentation.yml:
--------------------------------------------------------------------------------
1 | name: "📃 Documentation Bug"
2 | description: "Report inaccuracies or omissions in the documentation."
3 | title: "[docs] "
4 | labels: ["docs"]
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: Thank you for helping us improve the documentation! Your contribution is invaluable in enhancing the user experience.
9 | - type: textarea
10 | attributes:
11 | label: Summary
12 | description: "Please succinctly describe the inaccuracies or omissions you have identified in the documentation."
13 | placeholder: "Enter a brief summary of the issue."
14 | validations:
15 | required: true
16 | - type: input
17 | attributes:
18 | label: Link to the Related Documentation Page
19 | description: "Please provide a link to the documentation page that requires attention."
20 | placeholder: "Enter the URL of the documentation page."
21 | validations:
22 | required: true
23 | - type: textarea
24 | attributes:
25 | label: Describe the Issue
26 | description: "Please provide a detailed description of the inaccuracies or omissions you have observed in the documentation."
27 | placeholder: "Enter a detailed description of the issue."
28 | validations:
29 | required: true
30 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: "🙋♂️ Feature Request"
2 | description: "Request the addition of a new feature."
3 | labels: ["feature", "request"]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: Thank you for helping us enhance the project! Your input is greatly appreciated in making it even better.
8 | - type: textarea
9 | attributes:
10 | label: Feature Request
11 | description: "Please describe the feature you would like to request."
12 | placeholder: "Enter details about the feature you want."
13 | value: "I want to request a feature that..."
14 | validations:
15 | required: true
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/questions.yml:
--------------------------------------------------------------------------------
1 | name: "❓ Questions and Discussions"
2 | description: "Initiate a conversation or seek clarification on specific aspects."
3 | labels: ["question"]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: Thank you for starting this discussion! Your engagement is valued.
8 | - type: input
9 | attributes:
10 | label: Question or Discussion
11 | description: "Please provide a brief description of your question or the topic you wish to discuss."
12 | placeholder: "Enter your question or discussion topic here."
13 | value: "I have a question about..."
14 | validations:
15 | required: true
16 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | # PR Name
2 |
3 | ## Motivation 💡
4 |
5 |
8 |
9 | - Issue
10 |
11 | ## Changes 🛠
12 |
13 |
16 |
17 | - 1st change ✨
18 | - 2nd change ✨
19 |
20 | ## Considerations 🤔
21 |
22 |
25 |
26 | - Warning... ⚠️
27 | - This part could be improved...
28 |
29 | ## Dependencies 📦
30 |
31 |
34 |
35 | - [Main](link-to-branch)
36 |
--------------------------------------------------------------------------------
/.github/workflows/branch.yml:
--------------------------------------------------------------------------------
1 | name: "Branch"
2 |
3 | on:
4 | push:
5 | branches:
6 | - "main"
7 |
8 | concurrency:
9 | # Cancel old runs if there is a new commit in the same branch
10 | group: ${{ github.workflow }}-${{ github.ref }}
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | integration:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Retrieve branch name
18 | run: echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
19 | - uses: actions/checkout@v2
20 | - uses: docker/setup-qemu-action@v2
21 | - uses: docker/setup-buildx-action@v2
22 | - uses: actions/cache@v3
23 | with:
24 | path: /tmp/.buildx-cache
25 | key: ${{ github.job }}-${{ runner.os }}-${{ env.BRANCH }}-buildx
26 | restore-keys: |
27 | ${{ github.job }}-${{ runner.os }}-${{ env.BRANCH }}-buildx
28 | # Docker login
29 | - uses: docker/login-action@v2
30 | with:
31 | username: ${{ secrets.DOCKER_USERNAME }}
32 | password: ${{ secrets.DOCKER_PUSH_TOKEN }}
33 | # Build and push docker image
34 | - name: Build docker image
35 | uses: docker/build-push-action@v4
36 | with:
37 | target: release
38 | push: true
39 | tags: peersyst/exrp:${{ env.BRANCH }}
40 | cache-from: type=local,src=/tmp/.buildx-cache
41 | cache-to: type=local,dest=/tmp/.buildx-cache-new
42 | - name: Move cache
43 | if: always()
44 | run: |
45 | rm -rf /tmp/.buildx-cache
46 | mv /tmp/.buildx-cache-new /tmp/.buildx-cache
47 |
--------------------------------------------------------------------------------
/.github/workflows/cosmovisor.yml:
--------------------------------------------------------------------------------
1 | name: "Cosmovisor"
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | tag:
7 | description: The docker tag for the publish
8 | required: true
9 |
10 | jobs:
11 | release:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v4
15 | - uses: docker/setup-qemu-action@v2
16 | - uses: docker/setup-buildx-action@v2
17 | # Docker login
18 | - uses: docker/login-action@v2
19 | with:
20 | username: ${{ secrets.DOCKER_USERNAME }}
21 | password: ${{ secrets.DOCKER_PUSH_TOKEN }}
22 | # Build and push docker image
23 | - name: Build docker image
24 | uses: docker/build-push-action@v4
25 | with:
26 | file: tools/cosmovisor/Dockerfile
27 | push: true
28 | tags: |
29 | peersyst/exrp-cosmovisor:${{ github.event.inputs.tag }}
30 | peersyst/exrp-cosmovisor:latest
31 |
--------------------------------------------------------------------------------
/.github/workflows/goreleaser.yml:
--------------------------------------------------------------------------------
1 | name: GoReleaser
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | commit_branch:
6 | description: The branch or the commit sha to push tag to
7 | required: true
8 | workflow_call:
9 | inputs:
10 | commit_branch:
11 | type: string
12 | description: The branch or the commit sha to push tag to
13 | required: true
14 |
15 | jobs:
16 | release:
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Free disk space
20 | run: rm -rf /opt/hostedtoolcache
21 | - uses: actions/checkout@v4
22 | with:
23 | ref: ${{ inputs.commit_branch }}
24 | fetch-depth: 0
25 | fetch-tags: true
26 | - uses: docker/setup-qemu-action@v2
27 | - uses: docker/setup-buildx-action@v2
28 | # Build and push docker image
29 | - name: Run go releaser
30 | run: |
31 | docker run --rm -e CGO_ENABLED -e GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} \
32 | -v /var/run/docker.sock:/var/run/docker.sock -v $PWD:/go/src/exrp -w /go/src/exrp \
33 | goreleaser/goreleaser-cross:v1.22 release --clean --skip validate
--------------------------------------------------------------------------------
/.github/workflows/pull-request.yml:
--------------------------------------------------------------------------------
1 | name: "Pull Request"
2 |
3 | on:
4 | pull_request:
5 | types: [opened, synchronize]
6 |
7 | concurrency:
8 | # Cancel old runs if there is a new commit in the same branch
9 | group: ${{ github.workflow }}-${{ github.ref }}
10 | cancel-in-progress: true
11 |
12 | jobs:
13 | integration:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v2
17 | - uses: docker/setup-qemu-action@v2
18 | - uses: docker/setup-buildx-action@v2
19 | - uses: actions/cache@v3
20 | with:
21 | path: /tmp/.buildx-cache
22 | key: ${{ github.job }}-${{ runner.os }}-${{ github.event.pull_request.number }}-buildx
23 | restore-keys: |
24 | ${{ github.job }}-${{ runner.os }}-${{ github.event.pull_request.number }}-buildx
25 | # Build docker image
26 | - name: Build docker image
27 | uses: docker/build-push-action@v4
28 | with:
29 | target: integration
30 | push: false
31 | cache-from: type=local,src=/tmp/.buildx-cache
32 | cache-to: type=local,dest=/tmp/.buildx-cache-new
33 | - name: Move cache
34 | if: always()
35 | run: |
36 | rm -rf /tmp/.buildx-cache
37 | mv /tmp/.buildx-cache-new /tmp/.buildx-cache
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | commit_branch:
6 | description: The branch or the commit sha to push tag to
7 | required: true
8 | tag:
9 | description: The tag of the release
10 | required: true
11 | is_latest_release:
12 | description: Is this the latest release
13 | type: boolean
14 | required: true
15 | permissions:
16 | contents: write
17 | jobs:
18 | release:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - uses: actions/checkout@v4
22 | with:
23 | ref: ${{ github.event.inputs.commit_branch }}
24 | fetch-depth: 0
25 | fetch-tags: true
26 | - uses: docker/setup-qemu-action@v2
27 | - uses: docker/setup-buildx-action@v2
28 | - name: Free disk space
29 | run: rm -rf /opt/hostedtoolcache
30 | # Docker login
31 | - uses: docker/login-action@v2
32 | with:
33 | username: ${{ secrets.DOCKER_USERNAME }}
34 | password: ${{ secrets.DOCKER_PUSH_TOKEN }}
35 | - run: |
36 | TAG=${{ github.event.inputs.tag }}
37 | echo "VERSION=${TAG#v}" >> $GITHUB_ENV
38 | # Build and push docker image
39 | - name: Build docker image
40 | uses: docker/build-push-action@v4
41 | with:
42 | target: release
43 | push: true
44 | build-args: VERSION=${{ env.VERSION }}
45 | tags: |
46 | peersyst/exrp:${{ github.event.inputs.tag }}
47 | ${{ fromJSON('["", "peersyst/exrp:latest"]')[github.event.inputs.is_latest_release == 'true'] }}
48 | - name: Publish the Release
49 | uses: softprops/action-gh-release@v1
50 | with:
51 | tag_name: ${{ github.event.inputs.tag }}
52 | prerelease: steps.check-prerelease.outputs.match == 'true'
53 | target_commitish: ${{ github.event.inputs.commit_branch }}
54 | env:
55 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
56 | goreleaser:
57 | needs: [ release ]
58 | uses: ./.github/workflows/goreleaser.yml
59 | secrets: inherit
60 | with:
61 | commit_branch: ${{ github.event.inputs.commit_branch }}
62 |
--------------------------------------------------------------------------------
/.github/workflows/unit-coverage.yml:
--------------------------------------------------------------------------------
1 | name: Coverage
2 | on:
3 | push:
4 | branches: [ main ]
5 | pull_request:
6 | branches: [ '**' ]
7 | jobs:
8 | build:
9 | name: Unit test
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v3
13 | - uses: actions/setup-go@v3
14 |
15 | - name: Generate unit test coverage
16 | run: make coverage-unit
17 |
18 | - name: Check unit test coverage
19 | uses: vladopajic/go-test-coverage@v2
20 | with:
21 | # Configure action using config file (option 1)
22 | config: ./.testcoverage.yml
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | vue/node_modules
2 | vue/dist
3 | build/
4 | release/
5 | .idea/
6 | .vscode/
7 | .DS_Store
8 |
9 |
10 | .exrpd/
11 | *.out
12 | *.html
13 |
14 | bin/
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | run:
2 | tests: true
3 | timeout: 5m
4 | concurrency: 4
5 |
6 | linters:
7 | enable:
8 | - dogsled
9 | - dupl
10 | - errcheck
11 | - goconst
12 | - gocritic
13 | - gofumpt
14 | - revive
15 | - gosec
16 | - gosimple
17 | - govet
18 | - ineffassign
19 | - misspell
20 | - nakedret
21 | - prealloc
22 | - exportloopref
23 | - staticcheck
24 | - stylecheck
25 | - typecheck
26 | - unconvert
27 | - unparam
28 | - unused
29 | - nolintlint
30 | - asciicheck
31 | - exportloopref
32 | - gofumpt
33 | - gomodguard
34 |
35 | linters-settings:
36 | dogsled:
37 | max-blank-identifiers: 3
38 | golint:
39 | min-confidence: 0
40 | maligned:
41 | suggest-new: true
42 | misspell:
43 | locale: US
44 | nolintlint:
45 | allow-unused: false
46 | allow-leading-space: true
47 | require-explanation: false
48 | require-specific: false
49 | gofumpt:
50 | lang-version: "1.22"
51 | gomodguard:
52 | blocked:
53 | versions: # List of blocked module version constraints
54 | - https://github.com/etcd-io/etcd: # Blocked module with version constraint
55 | version: ">= 3.4.10 || ~3.3.23" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons
56 | reason: "CVE-2020-15114; CVE-2020-15136; CVE-2020-15115" # Reason why the version constraint exists. (Optional)
57 | - https://github.com/dgrijalva/jwt-go: # Blocked module with version constraint
58 | version: ">= 4.0.0-preview1" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons
59 | reason: "CVE-2020-26160" # Reason why the version constraint exists. (Optional)
60 |
--------------------------------------------------------------------------------
/.goreleaser.yml:
--------------------------------------------------------------------------------
1 | before:
2 | hooks:
3 | - go mod download
4 |
5 | builds:
6 | - id: "exrpd-darwin-amd64"
7 | main: ./cmd/exrpd
8 | binary: bin/exrpd
9 | env:
10 | - CGO_ENABLED=1
11 | - CC=o64-clang
12 | - CXX=o64-clang++
13 | goos:
14 | - darwin
15 | goarch:
16 | - amd64
17 | flags:
18 | - -tags=cgo
19 | ldflags:
20 | - -s -w -X github.com/cosmos/cosmos-sdk/version.Name=exrp -X github.com/cosmos/cosmos-sdk/version.AppName=exrpd -X github.com/cosmos/cosmos-sdk/version.Version={{.Version}} -X github.com/cosmos/cosmos-sdk/version.Commit={{.Commit}}
21 | - id: "exrpd-darwin-arm64"
22 | main: ./cmd/exrpd
23 | binary: bin/exrpd
24 | env:
25 | - CGO_ENABLED=1
26 | - CC=oa64-clang
27 | - CXX=oa64-clang++
28 | goos:
29 | - darwin
30 | goarch:
31 | - arm64
32 | flags:
33 | - -tags=cgo
34 | ldflags:
35 | - -s -w -X github.com/cosmos/cosmos-sdk/version.Name=exrp -X github.com/cosmos/cosmos-sdk/version.AppName=exrpd -X github.com/cosmos/cosmos-sdk/version.Version={{.Version}} -X github.com/cosmos/cosmos-sdk/version.Commit={{.Commit}}
36 | - id: "exrpd-linux-amd64"
37 | main: ./cmd/exrpd
38 | binary: bin/exrpd
39 | env:
40 | - CGO_ENABLED=1
41 | - CC=gcc
42 | - CXX=g++
43 | goos:
44 | - linux
45 | goarch:
46 | - amd64
47 | flags:
48 | - -tags=cgo
49 | ldflags:
50 | - -s -w -X github.com/cosmos/cosmos-sdk/version.Name=exrp -X github.com/cosmos/cosmos-sdk/version.AppName=exrpd -X github.com/cosmos/cosmos-sdk/version.Version={{.Version}} -X github.com/cosmos/cosmos-sdk/version.Commit={{.Commit}}
51 | - id: "exrpd-linux-arm64"
52 | main: ./cmd/exrpd
53 | binary: bin/exrpd
54 | env:
55 | - CGO_ENABLED=1
56 | - CC=aarch64-linux-gnu-gcc
57 | - CXX=aarch64-linux-gnu-g++
58 | goos:
59 | - linux
60 | goarch:
61 | - arm64
62 | flags:
63 | - -tags=cgo
64 | ldflags:
65 | - -s -w -X github.com/cosmos/cosmos-sdk/version.Name=exrp -X github.com/cosmos/cosmos-sdk/version.AppName=exrpd -X github.com/cosmos/cosmos-sdk/version.Version={{.Version}} -X github.com/cosmos/cosmos-sdk/version.Commit={{.Commit}}
66 | - id: "exrpd-windows"
67 | main: ./cmd/exrpd
68 | binary: bin/exrpd
69 | env:
70 | - CGO_ENABLED=1
71 | - CC=x86_64-w64-mingw32-gcc
72 | - CXX=x86_64-w64-mingw32-g++
73 | goos:
74 | - windows
75 | goarch:
76 | - amd64
77 | flags:
78 | - -tags=cgo
79 | - -buildmode=exe
80 | ldflags:
81 | - -s -w -X github.com/cosmos/cosmos-sdk/version.Name=exrp -X github.com/cosmos/cosmos-sdk/version.AppName=exrpd -X github.com/cosmos/cosmos-sdk/version.Version={{.Version}} -X github.com/cosmos/cosmos-sdk/version.Commit={{.Commit}}
82 |
83 | archives:
84 | - name_template: '{{ .ProjectName }}_{{ .Version }}_{{- title .Os }}_{{ .Arch }}'
85 | format_overrides:
86 | - goos: windows
87 | format: zip
88 | builds:
89 | - exrpd-darwin-amd64
90 | - exrpd-darwin-arm64
91 | - exrpd-windows
92 | - exrpd-linux-amd64
93 | - exrpd-linux-arm64
94 |
95 | checksum:
96 | name_template: 'checksums.txt'
--------------------------------------------------------------------------------
/.testcoverage.yml:
--------------------------------------------------------------------------------
1 | # (mandatory)
2 | # Path to coverage profile file (output of `go test -coverprofile` command).
3 | #
4 | # For cases where there are many coverage profiles, such as when running
5 | # unit tests and integration tests separately, you can combine all those
6 | # profiles into one. In this case, the profile should have a comma-separated list
7 | # of profile files, e.g., 'cover_unit.out,cover_integration.out'.
8 | profile: coverage_unit.out
9 |
10 | # (optional; but recommended to set)
11 | # When specified reported file paths will not contain local prefix in the output.
12 | local-prefix: "github.com/xrplevm/node"
13 |
14 | # Holds coverage thresholds percentages, values should be in range [0-100].
15 | threshold:
16 | # (optional; default 0)
17 | # Minimum overall project coverage percentage required.
18 | total: 70
19 |
20 | # Holds regexp rules which will override thresholds for matched files or packages
21 | # using their paths.
22 | #
23 | # First rule from this list that matches file or package is going to apply
24 | # new threshold to it. If project has multiple rules that match same path,
25 | # override rules should be listed in order from specific to more general rules.
26 | # override:
27 | # Increase coverage threshold to 100% for `foo` package
28 | # (default is 80, as configured above in this example).
29 | # - path: ^pkg/lib/foo$
30 | # threshold: 100
31 |
32 | # Holds regexp rules which will exclude matched files or packages
33 | # from coverage statistics.
34 | exclude:
35 | # Exclude files or packages matching their paths
36 | paths:
37 | - cmd
38 | - docs
39 | - app
40 | - tools
41 | - tests
42 | - \.pb\.go$
43 | - \.pb\.gw\.go$
44 | - module.go$
45 | - \/testutil\/
46 | - \/client\/
47 |
48 | # File name of go-test-coverage breakdown file, which can be used to
49 | # analyze coverage difference.
50 | breakdown-file-name: ''
51 |
52 | diff:
53 | # File name of go-test-coverage breakdown file which will be used to
54 | # report coverage difference.
55 | base-breakdown-file-name: ''
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.22.11 AS base
2 | USER root
3 | RUN apt update && \
4 | apt-get install -y \
5 | build-essential \
6 | ca-certificates
7 | WORKDIR /app
8 | COPY . .
9 | RUN make install
10 |
11 |
12 | FROM base AS build
13 | ARG VERSION=0.0.0
14 | RUN make build
15 |
16 |
17 | FROM base AS integration
18 | RUN make lint
19 | # Unit tests
20 | RUN make test-poa
21 | # Integration tests
22 | RUN make test-integration
23 | RUN make test-upgrade
24 | # Simulation tests
25 | RUN make test-sim-benchmark-simulation
26 | RUN make test-sim-full-app-fast
27 |
28 | RUN touch /test.lock
29 |
30 | FROM golang:1.22.11 AS release
31 | WORKDIR /
32 | COPY --from=integration /test.lock /test.lock
33 | COPY --from=build /app/bin/exrpd /usr/bin/exrpd
34 | ENTRYPOINT ["/bin/sh", "-ec"]
35 | CMD ["exrpd"]
--------------------------------------------------------------------------------
/app/ante.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "github.com/cosmos/cosmos-sdk/client"
5 | "github.com/cosmos/cosmos-sdk/codec"
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
8 | "github.com/evmos/evmos/v20/app/ante"
9 | ethante "github.com/evmos/evmos/v20/app/ante/evm"
10 | etherminttypes "github.com/evmos/evmos/v20/types"
11 | poaante "github.com/xrplevm/node/v8/x/poa/ante"
12 | )
13 |
14 | type AnteHandlerOptions ante.HandlerOptions
15 |
16 | func NewAnteHandlerOptionsFromApp(app *App, txConfig client.TxConfig, maxGasWanted uint64) *AnteHandlerOptions {
17 | return &AnteHandlerOptions{
18 | Cdc: app.appCodec,
19 | AccountKeeper: app.AccountKeeper,
20 | BankKeeper: app.BankKeeper,
21 | ExtensionOptionChecker: etherminttypes.HasDynamicFeeExtensionOption,
22 | EvmKeeper: app.EvmKeeper,
23 | FeegrantKeeper: app.FeeGrantKeeper,
24 | IBCKeeper: app.IBCKeeper,
25 | FeeMarketKeeper: app.FeeMarketKeeper,
26 | SignModeHandler: txConfig.SignModeHandler(),
27 | SigGasConsumer: ante.SigVerificationGasConsumer,
28 | MaxTxGasWanted: maxGasWanted,
29 | TxFeeChecker: ethante.NewDynamicFeeChecker(app.EvmKeeper),
30 | StakingKeeper: app.StakingKeeper,
31 | DistributionKeeper: app.DistrKeeper,
32 | ExtraDecorator: poaante.NewPoaDecorator(),
33 | AuthzDisabledMsgTypes: []string{
34 | sdk.MsgTypeURL(&stakingtypes.MsgUndelegate{}),
35 | sdk.MsgTypeURL(&stakingtypes.MsgBeginRedelegate{}),
36 | sdk.MsgTypeURL(&stakingtypes.MsgCancelUnbondingDelegation{}),
37 | sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}),
38 | },
39 | }
40 | }
41 |
42 | func (aa *AnteHandlerOptions) Validate() error {
43 | return (*ante.HandlerOptions)(aa).Validate()
44 | }
45 |
46 | func (aa *AnteHandlerOptions) Options() ante.HandlerOptions {
47 | return ante.HandlerOptions(*aa)
48 | }
49 |
50 | func (aa *AnteHandlerOptions) WithCodec(cdc codec.BinaryCodec) *AnteHandlerOptions {
51 | aa.Cdc = cdc
52 | return aa
53 | }
54 |
55 | func (aa *AnteHandlerOptions) WithMaxTxGasWanted(maxTxGasWanted uint64) *AnteHandlerOptions {
56 | aa.MaxTxGasWanted = maxTxGasWanted
57 | return aa
58 | }
59 |
--------------------------------------------------------------------------------
/app/encoding.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | // MakeEncodingConfig creates an EncodingConfig for testing
4 | // func MakeEncodingConfig() params.EncodingConfig {
5 | // return evmenc.MakeConfig(ModuleBasics)
6 | // }
7 |
--------------------------------------------------------------------------------
/app/genesis.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "encoding/json"
5 |
6 | sdkmath "cosmossdk.io/math"
7 |
8 | feemarkettypes "github.com/evmos/evmos/v20/x/feemarket/types"
9 | )
10 |
11 | // GenesisState The genesis state of the blockchain is represented here as a map of raw json
12 | // messages key'd by a identifier string.
13 | // The identifier is used to determine which module genesis information belongs
14 | // to so it may be appropriately routed during init chain.
15 | // Within this application default genesis information is retrieved from
16 | // the ModuleBasicManager which populates json from each BasicModule
17 | // object provided to it during init.
18 | type GenesisState map[string]json.RawMessage
19 |
20 | // NewDefaultGenesisState generates the default state for the application.
21 | func NewDefaultGenesisState(app *App) GenesisState {
22 | genState := app.BasicModuleManager.DefaultGenesis(app.AppCodec())
23 | // Set default feemarket params
24 | var feeMarketState feemarkettypes.GenesisState
25 | app.cdc.MustUnmarshalJSON(genState[feemarkettypes.ModuleName], &feeMarketState)
26 | feeMarketState.Params.NoBaseFee = true
27 | feeMarketState.Params.BaseFee = sdkmath.NewInt(0)
28 | genState[feemarkettypes.ModuleName] = app.cdc.MustMarshalJSON(&feeMarketState)
29 |
30 | return genState
31 | }
32 |
--------------------------------------------------------------------------------
/app/precompiles.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "fmt"
5 |
6 | govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
7 |
8 | authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
9 | bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
10 | distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
11 | channelkeeper "github.com/cosmos/ibc-go/v8/modules/core/04-channel/keeper"
12 | "github.com/ethereum/go-ethereum/common"
13 | bankprecompile "github.com/evmos/evmos/v20/precompiles/bank"
14 | "github.com/evmos/evmos/v20/precompiles/bech32"
15 | distprecompile "github.com/evmos/evmos/v20/precompiles/distribution"
16 | govprecompile "github.com/evmos/evmos/v20/precompiles/gov"
17 | ics20precompile "github.com/evmos/evmos/v20/precompiles/ics20"
18 | "github.com/evmos/evmos/v20/precompiles/p256"
19 | stakingprecompile "github.com/evmos/evmos/v20/precompiles/staking"
20 | erc20Keeper "github.com/evmos/evmos/v20/x/erc20/keeper"
21 | "github.com/evmos/evmos/v20/x/evm/core/vm"
22 | transferkeeper "github.com/evmos/evmos/v20/x/ibc/transfer/keeper"
23 | stakingkeeper "github.com/evmos/evmos/v20/x/staking/keeper"
24 | "golang.org/x/exp/maps"
25 | )
26 |
27 | const bech32PrecompileBaseGas = 6_000
28 |
29 | // AvailableStaticPrecompiles returns the list of all available static precompiled contracts.
30 | // NOTE: this should only be used during initialization of the Keeper.
31 | func NewAvailableStaticPrecompiles(
32 | stakingKeeper stakingkeeper.Keeper,
33 | distributionKeeper distributionkeeper.Keeper,
34 | bankKeeper bankkeeper.Keeper,
35 | erc20Keeper erc20Keeper.Keeper,
36 | authzKeeper authzkeeper.Keeper,
37 | transferKeeper transferkeeper.Keeper,
38 | channelKeeper channelkeeper.Keeper,
39 | govKeeper govkeeper.Keeper,
40 | ) map[common.Address]vm.PrecompiledContract {
41 | // Clone the mapping from the latest EVM fork.
42 | precompiles := maps.Clone(vm.PrecompiledContractsBerlin)
43 |
44 | // secp256r1 precompile as per EIP-7212
45 | p256Precompile := &p256.Precompile{}
46 |
47 | bech32Precompile, err := bech32.NewPrecompile(bech32PrecompileBaseGas)
48 | if err != nil {
49 | panic(fmt.Errorf("failed to instantiate bech32 precompile: %w", err))
50 | }
51 |
52 | stakingPrecompile, err := stakingprecompile.NewPrecompile(stakingKeeper, authzKeeper)
53 | if err != nil {
54 | panic(fmt.Errorf("failed to instantiate staking precompile: %w", err))
55 | }
56 |
57 | distributionPrecompile, err := distprecompile.NewPrecompile(
58 | distributionKeeper,
59 | stakingKeeper,
60 | authzKeeper,
61 | )
62 | if err != nil {
63 | panic(fmt.Errorf("failed to instantiate distribution precompile: %w", err))
64 | }
65 |
66 | ibcTransferPrecompile, err := ics20precompile.NewPrecompile(
67 | stakingKeeper,
68 | transferKeeper,
69 | channelKeeper,
70 | authzKeeper,
71 | )
72 | if err != nil {
73 | panic(fmt.Errorf("failed to instantiate ICS20 precompile: %w", err))
74 | }
75 |
76 | bankPrecompile, err := bankprecompile.NewPrecompile(bankKeeper, erc20Keeper)
77 | if err != nil {
78 | panic(fmt.Errorf("failed to instantiate bank precompile: %w", err))
79 | }
80 |
81 | govPrecompile, err := govprecompile.NewPrecompile(govKeeper, authzKeeper)
82 | if err != nil {
83 | panic(fmt.Errorf("failed to instantiate gov precompile: %w", err))
84 | }
85 |
86 | // Stateless precompiles
87 | precompiles[bech32Precompile.Address()] = bech32Precompile
88 | precompiles[p256Precompile.Address()] = p256Precompile
89 |
90 | // Stateful precompiles
91 | precompiles[stakingPrecompile.Address()] = stakingPrecompile
92 | precompiles[distributionPrecompile.Address()] = distributionPrecompile
93 | precompiles[ibcTransferPrecompile.Address()] = ibcTransferPrecompile
94 | precompiles[bankPrecompile.Address()] = bankPrecompile
95 | precompiles[govPrecompile.Address()] = govPrecompile
96 | return precompiles
97 | }
98 |
--------------------------------------------------------------------------------
/app/simulation_test.go:
--------------------------------------------------------------------------------
1 | package app_test
2 |
3 | import (
4 | "math/rand"
5 | "os"
6 | "testing"
7 | "time"
8 |
9 | "cosmossdk.io/log"
10 |
11 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
12 | sdk "github.com/cosmos/cosmos-sdk/types"
13 | "github.com/evmos/evmos/v20/crypto/ethsecp256k1"
14 |
15 | dbm "github.com/cosmos/cosmos-db"
16 | "github.com/cosmos/cosmos-sdk/baseapp"
17 | "github.com/cosmos/cosmos-sdk/client/flags"
18 | "github.com/cosmos/cosmos-sdk/server"
19 | simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
20 | simulationtypes "github.com/cosmos/cosmos-sdk/types/simulation"
21 | "github.com/cosmos/cosmos-sdk/x/simulation"
22 | simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli"
23 | "github.com/evmos/evmos/v20/app/ante"
24 | "github.com/stretchr/testify/require"
25 | "github.com/xrplevm/node/v8/app"
26 | )
27 |
28 | func init() {
29 | simcli.GetSimulatorFlags()
30 | }
31 |
32 | const SimAppChainID = "simulation_777-1"
33 |
34 | // NewSimApp disable feemarket on native tx, otherwise the cosmos-sdk simulation tests will fail.
35 | func NewSimApp(logger log.Logger, db dbm.DB, config simulationtypes.Config) (*app.App, error) {
36 | appOptions := make(simtestutil.AppOptionsMap, 0)
37 | appOptions[flags.FlagHome] = app.DefaultNodeHome
38 | appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
39 |
40 | bApp := app.New(
41 | logger,
42 | db,
43 | nil,
44 | false,
45 | map[int64]bool{},
46 | app.DefaultNodeHome,
47 | simcli.FlagPeriodValue,
48 | appOptions,
49 | baseapp.SetChainID(config.ChainID),
50 | )
51 | handlerOpts := app.NewAnteHandlerOptionsFromApp(bApp, bApp.GetTxConfig(), 0)
52 | if err := handlerOpts.Validate(); err != nil {
53 | panic(err)
54 | }
55 | bApp.SetAnteHandler(ante.NewAnteHandler(handlerOpts.Options()))
56 |
57 | if err := bApp.LoadLatestVersion(); err != nil {
58 | return nil, err
59 | }
60 | return bApp, nil
61 | }
62 |
63 | // RandomAccounts generates n random accounts
64 | func RandomAccounts(r *rand.Rand, n int) []simulationtypes.Account {
65 | accs := make([]simulationtypes.Account, n)
66 |
67 | for i := 0; i < n; i++ {
68 | // don't need that much entropy for simulation
69 | privkeySeed := make([]byte, 32)
70 | r.Read(privkeySeed)
71 |
72 | accs[i].PrivKey = ðsecp256k1.PrivKey{Key: privkeySeed}
73 | accs[i].PubKey = accs[i].PrivKey.PubKey()
74 | accs[i].Address = sdk.AccAddress(accs[i].PubKey.Address())
75 |
76 | accs[i].ConsKey = ed25519.GenPrivKeyFromSecret(privkeySeed)
77 | }
78 |
79 | return accs
80 | }
81 |
82 | // BenchmarkSimulation run the chain simulation
83 | // Running using starport command:
84 | // `ignite chain simulate -v --numBlocks 200 --blockSize 50`
85 | // Running as go benchmark test:
86 | // `go test -benchmem -run=^$ -bench ^BenchmarkSimulation ./app -NumBlocks=200 -BlockSize 50 -Commit=true -Verbose=true -Enabled=true`
87 | //
88 | //nolint:dupl
89 | func BenchmarkSimulation(b *testing.B) {
90 | simcli.FlagSeedValue = time.Now().Unix()
91 | simcli.FlagVerboseValue = false
92 | simcli.FlagCommitValue = true
93 | simcli.FlagEnabledValue = true
94 |
95 | config := simcli.NewConfigFromFlags()
96 | config.ChainID = SimAppChainID
97 | db, dir, logger, _, err := simtestutil.SetupSimulation(
98 | config,
99 | "leveldb-bApp-sim",
100 | "Simulation",
101 | simcli.FlagVerboseValue,
102 | simcli.FlagEnabledValue,
103 | )
104 |
105 | require.NoError(b, err, "simulation setup failed")
106 |
107 | config.ChainID = SimAppChainID
108 |
109 | b.Cleanup(func() {
110 | require.NoError(b, db.Close())
111 | require.NoError(b, os.RemoveAll(dir))
112 | })
113 |
114 | bApp, _ := NewSimApp(logger, db, config)
115 |
116 | // Run randomized simulations
117 | _, simParams, simErr := simulation.SimulateFromSeed(
118 | b,
119 | os.Stdout,
120 | bApp.BaseApp,
121 | simtestutil.AppStateFn(
122 | bApp.AppCodec(),
123 | bApp.SimulationManager(),
124 | app.NewDefaultGenesisState(bApp),
125 | ),
126 | RandomAccounts,
127 | simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config),
128 | bApp.ModuleAccountAddrs(),
129 | config,
130 | bApp.AppCodec(),
131 | )
132 |
133 | // export state and simParams before the simulation error is checked
134 | err = simtestutil.CheckExportSimulation(bApp, config, simParams)
135 | require.NoError(b, err)
136 | require.NoError(b, simErr)
137 |
138 | if config.Commit {
139 | simtestutil.PrintStats(db)
140 | }
141 | }
142 |
143 | //nolint:dupl
144 | func TestFullAppSimulation(t *testing.T) {
145 | simcli.FlagSeedValue = time.Now().Unix()
146 | simcli.FlagVerboseValue = false
147 | simcli.FlagCommitValue = true
148 | simcli.FlagEnabledValue = true
149 |
150 | config := simcli.NewConfigFromFlags()
151 | config.ChainID = SimAppChainID
152 | db, dir, logger, _, err := simtestutil.SetupSimulation(
153 | config,
154 | "leveldb-bApp-sim",
155 | "Simulation",
156 | simcli.FlagVerboseValue,
157 | simcli.FlagEnabledValue,
158 | )
159 |
160 | require.NoError(t, err, "simulation setup failed")
161 |
162 | config.ChainID = SimAppChainID
163 |
164 | t.Cleanup(func() {
165 | require.NoError(t, db.Close())
166 | require.NoError(t, os.RemoveAll(dir))
167 | })
168 |
169 | bApp, _ := NewSimApp(logger, db, config)
170 |
171 | // Run randomized simulations
172 | _, simParams, simErr := simulation.SimulateFromSeed(
173 | t,
174 | os.Stdout,
175 | bApp.BaseApp,
176 | simtestutil.AppStateFn(
177 | bApp.AppCodec(),
178 | bApp.SimulationManager(),
179 | app.NewDefaultGenesisState(bApp),
180 | ),
181 | RandomAccounts,
182 | simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config),
183 | bApp.ModuleAccountAddrs(),
184 | config,
185 | bApp.AppCodec(),
186 | )
187 |
188 | // export state and simParams before the simulation error is checked
189 | err = simtestutil.CheckExportSimulation(bApp, config, simParams)
190 | require.NoError(t, err)
191 | require.NoError(t, simErr)
192 |
193 | if config.Commit {
194 | simtestutil.PrintStats(db)
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/app/upgrades.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "fmt"
5 |
6 | storetypes "cosmossdk.io/store/types"
7 | upgradetypes "cosmossdk.io/x/upgrade/types"
8 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
9 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
10 | ratelimittypes "github.com/cosmos/ibc-apps/modules/rate-limiting/v8/types"
11 | icahosttypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"
12 | v4 "github.com/xrplevm/node/v8/app/upgrades/v4"
13 | v5 "github.com/xrplevm/node/v8/app/upgrades/v5"
14 | v6 "github.com/xrplevm/node/v8/app/upgrades/v6"
15 | v7 "github.com/xrplevm/node/v8/app/upgrades/v7"
16 | v8 "github.com/xrplevm/node/v8/app/upgrades/v8"
17 | )
18 |
19 | func (app *App) setupUpgradeHandlers() {
20 | authAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String()
21 | app.UpgradeKeeper.SetUpgradeHandler(
22 | v4.UpgradeName,
23 | v4.CreateUpgradeHandler(
24 | app.mm,
25 | app.configurator,
26 | app.appCodec,
27 | app.GetKey("upgrade"),
28 | app.ConsensusParamsKeeper,
29 | authAddr,
30 | app.EvmKeeper,
31 | app.Erc20Keeper,
32 | app.GovKeeper,
33 | ),
34 | )
35 | app.UpgradeKeeper.SetUpgradeHandler(
36 | v5.UpgradeName,
37 | v5.CreateUpgradeHandler(
38 | app.mm,
39 | app.configurator,
40 | ),
41 | )
42 | app.UpgradeKeeper.SetUpgradeHandler(
43 | v6.UpgradeName,
44 | v6.CreateUpgradeHandler(
45 | app.mm,
46 | app.configurator,
47 | ),
48 | )
49 | app.UpgradeKeeper.SetUpgradeHandler(
50 | v7.UpgradeName,
51 | v7.CreateUpgradeHandler(
52 | app.mm,
53 | app.configurator,
54 | ),
55 | )
56 | app.UpgradeKeeper.SetUpgradeHandler(
57 | v8.UpgradeName,
58 | v8.CreateUpgradeHandler(
59 | app.mm,
60 | app.configurator,
61 | ),
62 | )
63 |
64 | // When a planned update height is reached, the old binary will panic
65 | // writing on disk the height and name of the update that triggered it
66 | // This will read that value, and execute the preparations for the upgrade.
67 | upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
68 | if err != nil {
69 | panic(fmt.Errorf("failed to read upgrade info from disk: %w", err))
70 | }
71 |
72 | if app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
73 | return
74 | }
75 |
76 | var storeUpgrades *storetypes.StoreUpgrades
77 |
78 | switch upgradeInfo.Name {
79 | case v4.UpgradeName:
80 | storeUpgrades = &storetypes.StoreUpgrades{
81 | Added: []string{
82 | icahosttypes.StoreKey,
83 | ratelimittypes.ModuleName,
84 | },
85 | Deleted: []string{},
86 | }
87 | case v5.UpgradeName, v6.UpgradeName:
88 | // No store upgrades for v5
89 | storeUpgrades = &storetypes.StoreUpgrades{}
90 | }
91 |
92 | if storeUpgrades != nil {
93 | // configure store loader that checks if version == upgradeHeight and applies store upgrades
94 | app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, storeUpgrades))
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/upgrades/v4/constants.go:
--------------------------------------------------------------------------------
1 | package v4
2 |
3 | const (
4 | // UpgradeName is the shared upgrade plan name for mainnet
5 | UpgradeName = "v4.0.0"
6 | )
7 |
--------------------------------------------------------------------------------
/app/upgrades/v4/upgrades.go:
--------------------------------------------------------------------------------
1 | package v4
2 |
3 | import (
4 | "context"
5 | "errors"
6 |
7 | "cosmossdk.io/log"
8 | storetypes "cosmossdk.io/store/types"
9 | upgradetypes "cosmossdk.io/x/upgrade/types"
10 |
11 | "github.com/cosmos/cosmos-sdk/codec"
12 | "github.com/cosmos/cosmos-sdk/runtime"
13 | sdk "github.com/cosmos/cosmos-sdk/types"
14 | "github.com/cosmos/cosmos-sdk/types/module"
15 | consensusparamskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
16 | govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
17 | govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
18 | erc20keeper "github.com/evmos/evmos/v20/x/erc20/keeper"
19 | erc20types "github.com/evmos/evmos/v20/x/erc20/types"
20 | evmkeeper "github.com/evmos/evmos/v20/x/evm/keeper"
21 | "github.com/evmos/evmos/v20/x/evm/types"
22 | )
23 |
24 | const (
25 | XrpAddress = "0xD4949664cD82660AaE99bEdc034a0deA8A0bd517"
26 | XrpOwnerAddress = "ethm1zrxl239wa6ad5xge3gs68rt98227xgnjq0xyw2"
27 | )
28 |
29 | // CreateUpgradeHandler creates an SDK upgrade handler for v13
30 | func CreateUpgradeHandler(
31 | mm *module.Manager,
32 | configurator module.Configurator,
33 | cdc codec.Codec,
34 | upgradeKey *storetypes.KVStoreKey,
35 | consensusParamsKeeper consensusparamskeeper.Keeper,
36 | authAddr string,
37 | ek *evmkeeper.Keeper,
38 | erc20k erc20keeper.Keeper,
39 | gk govkeeper.Keeper,
40 | ) upgradetypes.UpgradeHandler {
41 | return func(c context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
42 | ctx := sdk.UnwrapSDKContext(c)
43 | logger := ctx.Logger().With("upgrade", UpgradeName)
44 |
45 | // Fix previous consensusparams upgrade
46 | logger.Info("Fixing previous consensusparams upgrade...")
47 | storesvc := runtime.NewKVStoreService(upgradeKey)
48 | consensuskeeper := consensusparamskeeper.NewKeeper(
49 | cdc,
50 | storesvc,
51 | authAddr,
52 | runtime.EventService{},
53 | )
54 | consensusParams, err := consensuskeeper.ParamsStore.Get(ctx)
55 | if err != nil {
56 | return nil, err
57 | }
58 | err = consensusParamsKeeper.ParamsStore.Set(ctx, consensusParams)
59 | if err != nil {
60 | return nil, err
61 | }
62 |
63 | logger.Debug("Enabling gov precompile...")
64 | if err := EnableGovPrecompile(ctx, ek); err != nil {
65 | logger.Error("error while enabling gov precompile", "error", err.Error())
66 | }
67 |
68 | // run the sdk v0.50 migrations
69 | logger.Debug("Running module migrations...")
70 | vm, err = mm.RunMigrations(ctx, configurator, vm)
71 | if err != nil {
72 | return vm, err
73 | }
74 |
75 | logger.Debug("Updating expedited prop params...")
76 | if err := UpdateExpeditedPropsParams(ctx, gk); err != nil {
77 | logger.Error("error while updating gov params", "error", err.Error())
78 | }
79 |
80 | logger.Debug("Assigning XRP owner address...")
81 | err = AssignXrpOwnerAddress(ctx, erc20k, sdk.MustAccAddressFromBech32(XrpOwnerAddress))
82 | if err != nil {
83 | logger.Error("error while assigning XRP owner address", "error", err.Error())
84 | return vm, err
85 | }
86 |
87 | err = AddCodeToERC20Extensions(ctx, logger, erc20k)
88 | if err != nil {
89 | logger.Error("error while adding code hashes", "error", err.Error())
90 | return vm, err
91 | }
92 | return vm, nil
93 | }
94 | }
95 |
96 | func EnableGovPrecompile(ctx sdk.Context, ek *evmkeeper.Keeper) error {
97 | // Enable gov precompile
98 | params := ek.GetParams(ctx)
99 | params.ActiveStaticPrecompiles = append(params.ActiveStaticPrecompiles, types.GovPrecompileAddress)
100 | if err := params.Validate(); err != nil {
101 | return err
102 | }
103 | return ek.SetParams(ctx, params)
104 | }
105 |
106 | func UpdateExpeditedPropsParams(ctx sdk.Context, gk govkeeper.Keeper) error {
107 | params, err := gk.Params.Get(ctx)
108 | if err != nil {
109 | return err
110 | }
111 |
112 | // use the same denom as the min deposit denom
113 | // also amount must be greater than MinDeposit amount
114 | denom := params.MinDeposit[0].Denom
115 | expDepAmt := params.ExpeditedMinDeposit[0].Amount
116 | if expDepAmt.LTE(params.MinDeposit[0].Amount) {
117 | expDepAmt = params.MinDeposit[0].Amount.MulRaw(govv1.DefaultMinExpeditedDepositTokensRatio)
118 | }
119 | params.ExpeditedMinDeposit = sdk.NewCoins(sdk.NewCoin(denom, expDepAmt))
120 |
121 | // if expedited voting period > voting period
122 | // set expedited voting period to be half the voting period
123 | if params.ExpeditedVotingPeriod != nil && params.VotingPeriod != nil && *params.ExpeditedVotingPeriod > *params.VotingPeriod {
124 | expPeriod := *params.VotingPeriod / 2
125 | params.ExpeditedVotingPeriod = &expPeriod
126 | }
127 |
128 | if err := params.ValidateBasic(); err != nil {
129 | return err
130 | }
131 | return gk.Params.Set(ctx, params)
132 | }
133 |
134 | func AssignXrpOwnerAddress(ctx sdk.Context, ek erc20keeper.Keeper, address sdk.AccAddress) error {
135 | tokenPairID := ek.GetTokenPairID(ctx, XrpAddress)
136 | tokenPair, found := ek.GetTokenPair(ctx, tokenPairID)
137 | if !found {
138 | return errors.New("token pair not found")
139 | }
140 | ek.SetTokenPairOwnerAddress(ctx, tokenPair, address.String())
141 | return nil
142 | }
143 |
144 | // AddCodeToERC20Extensions adds code and code hash to the ERC20 precompiles with the EVM.
145 | func AddCodeToERC20Extensions(
146 | ctx sdk.Context,
147 | logger log.Logger,
148 | erc20Keeper erc20keeper.Keeper,
149 | ) (err error) {
150 | logger.Info("Adding code to erc20 extensions...")
151 |
152 | erc20Keeper.IterateTokenPairs(ctx, func(tokenPair erc20types.TokenPair) bool {
153 | logger.Info("Adding code to erc20 extensions", "tokenPair", tokenPair)
154 | err = erc20Keeper.RegisterERC20CodeHash(ctx, tokenPair.GetERC20Contract())
155 | return err != nil
156 | })
157 |
158 | logger.Info("Done with erc20 extensions")
159 | return err
160 | }
161 |
--------------------------------------------------------------------------------
/app/upgrades/v5/constants.go:
--------------------------------------------------------------------------------
1 | package v5
2 |
3 | const (
4 | UpgradeName = "v5.0.0"
5 | )
6 |
--------------------------------------------------------------------------------
/app/upgrades/v5/upgrades.go:
--------------------------------------------------------------------------------
1 | package v5
2 |
3 | import (
4 | "context"
5 |
6 | upgradetypes "cosmossdk.io/x/upgrade/types"
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/cosmos/cosmos-sdk/types/module"
9 | )
10 |
11 | func CreateUpgradeHandler(
12 | mm *module.Manager,
13 | configurator module.Configurator,
14 | ) upgradetypes.UpgradeHandler {
15 | return func(c context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
16 | ctx := sdk.UnwrapSDKContext(c)
17 | logger := ctx.Logger().With("upgrade", UpgradeName)
18 | logger.Info("Running v5 upgrade handler...")
19 | return mm.RunMigrations(ctx, configurator, vm)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/upgrades/v6/constants.go:
--------------------------------------------------------------------------------
1 | package v6
2 |
3 | const (
4 | UpgradeName = "v6.0.0"
5 | )
6 |
--------------------------------------------------------------------------------
/app/upgrades/v6/upgrades.go:
--------------------------------------------------------------------------------
1 | package v6
2 |
3 | import (
4 | "context"
5 |
6 | upgradetypes "cosmossdk.io/x/upgrade/types"
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/cosmos/cosmos-sdk/types/module"
9 | )
10 |
11 | func CreateUpgradeHandler(
12 | mm *module.Manager,
13 | configurator module.Configurator,
14 | ) upgradetypes.UpgradeHandler {
15 | return func(c context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
16 | ctx := sdk.UnwrapSDKContext(c)
17 | logger := ctx.Logger().With("upgrade", UpgradeName)
18 | logger.Info("Running v6 upgrade handler...")
19 | return mm.RunMigrations(ctx, configurator, vm)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/upgrades/v7/constants.go:
--------------------------------------------------------------------------------
1 | package v7
2 |
3 | const (
4 | UpgradeName = "v7.0.0"
5 | )
6 |
--------------------------------------------------------------------------------
/app/upgrades/v7/upgrades.go:
--------------------------------------------------------------------------------
1 | package v7
2 |
3 | import (
4 | "context"
5 |
6 | upgradetypes "cosmossdk.io/x/upgrade/types"
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/cosmos/cosmos-sdk/types/module"
9 | )
10 |
11 | func CreateUpgradeHandler(
12 | mm *module.Manager,
13 | configurator module.Configurator,
14 | ) upgradetypes.UpgradeHandler {
15 | return func(c context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
16 | ctx := sdk.UnwrapSDKContext(c)
17 | logger := ctx.Logger().With("upgrade", UpgradeName)
18 | logger.Info("Running v7 upgrade handler...")
19 | return mm.RunMigrations(ctx, configurator, vm)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/upgrades/v8/constants.go:
--------------------------------------------------------------------------------
1 | package v8
2 |
3 | const (
4 | UpgradeName = "v8.0.0"
5 | )
6 |
--------------------------------------------------------------------------------
/app/upgrades/v8/upgrades.go:
--------------------------------------------------------------------------------
1 | package v8
2 |
3 | import (
4 | "context"
5 |
6 | upgradetypes "cosmossdk.io/x/upgrade/types"
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/cosmos/cosmos-sdk/types/module"
9 | )
10 |
11 | func CreateUpgradeHandler(
12 | mm *module.Manager,
13 | configurator module.Configurator,
14 | ) upgradetypes.UpgradeHandler {
15 | return func(c context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
16 | ctx := sdk.UnwrapSDKContext(c)
17 | logger := ctx.Logger().With("upgrade", UpgradeName)
18 | logger.Info("Running v8 upgrade handler...")
19 | return mm.RunMigrations(ctx, configurator, vm)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/utils.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "github.com/cosmos/cosmos-sdk/types/module"
5 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
6 | )
7 |
8 | // RandomGenesisAccounts defines the default RandomGenesisAccountsFn used on the SDK.
9 | // It creates a slice of BaseAccount, ContinuousVestingAccount and DelayedVestingAccount.
10 | func RandomGenesisAccounts(simState *module.SimulationState) authtypes.GenesisAccounts {
11 | genesisAccs := make(authtypes.GenesisAccounts, len(simState.Accounts))
12 | for i, acc := range simState.Accounts {
13 | bacc := authtypes.NewBaseAccountWithAddress(acc.Address)
14 | genesisAccs[i] = bacc
15 | }
16 | return genesisAccs
17 | }
18 |
--------------------------------------------------------------------------------
/buf.work.yaml:
--------------------------------------------------------------------------------
1 | # This workspace file points to the roots found in your
2 | # previous "buf.yaml" configuration.
3 | version: v1
4 | directories:
5 | - proto
6 |
--------------------------------------------------------------------------------
/cmd/exrpd/cmd/config.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
--------------------------------------------------------------------------------
/cmd/exrpd/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 |
7 | "cosmossdk.io/math"
8 |
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 | ethermint "github.com/evmos/evmos/v20/types"
11 |
12 | svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
13 |
14 | "github.com/xrplevm/node/v8/app"
15 | "github.com/xrplevm/node/v8/cmd/exrpd/cmd"
16 | )
17 |
18 | func main() {
19 | initSDKConfig()
20 | registerDenoms()
21 | rootCmd, _ := cmd.NewRootCmd()
22 | if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
23 | fmt.Fprintln(rootCmd.OutOrStderr(), err)
24 | os.Exit(1)
25 | }
26 | }
27 |
28 | func initSDKConfig() {
29 | // Set prefixes
30 | accountPubKeyPrefix := app.AccountAddressPrefix + "pub"
31 | validatorAddressPrefix := app.AccountAddressPrefix + "valoper"
32 | validatorPubKeyPrefix := app.AccountAddressPrefix + "valoperpub"
33 | consNodeAddressPrefix := app.AccountAddressPrefix + "valcons"
34 | consNodePubKeyPrefix := app.AccountAddressPrefix + "valconspub"
35 |
36 | // Set and seal config
37 | config := sdk.GetConfig()
38 | config.SetBech32PrefixForAccount(app.AccountAddressPrefix, accountPubKeyPrefix)
39 | config.SetBech32PrefixForValidator(validatorAddressPrefix, validatorPubKeyPrefix)
40 | config.SetBech32PrefixForConsensusNode(consNodeAddressPrefix, consNodePubKeyPrefix)
41 | config.SetCoinType(app.Bip44CoinType)
42 | config.SetPurpose(sdk.Purpose) // Shared
43 | // config.SetFullFundraiserPath(ethermint.BIP44HDPath) // nolint: staticcheck
44 | config.Seal()
45 | }
46 |
47 | func registerDenoms() {
48 | if err := sdk.RegisterDenom(app.DisplayDenom, math.LegacyOneDec()); err != nil {
49 | panic(err)
50 | }
51 |
52 | if err := sdk.RegisterDenom(app.BaseDenom, math.LegacyNewDecWithPrec(1, ethermint.BaseDenomUnit)); err != nil {
53 | panic(err)
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/docs/docs.go:
--------------------------------------------------------------------------------
1 | package docs
2 |
3 | import (
4 | "embed"
5 | httptemplate "html/template"
6 | "net/http"
7 |
8 | "github.com/gorilla/mux"
9 | )
10 |
11 | const (
12 | apiFile = "/static/openapi.yml"
13 | indexFile = "template/index.tpl"
14 | )
15 |
16 | //go:embed static
17 | var Static embed.FS
18 |
19 | //go:embed template
20 | var template embed.FS
21 |
22 | func RegisterOpenAPIService(appName string, rtr *mux.Router) {
23 | rtr.Handle(apiFile, http.FileServer(http.FS(Static)))
24 | rtr.HandleFunc("/", handler(appName))
25 | }
26 |
27 | // handler returns an http handler that servers OpenAPI console for an OpenAPI spec at specURL.
28 | func handler(title string) http.HandlerFunc {
29 | t, _ := httptemplate.ParseFS(template, indexFile)
30 |
31 | return func(w http.ResponseWriter, _ *http.Request) {
32 | //nolint:errcheck
33 | t.Execute(w, struct {
34 | Title string
35 | URL string
36 | }{
37 | title,
38 | apiFile,
39 | })
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/docs/template/index.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ .Title }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
24 |
25 |
26 | Footer
27 | © 2022 GitHub, Inc.
28 | Footer navigation
29 |
--------------------------------------------------------------------------------
/proto/buf.gen.gogo.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | plugins:
3 | - name: gocosmos
4 | out: .
5 | opt: plugins=grpc,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types
6 | - name: grpc-gateway
7 | out: .
8 | opt: logtostderr=true,allow_colon_final_segments=true
9 |
--------------------------------------------------------------------------------
/proto/buf.lock:
--------------------------------------------------------------------------------
1 | # Generated by buf. DO NOT EDIT.
2 | version: v1
3 | deps:
4 | - remote: buf.build
5 | owner: cosmos
6 | repository: cosmos-proto
7 | commit: 1935555c206d4afb9e94615dfd0fad31
8 | - remote: buf.build
9 | owner: cosmos
10 | repository: cosmos-sdk
11 | commit: 508e19f5f37549e3a471a2a59b903c00
12 | - remote: buf.build
13 | owner: cosmos
14 | repository: gogo-proto
15 | commit: 34d970b699f84aa382f3c29773a60836
16 | - remote: buf.build
17 | owner: googleapis
18 | repository: googleapis
19 | commit: 783e4b5374fa488ab068d08af9658438
20 |
--------------------------------------------------------------------------------
/proto/buf.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | name: buf.build/xrplevm/node
3 | deps:
4 | - buf.build/cosmos/cosmos-sdk
5 | - buf.build/cosmos/cosmos-proto
6 | - buf.build/cosmos/gogo-proto
7 | - buf.build/googleapis/googleapis
8 | lint:
9 | use:
10 | - DEFAULT
11 | - COMMENTS
12 | - FILE_LOWER_SNAKE_CASE
13 | except:
14 | - UNARY_RPC
15 | - COMMENT_FIELD
16 | - SERVICE_SUFFIX
17 | - PACKAGE_VERSION_SUFFIX
18 | - RPC_REQUEST_STANDARD_NAME
19 | - RPC_REQUEST_RESPONSE_UNIQUE
20 | - RPC_RESPONSE_STANDARD_NAME
21 | - RPC_REQUEST_RESPONSE_UNIQUE
22 | - COMMENT_MESSAGE
23 | - ENUM_ZERO_VALUE_SUFFIX
24 | breaking:
25 | use:
26 | - FILE
27 |
--------------------------------------------------------------------------------
/proto/poa/genesis.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package poa;
3 |
4 | import "gogoproto/gogo.proto";
5 | import "poa/params.proto";
6 |
7 | option go_package = "github.com/xrplevm/node/v8/x/poa/types";
8 |
9 | // GenesisState defines the poa module's genesis state.
10 | message GenesisState { Params params = 1 [ (gogoproto.nullable) = false ]; }
11 |
--------------------------------------------------------------------------------
/proto/poa/params.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package poa;
3 |
4 | option go_package = "github.com/xrplevm/node/v8/x/poa/types";
5 |
6 | // Params defines the parameters for the module.
7 | message Params {}
8 |
--------------------------------------------------------------------------------
/proto/poa/query.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package poa;
3 |
4 | import "gogoproto/gogo.proto";
5 | import "google/api/annotations.proto";
6 | import "poa/params.proto";
7 |
8 | option go_package = "github.com/xrplevm/node/v8/x/poa/types";
9 |
10 | // Query defines the gRPC querier service.
11 | service Query {
12 | // Parameters queries the parameters of the module.
13 | rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
14 | option (google.api.http).get = "/exrp/poa/params";
15 | }
16 | }
17 |
18 | // QueryParamsRequest is request type for the Query/Params RPC method.
19 | message QueryParamsRequest {}
20 |
21 | // QueryParamsResponse is response type for the Query/Params RPC method.
22 | message QueryParamsResponse {
23 | // params holds all the parameters of this module.
24 | Params params = 1 [ (gogoproto.nullable) = false ];
25 | }
--------------------------------------------------------------------------------
/proto/poa/tx.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package poa;
3 |
4 | import "gogoproto/gogo.proto";
5 | import "cosmos_proto/cosmos.proto";
6 | import "cosmos/msg/v1/msg.proto";
7 | import "cosmos/staking/v1beta1/staking.proto";
8 | import "google/protobuf/any.proto";
9 | import "amino/amino.proto";
10 |
11 | option go_package = "github.com/xrplevm/node/v8/x/poa/types";
12 |
13 | // Msg defines the Msg service.
14 | service Msg {
15 | option (cosmos.msg.v1.service) = true;
16 |
17 | // Adds a new validator into the authority
18 | rpc AddValidator(MsgAddValidator) returns (MsgAddValidatorResponse);
19 | // Removes an existing validator from the authority
20 | rpc RemoveValidator(MsgRemoveValidator) returns (MsgRemoveValidatorResponse);
21 | }
22 |
23 | // MsgAddValidator defines a message for adding a new validator
24 | message MsgAddValidator {
25 | option (cosmos.msg.v1.signer) = "authority";
26 |
27 | string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
28 | string validator_address = 2
29 | [ (amino.dont_omitempty) = false, (cosmos_proto.scalar) = "cosmos.AddressString" ];
30 | cosmos.staking.v1beta1.Description description = 3
31 | [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
32 | google.protobuf.Any pubkey = 4
33 | [ (cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey" ];
34 | }
35 | // MsgAddValidatorResponse defines the response for adding a new validator
36 | message MsgAddValidatorResponse {}
37 |
38 | // MsgRemoveValidator defines a message for removing an existing validator
39 | message MsgRemoveValidator {
40 | option (cosmos.msg.v1.signer) = "authority";
41 |
42 | string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
43 | string validator_address = 2
44 | [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
45 | }
46 | // MsgRemoveValidatorResponse defines the response for removing an existing
47 | // validator
48 | message MsgRemoveValidatorResponse {}
49 |
--------------------------------------------------------------------------------
/proto/scripts/protoc-swagger-gen.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eo pipefail
4 |
5 | mkdir -p ./tmp-swagger-gen
6 | cd proto
7 | proto_dirs=$(find ./ -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq)
8 | for dir in $proto_dirs; do
9 | # generate swagger files (filter query files)
10 | query_file=$(find "${dir}" -maxdepth 1 \( -name 'query.proto' -o -name 'service.proto' \))
11 | if [[ ! -z "$query_file" ]]; then
12 | buf generate --template buf.gen.swagger.yaml $query_file
13 | fi
14 | done
15 |
16 | cd ..
17 |
18 | # combine swagger files
19 | # uses nodejs package `swagger-combine`.
20 | # all the individual swagger files need to be configured in `config.json` for merging
21 | swagger-combine ./docs/client/config.json -o ./docs/client/swagger-ui/swagger.yaml -f yaml --continueOnConflictingPaths true --includeDefinitions true
22 |
23 | # clean swagger files
24 | rm -rf ./tmp-swagger-gen
--------------------------------------------------------------------------------
/proto/scripts/protocgen.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eo pipefail
4 | echo "Generating gogo proto code"
5 | cd proto
6 | proto_dirs=$(find ./ -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq)
7 | for dir in $proto_dirs; do
8 | for file in $(find "${dir}" -maxdepth 1 -name '*.proto'); do
9 | if grep "option go_package" $file &> /dev/null ; then
10 | buf generate --template buf.gen.gogo.yaml $file
11 | fi
12 | done
13 | done
14 | cd ..
15 | # move proto files to the right places
16 | cp -r proto/github.com/xrplevm/node/v*/* ./
17 | rm -rf proto/github.com
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
XRPL EVM Sidechain node
8 |
9 |
10 |
24 |
35 |
36 | ## About
37 |
38 | The XRP Ledger Ethereum Virtual Machine (EVM) sidechain is a fast and secure blockchain that brings web3 applications to the XRP Ledger community.
39 |
40 | ## Quick Start
41 |
42 | To learn how the XRPL EVM Sidechain works from a high-level perspective,
43 | go to the [Protocol Overview](https://docs.xrplevm.org/introduction) section of the documentation.
44 |
45 | ## Documentation
46 |
47 | Find all the documentation at [docs.xrplevm.org](https://docs.xrplevm.org).
48 | Head over there and check it out.
49 |
50 | ## Installation
51 |
52 | For prerequisites and detailed build instructions
53 | please read the [Join the EVM Sidechian](https://opensource.ripple.com/docs/evm-sidechain/join-evm-sidechain-devnet/) instructions.
54 |
55 | Or check out the latest [release](https://github.com/xrplevm/node/releases).
56 |
57 | ## Community
58 |
59 | The following chat channels and forums are great spots to ask questions about the XRPL EVM Sidechain:
60 |
61 | - [Peersyst Twitter](https://twitter.com/Peersyst)
62 | - [XRPL EVM Sidechian Discord](https://discord.gg/xrplevm)
63 |
64 | ## Contributing
65 |
66 | Looking for a good place to start contributing?
67 | Check out some
68 | [`good first issues`](https://github.com/xrplevm/node/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).
69 |
70 | For additional instructions, standards and style guides, please refer to the [Contributing](./CONTRIBUTING.md) document.
71 |
--------------------------------------------------------------------------------
/scripts/mockgen.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | mockgen -source=x/poa/types/expected_keepers.go -package testutil -destination=x/poa/testutil/expected_keepers_mock.go
4 | mockgen -source=x/poa/testutil/tx.go -package testutil -destination=x/poa/testutil/tx_mock.go
5 | mockgen -source=x/poa/testutil/keys.go -package testutil -destination=x/poa/testutil/keys_mock.go
6 | mockgen -source=x/poa/testutil/expected_msg_server.go -package testutil -destination=x/poa/testutil/expected_msg_server_mock.go
7 | mockgen -source=x/poa/testutil/staking_hooks.go -package testutil -destination=x/poa/testutil/staking_hooks_mock.go
--------------------------------------------------------------------------------
/tests/integration/network.go:
--------------------------------------------------------------------------------
1 | package integration
2 |
3 | import (
4 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
5 | "github.com/cosmos/cosmos-sdk/x/authz"
6 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
7 | distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
8 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
9 | slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
10 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
11 | erc20types "github.com/evmos/evmos/v20/x/erc20/types"
12 | evmtypes "github.com/evmos/evmos/v20/x/evm/types"
13 | feemarkettypes "github.com/evmos/evmos/v20/x/feemarket/types"
14 | commonnetwork "github.com/xrplevm/node/v8/testutil/integration/common/network"
15 | exrpcommon "github.com/xrplevm/node/v8/testutil/integration/exrp/common"
16 | exrpintegration "github.com/xrplevm/node/v8/testutil/integration/exrp/integration"
17 | poatypes "github.com/xrplevm/node/v8/x/poa/types"
18 | )
19 |
20 | var _ commonnetwork.Network = (*Network)(nil)
21 |
22 | type Network struct {
23 | exrpintegration.IntegrationNetwork
24 | }
25 |
26 | func NewIntegrationNetwork(opts ...exrpcommon.ConfigOption) *Network {
27 | network := exrpintegration.New(opts...)
28 | return &Network{
29 | IntegrationNetwork: *network,
30 | }
31 | }
32 |
33 | func (n *Network) SetupSdkConfig() {
34 | exrpcommon.SetupSdkConfig()
35 | }
36 |
37 | func (n *Network) GetERC20Client() erc20types.QueryClient {
38 | return exrpcommon.GetERC20Client(n)
39 | }
40 |
41 | func (n *Network) GetEvmClient() evmtypes.QueryClient {
42 | return exrpcommon.GetEvmClient(n)
43 | }
44 |
45 | func (n *Network) GetGovClient() govtypes.QueryClient {
46 | return exrpcommon.GetGovClient(n)
47 | }
48 |
49 | func (n *Network) GetBankClient() banktypes.QueryClient {
50 | return exrpcommon.GetBankClient(n)
51 | }
52 |
53 | func (n *Network) GetFeeMarketClient() feemarkettypes.QueryClient {
54 | return exrpcommon.GetFeeMarketClient(n)
55 | }
56 |
57 | func (n *Network) GetAuthClient() authtypes.QueryClient {
58 | return exrpcommon.GetAuthClient(n)
59 | }
60 |
61 | func (n *Network) GetAuthzClient() authz.QueryClient {
62 | return exrpcommon.GetAuthzClient(n)
63 | }
64 |
65 | func (n *Network) GetStakingClient() stakingtypes.QueryClient {
66 | return exrpcommon.GetStakingClient(n)
67 | }
68 |
69 | func (n *Network) GetSlashingClient() slashingtypes.QueryClient {
70 | return exrpcommon.GetSlashingClient(n)
71 | }
72 |
73 | func (n *Network) GetDistrClient() distrtypes.QueryClient {
74 | return exrpcommon.GetDistrClient(n)
75 | }
76 |
77 | func (n *Network) GetPoaClient() poatypes.QueryClient {
78 | return exrpcommon.GetPoaClient(n)
79 | }
80 |
--------------------------------------------------------------------------------
/tests/integration/slashing_test.go:
--------------------------------------------------------------------------------
1 | package integration
2 |
3 | import (
4 | "time"
5 |
6 | "cosmossdk.io/math"
7 | sdktypes "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/cosmos/cosmos-sdk/types/address"
9 | govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
10 | slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
11 | "github.com/stretchr/testify/require"
12 | "github.com/xrplevm/node/v8/testutil/integration/exrp/utils"
13 | )
14 |
15 | // Slashing tests
16 |
17 | func (s *TestSuite) TestSlashing_ChangeParams() {
18 | tt := []struct {
19 | name string
20 | newParams slashingtypes.Params
21 | expectedError string
22 | }{
23 | {
24 | name: "change slashing params - invalid slash fraction double sign",
25 | newParams: slashingtypes.NewParams(
26 | 200,
27 | math.LegacyOneDec(),
28 | time.Second,
29 | math.LegacyZeroDec(),
30 | math.LegacyOneDec(),
31 | ),
32 | expectedError: "slash fraction downtime must be zero: 1.000000000000000000",
33 | },
34 | {
35 | name: "change slashing params - invalid slash fraction downtime",
36 | newParams: slashingtypes.NewParams(
37 | 200,
38 | math.LegacyOneDec(),
39 | time.Second,
40 | math.LegacyOneDec(),
41 | math.LegacyZeroDec(),
42 | ),
43 | expectedError: "slash fraction double sign must be zero: 1.000000000000000000",
44 | },
45 | {
46 | name: "change slashing params - success",
47 | newParams: slashingtypes.NewParams(
48 | 200,
49 | math.LegacyOneDec(),
50 | time.Second,
51 | math.LegacyZeroDec(),
52 | math.LegacyZeroDec(),
53 | ),
54 | },
55 | }
56 |
57 | for _, tc := range tt {
58 | s.Run(tc.name, func() {
59 | authority := sdktypes.AccAddress(address.Module("gov"))
60 | msg := &slashingtypes.MsgUpdateParams{
61 | Authority: authority.String(),
62 | Params: tc.newParams,
63 | }
64 |
65 | proposal, err := utils.SubmitAndAwaitProposalResolution(s.factory, s.Network(), s.keyring.GetKeys(), "test", msg)
66 | require.NoError(s.T(), err)
67 |
68 | if tc.expectedError != "" {
69 | require.Equal(s.T(), govv1.ProposalStatus_PROPOSAL_STATUS_FAILED, proposal.Status)
70 | require.Equal(s.T(), proposal.FailedReason, tc.expectedError)
71 | } else {
72 | require.Equal(s.T(), govv1.ProposalStatus_PROPOSAL_STATUS_PASSED, proposal.Status)
73 | }
74 | })
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/tests/integration/suite.go:
--------------------------------------------------------------------------------
1 | package integration
2 |
3 | import (
4 | sdkmath "cosmossdk.io/math"
5 | sdk "github.com/cosmos/cosmos-sdk/types"
6 | evmtypes "github.com/evmos/evmos/v20/x/evm/types"
7 | "github.com/stretchr/testify/suite"
8 | "github.com/xrplevm/node/v8/app"
9 | factory "github.com/xrplevm/node/v8/testutil/integration/common/factory"
10 | "github.com/xrplevm/node/v8/testutil/integration/common/grpc"
11 | "github.com/xrplevm/node/v8/testutil/integration/common/keyring"
12 | exrpcommon "github.com/xrplevm/node/v8/testutil/integration/exrp/common"
13 | )
14 |
15 | type TestSuite struct {
16 | suite.Suite
17 |
18 | network *Network
19 | keyring keyring.Keyring
20 | factory factory.CoreTxFactory
21 | grpcHandler grpc.Handler
22 | }
23 |
24 | func (s *TestSuite) Network() *Network {
25 | return s.network
26 | }
27 |
28 | func (s *TestSuite) SetupSuite() {
29 | s.network.SetupSdkConfig()
30 | s.Require().Equal(sdk.GetConfig().GetBech32AccountAddrPrefix(), "ethm")
31 | }
32 |
33 | func (s *TestSuite) SetupTest() {
34 | // Check that the network was created successfully
35 | kr := keyring.New(5)
36 |
37 | customGenesis := exrpcommon.CustomGenesisState{}
38 |
39 | evmGen := evmtypes.DefaultGenesisState()
40 |
41 | evmGen.Params.EvmDenom = app.BaseDenom
42 |
43 | customGenesis[evmtypes.ModuleName] = evmGen
44 |
45 | s.network = NewIntegrationNetwork(
46 | exrpcommon.WithPreFundedAccounts(kr.GetAllAccAddrs()...),
47 | exrpcommon.WithAmountOfValidators(5),
48 | exrpcommon.WithCustomGenesis(customGenesis),
49 | exrpcommon.WithBondDenom("apoa"),
50 | exrpcommon.WithMaxValidators(7),
51 | exrpcommon.WithMinDepositAmt(sdkmath.NewInt(1)),
52 | exrpcommon.WithValidatorOperators(kr.GetAllAccAddrs()),
53 | )
54 | s.Require().NotNil(s.network)
55 |
56 | grpcHandler := grpc.NewIntegrationHandler(s.network)
57 |
58 | s.factory = factory.New(s.network, grpcHandler)
59 | s.keyring = kr
60 | s.grpcHandler = grpcHandler
61 | }
62 |
--------------------------------------------------------------------------------
/tests/integration/suite_test.go:
--------------------------------------------------------------------------------
1 | package integration
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/suite"
7 | )
8 |
9 | func TestIntegrationTestSuite(t *testing.T) {
10 | suite.Run(t, new(TestSuite))
11 | }
12 |
--------------------------------------------------------------------------------
/tests/sim/params.json:
--------------------------------------------------------------------------------
1 | {
2 | "op_weight_msg_create_validator": 0,
3 | "op_weight_msg_edit_validator": 0,
4 | "op_weight_msg_delegate": 0,
5 | "op_weight_msg_begin_redelegate": 0,
6 | "op_weight_msg_undelegate": 0,
7 | "op_weight_msg_cancel_unbonding_delegation": 0,
8 | "op_weight_msg_update_params": 0,
9 | "slash_fraction_double_sign": "0",
10 | "slash_fraction_downtime": "0",
11 | "stake_per_account": "1000000"
12 | }
--------------------------------------------------------------------------------
/tests/upgrade/README.md:
--------------------------------------------------------------------------------
1 | # Upgrade testsuite
2 |
3 | ## Download exported state
4 |
5 | ```bash
6 |
7 | ```
8 |
9 | ## Setup
10 |
11 | Set the `UPGRADE_STATE_FILE` environment variable to the path to the exported state file.
12 | ```bash
13 | UPGRADE_STATE_FILE="path/to/exported-state.json"
14 | ```
--------------------------------------------------------------------------------
/tests/upgrade/network.go:
--------------------------------------------------------------------------------
1 | package testupgrade
2 |
3 | import (
4 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
5 | "github.com/cosmos/cosmos-sdk/x/authz"
6 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
7 | distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
8 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
9 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
10 | erc20types "github.com/evmos/evmos/v20/x/erc20/types"
11 | evmtypes "github.com/evmos/evmos/v20/x/evm/types"
12 | feemarkettypes "github.com/evmos/evmos/v20/x/feemarket/types"
13 | commonnetwork "github.com/xrplevm/node/v8/testutil/integration/common/network"
14 | exrpcommon "github.com/xrplevm/node/v8/testutil/integration/exrp/common"
15 | upgradenetwork "github.com/xrplevm/node/v8/testutil/integration/exrp/upgrade"
16 | poatypes "github.com/xrplevm/node/v8/x/poa/types"
17 | )
18 |
19 | var _ commonnetwork.Network = (*UpgradeTestNetwork)(nil)
20 |
21 | type UpgradeTestNetwork struct {
22 | upgradenetwork.UpgradeIntegrationNetwork
23 | }
24 |
25 | func NewUpgradeTestNetwork(opts ...exrpcommon.ConfigOption) *UpgradeTestNetwork {
26 | network := upgradenetwork.New(opts...)
27 | return &UpgradeTestNetwork{
28 | UpgradeIntegrationNetwork: *network,
29 | }
30 | }
31 |
32 | func (n *UpgradeTestNetwork) SetupSdkConfig() {
33 | exrpcommon.SetupSdkConfig()
34 | }
35 |
36 | func (n *UpgradeTestNetwork) GetERC20Client() erc20types.QueryClient {
37 | return exrpcommon.GetERC20Client(n)
38 | }
39 |
40 | func (n *UpgradeTestNetwork) GetEvmClient() evmtypes.QueryClient {
41 | return exrpcommon.GetEvmClient(n)
42 | }
43 |
44 | func (n *UpgradeTestNetwork) GetGovClient() govtypes.QueryClient {
45 | return exrpcommon.GetGovClient(n)
46 | }
47 |
48 | func (n *UpgradeTestNetwork) GetBankClient() banktypes.QueryClient {
49 | return exrpcommon.GetBankClient(n)
50 | }
51 |
52 | func (n *UpgradeTestNetwork) GetFeeMarketClient() feemarkettypes.QueryClient {
53 | return exrpcommon.GetFeeMarketClient(n)
54 | }
55 |
56 | func (n *UpgradeTestNetwork) GetAuthClient() authtypes.QueryClient {
57 | return exrpcommon.GetAuthClient(n)
58 | }
59 |
60 | func (n *UpgradeTestNetwork) GetAuthzClient() authz.QueryClient {
61 | return exrpcommon.GetAuthzClient(n)
62 | }
63 |
64 | func (n *UpgradeTestNetwork) GetStakingClient() stakingtypes.QueryClient {
65 | return exrpcommon.GetStakingClient(n)
66 | }
67 |
68 | func (n *UpgradeTestNetwork) GetDistrClient() distrtypes.QueryClient {
69 | return exrpcommon.GetDistrClient(n)
70 | }
71 |
72 | func (n *UpgradeTestNetwork) GetPoaClient() poatypes.QueryClient {
73 | return exrpcommon.GetPoaClient(n)
74 | }
75 |
--------------------------------------------------------------------------------
/tests/upgrade/suite.go:
--------------------------------------------------------------------------------
1 | package testupgrade
2 |
3 | import (
4 | "os"
5 |
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | "github.com/stretchr/testify/suite"
8 | exrpupgrade "github.com/xrplevm/node/v8/testutil/integration/exrp/upgrade"
9 | )
10 |
11 | const defaultStateFile = "upgrade-state.json"
12 |
13 | type UpgradeTestSuite struct {
14 | suite.Suite
15 |
16 | network *UpgradeTestNetwork
17 | }
18 |
19 | func (s *UpgradeTestSuite) Network() *UpgradeTestNetwork {
20 | return s.network
21 | }
22 |
23 | func (s *UpgradeTestSuite) SetupTest() {
24 | // Get the state file from the environment variable, or use the default one
25 | stateFile := os.Getenv("UPGRADE_STATE_FILE")
26 | if stateFile == "" {
27 | stateFile = defaultStateFile
28 | }
29 | s.Require().NotEmpty(stateFile)
30 |
31 | // Setup the SDK config
32 | s.network.SetupSdkConfig()
33 |
34 | s.Require().Equal(sdk.GetConfig().GetBech32AccountAddrPrefix(), "ethm")
35 |
36 | // Create the network
37 | s.network = NewUpgradeTestNetwork(
38 | exrpupgrade.WithGenesisFile(stateFile),
39 | )
40 |
41 | // Check that the network was created successfully
42 | s.Require().NotNil(s.network)
43 | }
44 |
--------------------------------------------------------------------------------
/tests/upgrade/suite_test.go:
--------------------------------------------------------------------------------
1 | package testupgrade
2 |
3 | import (
4 | "testing"
5 |
6 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
7 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
8 | "github.com/stretchr/testify/suite"
9 | "github.com/xrplevm/node/v8/app"
10 | )
11 |
12 | func TestUpgradeTestSuite(t *testing.T) {
13 | suite.Run(t, new(UpgradeTestSuite))
14 | }
15 |
16 | func (s *UpgradeTestSuite) TestUpgrade() {
17 | denom := s.network.GetDenom()
18 | s.Require().NotEmpty(denom)
19 | s.Require().Equal(denom, app.BaseDenom)
20 |
21 | balances, err := s.Network().GetBankClient().AllBalances(s.network.GetContext(), &banktypes.QueryAllBalancesRequest{
22 | Address: "ethm1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3w48d64",
23 | })
24 |
25 | s.T().Log("balances", balances)
26 | s.Require().NoError(err)
27 |
28 | err = s.network.NextBlock()
29 | s.Require().NoError(err)
30 |
31 | res, err := s.Network().GetStakingClient().Validators(s.network.GetContext(), &stakingtypes.QueryValidatorsRequest{})
32 | s.Require().NoError(err)
33 |
34 | s.T().Log("validators", len(res.Validators))
35 | s.Require().Equal(len(res.Validators), 1)
36 | }
37 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/base.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package factory
4 |
5 | import (
6 | "fmt"
7 |
8 | errorsmod "cosmossdk.io/errors"
9 | abcitypes "github.com/cometbft/cometbft/abci/types"
10 | "github.com/cosmos/cosmos-sdk/client"
11 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
12 | sdktypes "github.com/cosmos/cosmos-sdk/types"
13 | testutiltypes "github.com/cosmos/cosmos-sdk/types/module/testutil"
14 | authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
15 | "github.com/xrplevm/node/v8/testutil/integration/common/grpc"
16 | "github.com/xrplevm/node/v8/testutil/integration/common/network"
17 | )
18 |
19 | // BaseTxFactory is the interface that wraps the common methods to build and broadcast transactions
20 | // within cosmos chains
21 | type BaseTxFactory interface {
22 | // BuildCosmosTx builds a Cosmos tx with the provided private key and txArgs
23 | BuildCosmosTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (authsigning.Tx, error)
24 | // SignCosmosTx signs a Cosmos transaction with the provided
25 | // private key and tx builder
26 | SignCosmosTx(privKey cryptotypes.PrivKey, txBuilder client.TxBuilder) error
27 | // ExecuteCosmosTx builds, signs and broadcasts a Cosmos tx with the provided private key and txArgs
28 | ExecuteCosmosTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (abcitypes.ExecTxResult, error)
29 | // EncodeTx encodes the provided transaction
30 | EncodeTx(tx sdktypes.Tx) ([]byte, error)
31 | // CommitCosmosTx creates, signs and commits a cosmos tx
32 | // (produces a block with the specified transaction)
33 | CommitCosmosTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (abcitypes.ExecTxResult, error)
34 | }
35 |
36 | // baseTxFactory is the struct of the basic tx factory
37 | // to build and broadcast transactions.
38 | // This is to simulate the behavior of a real user.
39 | type baseTxFactory struct {
40 | grpcHandler grpc.Handler
41 | network network.Network
42 | ec testutiltypes.TestEncodingConfig
43 | }
44 |
45 | // newBaseTxFactory instantiates a new baseTxFactory
46 | func newBaseTxFactory(
47 | network network.Network,
48 | grpcHandler grpc.Handler,
49 | ) BaseTxFactory {
50 | return &baseTxFactory{
51 | grpcHandler: grpcHandler,
52 | network: network,
53 | ec: network.GetEncodingConfig(),
54 | }
55 | }
56 |
57 | func (tf *baseTxFactory) BuildCosmosTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (authsigning.Tx, error) {
58 | txBuilder, err := tf.buildTx(privKey, txArgs)
59 | if err != nil {
60 | return nil, errorsmod.Wrap(err, "failed to build tx")
61 | }
62 | return txBuilder.GetTx(), nil
63 | }
64 |
65 | // ExecuteCosmosTx creates, signs and broadcasts a Cosmos transaction
66 | func (tf *baseTxFactory) ExecuteCosmosTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (abcitypes.ExecTxResult, error) {
67 | signedTx, err := tf.BuildCosmosTx(privKey, txArgs)
68 | if err != nil {
69 | return abcitypes.ExecTxResult{}, errorsmod.Wrap(err, "failed to build tx")
70 | }
71 |
72 | txBytes, err := tf.EncodeTx(signedTx)
73 | if err != nil {
74 | return abcitypes.ExecTxResult{}, errorsmod.Wrap(err, "failed to encode tx")
75 | }
76 |
77 | return tf.network.BroadcastTxSync(txBytes)
78 | }
79 |
80 | // CommitCosmosTx creates and signs a Cosmos transaction, and then includes it in
81 | // a block and commits the state changes on the chain
82 | func (tf *baseTxFactory) CommitCosmosTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (abcitypes.ExecTxResult, error) {
83 | signedTx, err := tf.BuildCosmosTx(privKey, txArgs)
84 | if err != nil {
85 | return abcitypes.ExecTxResult{}, errorsmod.Wrap(err, "failed to build tx")
86 | }
87 |
88 | txBytes, err := tf.EncodeTx(signedTx)
89 | if err != nil {
90 | return abcitypes.ExecTxResult{}, errorsmod.Wrap(err, "failed to encode tx")
91 | }
92 |
93 | blockRes, err := tf.network.NextBlockWithTxs(txBytes)
94 | if err != nil {
95 | return abcitypes.ExecTxResult{}, errorsmod.Wrap(err, "failed to include the tx in a block")
96 | }
97 | txResCount := len(blockRes.TxResults)
98 | if txResCount != 1 {
99 | return abcitypes.ExecTxResult{}, fmt.Errorf("expected to receive only one tx result, but got %d", txResCount)
100 | }
101 | return *blockRes.TxResults[0], nil
102 | }
103 |
104 | // SignCosmosTx is a helper function that signs a Cosmos transaction
105 | // with the provided private key and transaction builder
106 | func (tf *baseTxFactory) SignCosmosTx(privKey cryptotypes.PrivKey, txBuilder client.TxBuilder) error {
107 | txConfig := tf.ec.TxConfig
108 | signMode, err := authsigning.APISignModeToInternal(txConfig.SignModeHandler().DefaultMode())
109 | if err != nil {
110 | return errorsmod.Wrap(err, "invalid sign mode")
111 | }
112 | signerData, err := tf.setSignatures(privKey, txBuilder, signMode)
113 | if err != nil {
114 | return errorsmod.Wrap(err, "failed to set tx signatures")
115 | }
116 |
117 | return tf.signWithPrivKey(privKey, txBuilder, signerData, signMode)
118 | }
119 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/distribution.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package factory
4 |
5 | import (
6 | "fmt"
7 |
8 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 | distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
11 | )
12 |
13 | type DistributionTxFactory interface {
14 | // SetWithdrawAddress is a method to create and broadcast a MsgSetWithdrawAddress
15 | SetWithdrawAddress(delegatorPriv cryptotypes.PrivKey, withdrawerAddr sdk.AccAddress) error
16 | // WithdrawDelegationRewards is a method to create and broadcast a MsgWithdrawDelegationRewards
17 | WithdrawDelegationRewards(delegatorPriv cryptotypes.PrivKey, validatorAddr string) error
18 | // WithdrawValidatorCommission is a method to create and broadcast a MsgWithdrawValidatorCommission
19 | WithdrawValidatorCommission(validatorPriv cryptotypes.PrivKey) error
20 | }
21 |
22 | type distributionTxFactory struct {
23 | BaseTxFactory
24 | }
25 |
26 | func newDistrTxFactory(bf BaseTxFactory) DistributionTxFactory {
27 | return &distributionTxFactory{bf}
28 | }
29 |
30 | func (tf *distributionTxFactory) SetWithdrawAddress(delegatorPriv cryptotypes.PrivKey, withdrawerAddr sdk.AccAddress) error {
31 | delegatorAccAddr := sdk.AccAddress(delegatorPriv.PubKey().Address())
32 |
33 | msg := distrtypes.NewMsgSetWithdrawAddress(
34 | delegatorAccAddr,
35 | withdrawerAddr,
36 | )
37 |
38 | resp, err := tf.ExecuteCosmosTx(delegatorPriv, CosmosTxArgs{
39 | Msgs: []sdk.Msg{msg},
40 | })
41 |
42 | if resp.Code != 0 {
43 | err = fmt.Errorf("received error code %d on SetWithdrawAddress transaction. Logs: %s", resp.Code, resp.Log)
44 | }
45 |
46 | return err
47 | }
48 |
49 | // WithdrawDelegationRewards will withdraw any unclaimed staking rewards for the delegator associated with
50 | // the given private key from the validator.
51 | // The validator address should be in the format `evmosvaloper1...`.
52 | func (tf *distributionTxFactory) WithdrawDelegationRewards(delegatorPriv cryptotypes.PrivKey, validatorAddr string) error {
53 | delegatorAccAddr := sdk.AccAddress(delegatorPriv.PubKey().Address())
54 |
55 | msg := distrtypes.NewMsgWithdrawDelegatorReward(
56 | delegatorAccAddr.String(),
57 | validatorAddr,
58 | )
59 |
60 | resp, err := tf.ExecuteCosmosTx(delegatorPriv, CosmosTxArgs{
61 | Msgs: []sdk.Msg{msg},
62 | })
63 |
64 | if resp.Code != 0 {
65 | err = fmt.Errorf("received error code %d on WithdrawDelegationRewards transaction. Logs: %s", resp.Code, resp.Log)
66 | }
67 |
68 | return err
69 | }
70 |
71 | func (tf *distributionTxFactory) WithdrawValidatorCommission(validatorPriv cryptotypes.PrivKey) error {
72 | validatorAddr := sdk.ValAddress(validatorPriv.PubKey().Address())
73 |
74 | msg := distrtypes.NewMsgWithdrawValidatorCommission(
75 | validatorAddr.String(),
76 | )
77 |
78 | resp, err := tf.ExecuteCosmosTx(validatorPriv, CosmosTxArgs{
79 | Msgs: []sdk.Msg{msg},
80 | })
81 |
82 | if resp.Code != 0 {
83 | err = fmt.Errorf("received error code %d on WithdrawValidatorCommission transaction. Logs: %s", resp.Code, resp.Log)
84 | }
85 |
86 | return err
87 | }
88 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/factory.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package factory
5 |
6 | import (
7 | "github.com/xrplevm/node/v8/testutil/integration/common/grpc"
8 | "github.com/xrplevm/node/v8/testutil/integration/common/network"
9 | )
10 |
11 | const (
12 | GasAdjustment = float64(1.7)
13 | )
14 |
15 | // CoreTxFactory is the interface that wraps the methods
16 | // to build and broadcast cosmos transactions, and also
17 | // includes module-specific transactions
18 | type CoreTxFactory interface {
19 | BaseTxFactory
20 | DistributionTxFactory
21 | StakingTxFactory
22 | FundTxFactory
23 | }
24 |
25 | var _ CoreTxFactory = (*IntegrationTxFactory)(nil)
26 |
27 | // IntegrationTxFactory is a helper struct to build and broadcast transactions
28 | // to the network on integration tests. This is to simulate the behavior of a real user.
29 | type IntegrationTxFactory struct {
30 | BaseTxFactory
31 | DistributionTxFactory
32 | StakingTxFactory
33 | FundTxFactory
34 | }
35 |
36 | // New creates a new IntegrationTxFactory instance
37 | func New(
38 | network network.Network,
39 | grpcHandler grpc.Handler,
40 | ) CoreTxFactory {
41 | bf := newBaseTxFactory(network, grpcHandler)
42 | return &IntegrationTxFactory{
43 | bf,
44 | newDistrTxFactory(bf),
45 | newStakingTxFactory(bf),
46 | newFundTxFactory(bf),
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/fund.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package factory
5 |
6 | import (
7 | "fmt"
8 |
9 | sdktypes "github.com/cosmos/cosmos-sdk/types"
10 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
11 | "github.com/xrplevm/node/v8/testutil/integration/common/keyring"
12 | )
13 |
14 | // FundTxFactory is the interface that wraps the common methods to fund accounts
15 | // via a bank send transaction
16 | type FundTxFactory interface {
17 | // FundAccount funds the given account with the given amount.
18 | FundAccount(sender keyring.Key, receiver sdktypes.AccAddress, amount sdktypes.Coins) error
19 | }
20 |
21 | // baseTxFactory is the struct of the basic tx factory
22 | // to build and broadcast transactions.
23 | // This is to simulate the behavior of a real user.
24 | type fundTxFactory struct {
25 | BaseTxFactory
26 | }
27 |
28 | // newBaseTxFactory instantiates a new baseTxFactory
29 | func newFundTxFactory(bf BaseTxFactory) FundTxFactory {
30 | return &fundTxFactory{bf}
31 | }
32 |
33 | // FundAccount funds the given account with the given amount of coins.
34 | func (tf *fundTxFactory) FundAccount(sender keyring.Key, receiver sdktypes.AccAddress, coins sdktypes.Coins) error {
35 | bankmsg := banktypes.NewMsgSend(
36 | sender.AccAddr,
37 | receiver,
38 | coins,
39 | )
40 | txArgs := CosmosTxArgs{Msgs: []sdktypes.Msg{bankmsg}}
41 | txRes, err := tf.ExecuteCosmosTx(sender.Priv, txArgs)
42 | if err != nil {
43 | return err
44 | }
45 |
46 | if txRes.Code != 0 {
47 | return fmt.Errorf("transaction returned non-zero code %d", txRes.Code)
48 | }
49 |
50 | return nil
51 | }
52 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/helper.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package factory
5 |
6 | import (
7 | "math/big"
8 |
9 | errorsmod "cosmossdk.io/errors"
10 | sdkmath "cosmossdk.io/math"
11 | "github.com/cosmos/cosmos-sdk/client"
12 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
13 | sdktypes "github.com/cosmos/cosmos-sdk/types"
14 | authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
15 | )
16 |
17 | // EncodeTx encodes the tx using the txConfig's encoder.
18 | func (tf *baseTxFactory) EncodeTx(tx sdktypes.Tx) ([]byte, error) {
19 | txConfig := tf.ec.TxConfig
20 | txBytes, err := txConfig.TxEncoder()(tx)
21 | if err != nil {
22 | return nil, errorsmod.Wrap(err, "failed to encode tx")
23 | }
24 | return txBytes, nil
25 | }
26 |
27 | // buildTx builds a tx with the provided private key and txArgs
28 | func (tf *baseTxFactory) buildTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (client.TxBuilder, error) {
29 | txConfig := tf.ec.TxConfig
30 | txBuilder := txConfig.NewTxBuilder()
31 |
32 | if err := txBuilder.SetMsgs(txArgs.Msgs...); err != nil {
33 | return nil, errorsmod.Wrap(err, "failed to set tx msgs")
34 | }
35 |
36 | if txArgs.FeeGranter != nil {
37 | txBuilder.SetFeeGranter(txArgs.FeeGranter)
38 | }
39 |
40 | senderAddress := sdktypes.AccAddress(privKey.PubKey().Address().Bytes())
41 |
42 | if txArgs.FeeGranter != nil {
43 | txBuilder.SetFeeGranter(txArgs.FeeGranter)
44 | }
45 |
46 | txBuilder.SetFeePayer(senderAddress)
47 |
48 | // need to sign the tx to simulate the tx to get the gas estimation
49 | signMode, err := authsigning.APISignModeToInternal(txConfig.SignModeHandler().DefaultMode())
50 | if err != nil {
51 | return nil, errorsmod.Wrap(err, "invalid sign mode")
52 | }
53 | signerData, err := tf.setSignatures(privKey, txBuilder, signMode)
54 | if err != nil {
55 | return nil, errorsmod.Wrap(err, "failed to set tx signatures")
56 | }
57 |
58 | gasLimit, err := tf.estimateGas(txArgs, txBuilder)
59 | if err != nil {
60 | return nil, errorsmod.Wrap(err, "failed to estimate gas")
61 | }
62 | txBuilder.SetGasLimit(gasLimit)
63 |
64 | fees := txArgs.Fees
65 | if fees.IsZero() {
66 | fees, err = tf.calculateFees(txArgs.GasPrice, gasLimit)
67 | if err != nil {
68 | return nil, errorsmod.Wrap(err, "failed to calculate fees")
69 | }
70 | }
71 | txBuilder.SetFeeAmount(fees)
72 |
73 | if err := tf.signWithPrivKey(privKey, txBuilder, signerData, signMode); err != nil {
74 | return nil, errorsmod.Wrap(err, "failed to sign Cosmos Tx")
75 | }
76 |
77 | return txBuilder, nil
78 | }
79 |
80 | // calculateFees calculates the fees for the transaction.
81 | func (tf *baseTxFactory) calculateFees(gasPrice *sdkmath.Int, gasLimit uint64) (sdktypes.Coins, error) {
82 | denom := tf.network.GetDenom()
83 | var fees sdktypes.Coins
84 | if gasPrice != nil {
85 | fees = sdktypes.Coins{{Denom: denom, Amount: gasPrice.MulRaw(int64(gasLimit))}} //#nosec G115
86 | } else {
87 | resp, err := tf.grpcHandler.GetBaseFee()
88 | if err != nil {
89 | return sdktypes.Coins{}, errorsmod.Wrap(err, "failed to get base fee")
90 | }
91 | price := resp.BaseFee
92 | fees = sdktypes.Coins{{Denom: denom, Amount: price.MulRaw(int64(gasLimit))}} //#nosec G115
93 | }
94 | return fees, nil
95 | }
96 |
97 | // estimateGas estimates the gas needed for the transaction.
98 | func (tf *baseTxFactory) estimateGas(txArgs CosmosTxArgs, txBuilder client.TxBuilder) (uint64, error) {
99 | txConfig := tf.ec.TxConfig
100 | simulateBytes, err := txConfig.TxEncoder()(txBuilder.GetTx())
101 | if err != nil {
102 | return 0, errorsmod.Wrap(err, "failed to encode tx")
103 | }
104 |
105 | var gasLimit uint64
106 | if txArgs.Gas == nil {
107 | simulateRes, err := tf.network.Simulate(simulateBytes)
108 | if err != nil {
109 | return 0, errorsmod.Wrap(err, "failed to simulate tx")
110 | }
111 |
112 | gasAdj := new(big.Float).SetFloat64(GasAdjustment)
113 | gasUsed := new(big.Float).SetUint64(simulateRes.GasInfo.GasUsed)
114 | gasLimit, _ = gasAdj.Mul(gasAdj, gasUsed).Uint64()
115 | } else {
116 | gasLimit = *txArgs.Gas
117 | }
118 | return gasLimit, nil
119 | }
120 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/sign.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package factory
5 |
6 | import (
7 | "context"
8 |
9 | errorsmod "cosmossdk.io/errors"
10 | "github.com/cosmos/cosmos-sdk/client"
11 | cosmostx "github.com/cosmos/cosmos-sdk/client/tx"
12 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
13 | sdktypes "github.com/cosmos/cosmos-sdk/types"
14 | "github.com/cosmos/cosmos-sdk/types/tx/signing"
15 | authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
16 | )
17 |
18 | // setSignatures is a helper function that sets the signature for
19 | // the transaction in the tx builder. It returns the signerData to be used
20 | // when signing the transaction (e.g. when calling signWithPrivKey)
21 | func (tf *baseTxFactory) setSignatures(privKey cryptotypes.PrivKey, txBuilder client.TxBuilder, signMode signing.SignMode) (signerData authsigning.SignerData, err error) {
22 | senderAddress := sdktypes.AccAddress(privKey.PubKey().Address().Bytes())
23 | account, err := tf.grpcHandler.GetAccount(senderAddress.String())
24 | if err != nil {
25 | return signerData, err
26 | }
27 | sequence := account.GetSequence()
28 | signerData = authsigning.SignerData{
29 | ChainID: tf.network.GetChainID(),
30 | AccountNumber: account.GetAccountNumber(),
31 | Sequence: sequence,
32 | Address: senderAddress.String(),
33 | PubKey: privKey.PubKey(),
34 | }
35 |
36 | sigsV2 := signing.SignatureV2{
37 | PubKey: privKey.PubKey(),
38 | Data: &signing.SingleSignatureData{
39 | SignMode: signMode,
40 | Signature: nil,
41 | },
42 | Sequence: sequence,
43 | }
44 |
45 | return signerData, txBuilder.SetSignatures(sigsV2)
46 | }
47 |
48 | // signWithPrivKey is a helper function that signs a transaction
49 | // with the provided private key
50 | func (tf *baseTxFactory) signWithPrivKey(privKey cryptotypes.PrivKey, txBuilder client.TxBuilder, signerData authsigning.SignerData, signMode signing.SignMode) error {
51 | txConfig := tf.ec.TxConfig
52 | signature, err := cosmostx.SignWithPrivKey(context.TODO(), signMode, signerData, txBuilder, privKey, txConfig, signerData.Sequence)
53 | if err != nil {
54 | return errorsmod.Wrap(err, "failed to sign tx")
55 | }
56 |
57 | return txBuilder.SetSignatures(signature)
58 | }
59 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/staking.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package factory
5 |
6 | import (
7 | "fmt"
8 |
9 | "cosmossdk.io/math"
10 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
11 | sdk "github.com/cosmos/cosmos-sdk/types"
12 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
13 | )
14 |
15 | type StakingTxFactory interface {
16 | // Delegate is a method to create and execute a MsgDelegate paying always the same fee amount
17 | // The tx is included in a block and committed in the chain state
18 | Delegate(delegatorPriv cryptotypes.PrivKey, validatorAddr string, amount sdk.Coin) error
19 | // CreateValidator is a method to create and broadcast a MsgCreateValidator
20 | CreateValidator(operatorPriv cryptotypes.PrivKey, pubKey cryptotypes.PubKey, selfDelegation sdk.Coin, description stakingtypes.Description, commission stakingtypes.CommissionRates, minSelfDelegation math.Int) error
21 | }
22 |
23 | type stakingTxFactory struct {
24 | BaseTxFactory
25 | }
26 |
27 | func newStakingTxFactory(bf BaseTxFactory) StakingTxFactory {
28 | return &stakingTxFactory{bf}
29 | }
30 |
31 | // Delegate on behalf of the account associated with the given private key.
32 | // The defined amount will delegated to the specified validator.
33 | // The validator address should be in the format `evmosvaloper1...`.
34 | func (tf *stakingTxFactory) Delegate(delegatorPriv cryptotypes.PrivKey, validatorAddr string, amount sdk.Coin) error {
35 | delegatorAccAddr := sdk.AccAddress(delegatorPriv.PubKey().Address())
36 |
37 | msgDelegate := stakingtypes.NewMsgDelegate(
38 | delegatorAccAddr.String(),
39 | validatorAddr,
40 | amount,
41 | )
42 |
43 | // set gas and gas prices to pay the same fees
44 | // every time this function is called
45 | feesToPay := math.NewInt(1e16)
46 | gas := uint64(400_000)
47 | gasPrice := feesToPay.QuoRaw(int64(gas)) //#nosec G115 -- gas will not exceed int64
48 |
49 | res, err := tf.CommitCosmosTx(delegatorPriv, CosmosTxArgs{
50 | Msgs: []sdk.Msg{msgDelegate},
51 | Gas: &gas,
52 | GasPrice: &gasPrice,
53 | })
54 |
55 | if res.IsErr() {
56 | return fmt.Errorf("tx result with code %d. Logs: %s", res.Code, res.Log)
57 | }
58 |
59 | return err
60 | }
61 |
62 | // CreateValidator executes the transaction to create a validator
63 | // with the parameters specified
64 | func (tf *stakingTxFactory) CreateValidator(operatorPriv cryptotypes.PrivKey, pubKey cryptotypes.PubKey, selfDelegation sdk.Coin, description stakingtypes.Description, commission stakingtypes.CommissionRates, minSelfDelegation math.Int) error {
65 | operatorAccAddr := sdk.ValAddress(operatorPriv.PubKey().Address())
66 |
67 | msgCreateValidator, err := stakingtypes.NewMsgCreateValidator(
68 | operatorAccAddr.String(),
69 | pubKey,
70 | selfDelegation,
71 | description,
72 | commission,
73 | minSelfDelegation,
74 | )
75 | if err != nil {
76 | return err
77 | }
78 |
79 | resp, err := tf.ExecuteCosmosTx(operatorPriv, CosmosTxArgs{
80 | Msgs: []sdk.Msg{msgCreateValidator},
81 | })
82 |
83 | if resp.Code != 0 {
84 | err = fmt.Errorf("received error code %d on CreateValidator transaction. Logs: %s", resp.Code, resp.Log)
85 | }
86 |
87 | return err
88 | }
89 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/types.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package factory
4 |
5 | import (
6 | sdkmath "cosmossdk.io/math"
7 | sdktypes "github.com/cosmos/cosmos-sdk/types"
8 | )
9 |
10 | // CosmosTxArgs contains the params to create a cosmos tx
11 | type CosmosTxArgs struct {
12 | // ChainID is the chain's id in cosmos format, e.g. 'evmos_9000-1'
13 | ChainID string
14 | // Gas to be used on the tx
15 | Gas *uint64
16 | // GasPrice to use on tx
17 | GasPrice *sdkmath.Int
18 | // Fees is the fee to be used on the tx (amount and denom)
19 | Fees sdktypes.Coins
20 | // FeeGranter is the account address of the fee granter
21 | FeeGranter sdktypes.AccAddress
22 | // Msgs slice of messages to include on the tx
23 | Msgs []sdktypes.Msg
24 | }
25 |
--------------------------------------------------------------------------------
/testutil/integration/common/grpc/account.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package grpc
4 |
5 | import (
6 | "context"
7 |
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
10 | )
11 |
12 | // GetAccount returns the account for the given address.
13 | func (gqh *IntegrationHandler) GetAccount(address string) (sdk.AccountI, error) {
14 | authClient := gqh.network.GetAuthClient()
15 | res, err := authClient.Account(context.Background(), &authtypes.QueryAccountRequest{
16 | Address: address,
17 | })
18 | if err != nil {
19 | return nil, err
20 | }
21 |
22 | encodingCgf := gqh.network.GetEncodingConfig()
23 | var acc sdk.AccountI
24 | if err = encodingCgf.InterfaceRegistry.UnpackAny(res.Account, &acc); err != nil {
25 | return nil, err
26 | }
27 | return acc, nil
28 | }
29 |
--------------------------------------------------------------------------------
/testutil/integration/common/grpc/authz.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package grpc
5 |
6 | import (
7 | "context"
8 |
9 | "github.com/cosmos/cosmos-sdk/x/authz"
10 | )
11 |
12 | // GetGrants returns the grants for the given grantee and granter combination.
13 | //
14 | // NOTE: To extract the concrete authorizations, use the GetAuthorizations method.
15 | func (gqh *IntegrationHandler) GetGrants(grantee, granter string) ([]*authz.Grant, error) {
16 | authzClient := gqh.network.GetAuthzClient()
17 | res, err := authzClient.Grants(context.Background(), &authz.QueryGrantsRequest{
18 | Grantee: grantee,
19 | Granter: granter,
20 | })
21 | if err != nil {
22 | return nil, err
23 | }
24 |
25 | return res.Grants, nil
26 | }
27 |
28 | // GetGrantsByGrantee returns the grants for the given grantee.
29 | //
30 | // NOTE: To extract the concrete authorizations, use the GetAuthorizationsByGrantee method.
31 | func (gqh *IntegrationHandler) GetGrantsByGrantee(grantee string) ([]*authz.GrantAuthorization, error) {
32 | authzClient := gqh.network.GetAuthzClient()
33 | res, err := authzClient.GranteeGrants(context.Background(), &authz.QueryGranteeGrantsRequest{
34 | Grantee: grantee,
35 | })
36 | if err != nil {
37 | return nil, err
38 | }
39 |
40 | return res.Grants, nil
41 | }
42 |
43 | // GetGrantsByGranter returns the grants for the given granter.
44 | //
45 | // NOTE: To extract the concrete authorizations, use the GetAuthorizationsByGranter method.
46 | func (gqh *IntegrationHandler) GetGrantsByGranter(granter string) ([]*authz.GrantAuthorization, error) {
47 | authzClient := gqh.network.GetAuthzClient()
48 | res, err := authzClient.GranterGrants(context.Background(), &authz.QueryGranterGrantsRequest{
49 | Granter: granter,
50 | })
51 | if err != nil {
52 | return nil, err
53 | }
54 |
55 | return res.Grants, nil
56 | }
57 |
58 | // GetAuthorizations returns the concrete authorizations for the given grantee and granter combination.
59 | func (gqh *IntegrationHandler) GetAuthorizations(grantee, granter string) ([]authz.Authorization, error) {
60 | encodingCfg := gqh.network.GetEncodingConfig()
61 |
62 | grants, err := gqh.GetGrants(grantee, granter)
63 | if err != nil {
64 | return nil, err
65 | }
66 |
67 | auths := make([]authz.Authorization, 0, len(grants))
68 | for _, grant := range grants {
69 | var auth authz.Authorization
70 | err := encodingCfg.InterfaceRegistry.UnpackAny(grant.Authorization, &auth)
71 | if err != nil {
72 | return nil, err
73 | }
74 |
75 | auths = append(auths, auth)
76 | }
77 |
78 | return auths, nil
79 | }
80 |
81 | // GetAuthorizationsByGrantee returns the concrete authorizations for the given grantee.
82 | func (gqh *IntegrationHandler) GetAuthorizationsByGrantee(grantee string) ([]authz.Authorization, error) {
83 | grants, err := gqh.GetGrantsByGrantee(grantee)
84 | if err != nil {
85 | return nil, err
86 | }
87 |
88 | return gqh.unpackGrantAuthzs(grants)
89 | }
90 |
91 | // GetAuthorizationsByGranter returns the concrete authorizations for the given granter.
92 | func (gqh *IntegrationHandler) GetAuthorizationsByGranter(granter string) ([]authz.Authorization, error) {
93 | grants, err := gqh.GetGrantsByGranter(granter)
94 | if err != nil {
95 | return nil, err
96 | }
97 |
98 | return gqh.unpackGrantAuthzs(grants)
99 | }
100 |
101 | // unpackGrantAuthzs unpacks the given grant authorization.
102 | func (gqh *IntegrationHandler) unpackGrantAuthzs(grantAuthzs []*authz.GrantAuthorization) ([]authz.Authorization, error) {
103 | encodingCfg := gqh.network.GetEncodingConfig()
104 |
105 | auths := make([]authz.Authorization, 0, len(grantAuthzs))
106 | for _, grantAuthz := range grantAuthzs {
107 | var auth authz.Authorization
108 | err := encodingCfg.InterfaceRegistry.UnpackAny(grantAuthz.Authorization, &auth)
109 | if err != nil {
110 | return nil, err
111 | }
112 |
113 | auths = append(auths, auth)
114 | }
115 |
116 | return auths, nil
117 | }
118 |
--------------------------------------------------------------------------------
/testutil/integration/common/grpc/bank.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package grpc
5 |
6 | import (
7 | "context"
8 |
9 | sdktypes "github.com/cosmos/cosmos-sdk/types"
10 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
11 | )
12 |
13 | // GetBalance returns the balance for the given address and denom.
14 | func (gqh *IntegrationHandler) GetBalance(address sdktypes.AccAddress, denom string) (*banktypes.QueryBalanceResponse, error) {
15 | bankClient := gqh.network.GetBankClient()
16 | return bankClient.Balance(context.Background(), &banktypes.QueryBalanceRequest{
17 | Address: address.String(),
18 | Denom: denom,
19 | })
20 | }
21 |
22 | // GetAllBalances returns all the balances for the given address.
23 | func (gqh *IntegrationHandler) GetAllBalances(address sdktypes.AccAddress) (*banktypes.QueryAllBalancesResponse, error) {
24 | bankClient := gqh.network.GetBankClient()
25 | return bankClient.AllBalances(context.Background(), &banktypes.QueryAllBalancesRequest{
26 | Address: address.String(),
27 | })
28 | }
29 |
30 | // GetTotalSupply returns all the balances for the given address.
31 | func (gqh *IntegrationHandler) GetTotalSupply() (*banktypes.QueryTotalSupplyResponse, error) {
32 | bankClient := gqh.network.GetBankClient()
33 | return bankClient.TotalSupply(context.Background(), &banktypes.QueryTotalSupplyRequest{})
34 | }
35 |
36 | // GetSpendableBalance returns the spendable balance for the given denomination.
37 | func (gqh *IntegrationHandler) GetSpendableBalance(address sdktypes.AccAddress, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) {
38 | bankClient := gqh.network.GetBankClient()
39 | return bankClient.SpendableBalanceByDenom(context.Background(), &banktypes.QuerySpendableBalanceByDenomRequest{Address: address.String(), Denom: denom})
40 | }
41 |
--------------------------------------------------------------------------------
/testutil/integration/common/grpc/distribution.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package grpc
4 |
5 | import (
6 | "context"
7 |
8 | distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
9 | )
10 |
11 | // GetDelegationTotalRewards returns the total delegation rewards for the given delegator.
12 | func (gqh *IntegrationHandler) GetDelegationTotalRewards(delegatorAddress string) (*distrtypes.QueryDelegationTotalRewardsResponse, error) {
13 | distrClient := gqh.network.GetDistrClient()
14 | return distrClient.DelegationTotalRewards(context.Background(), &distrtypes.QueryDelegationTotalRewardsRequest{
15 | DelegatorAddress: delegatorAddress,
16 | })
17 | }
18 |
19 | // GetDelegationRewards returns the delegation rewards for the given delegator and validator.
20 | func (gqh *IntegrationHandler) GetDelegationRewards(delegatorAddress string, validatorAddress string) (*distrtypes.QueryDelegationRewardsResponse, error) {
21 | distrClient := gqh.network.GetDistrClient()
22 | return distrClient.DelegationRewards(context.Background(), &distrtypes.QueryDelegationRewardsRequest{
23 | DelegatorAddress: delegatorAddress,
24 | ValidatorAddress: validatorAddress,
25 | })
26 | }
27 |
28 | // GetDelegatorWithdrawAddr returns the withdraw address the given delegator.
29 | func (gqh *IntegrationHandler) GetDelegatorWithdrawAddr(delegatorAddress string) (*distrtypes.QueryDelegatorWithdrawAddressResponse, error) {
30 | distrClient := gqh.network.GetDistrClient()
31 | return distrClient.DelegatorWithdrawAddress(context.Background(), &distrtypes.QueryDelegatorWithdrawAddressRequest{
32 | DelegatorAddress: delegatorAddress,
33 | })
34 | }
35 |
36 | // GetValidatorCommission returns the commission for the given validator.
37 | func (gqh *IntegrationHandler) GetValidatorCommission(validatorAddress string) (*distrtypes.QueryValidatorCommissionResponse, error) {
38 | distrClient := gqh.network.GetDistrClient()
39 | return distrClient.ValidatorCommission(context.Background(), &distrtypes.QueryValidatorCommissionRequest{
40 | ValidatorAddress: validatorAddress,
41 | })
42 | }
43 |
44 | // GetValidatorOutstandingRewards returns the delegation rewards for the given delegator and validator.
45 | func (gqh *IntegrationHandler) GetValidatorOutstandingRewards(validatorAddress string) (*distrtypes.QueryValidatorOutstandingRewardsResponse, error) {
46 | distrClient := gqh.network.GetDistrClient()
47 | return distrClient.ValidatorOutstandingRewards(context.Background(), &distrtypes.QueryValidatorOutstandingRewardsRequest{
48 | ValidatorAddress: validatorAddress,
49 | })
50 | }
51 |
52 | // GetCommunityPool queries the community pool coins.
53 | func (gqh *IntegrationHandler) GetCommunityPool() (*distrtypes.QueryCommunityPoolResponse, error) {
54 | distrClient := gqh.network.GetDistrClient()
55 | return distrClient.CommunityPool(context.Background(), &distrtypes.QueryCommunityPoolRequest{})
56 | }
57 |
--------------------------------------------------------------------------------
/testutil/integration/common/grpc/feemarket.go:
--------------------------------------------------------------------------------
1 | package grpc
2 |
3 | import (
4 | "context"
5 |
6 | feemarkettypes "github.com/evmos/evmos/v20/x/feemarket/types"
7 | )
8 |
9 | // GetBaseFee returns the base fee from the feemarket module.
10 | func (gqh *IntegrationHandler) GetBaseFee() (*feemarkettypes.QueryBaseFeeResponse, error) {
11 | feeMarketClient := gqh.network.GetFeeMarketClient()
12 | return feeMarketClient.BaseFee(context.Background(), &feemarkettypes.QueryBaseFeeRequest{})
13 | }
14 |
--------------------------------------------------------------------------------
/testutil/integration/common/grpc/gov.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package grpc
5 |
6 | import (
7 | "fmt"
8 | "slices"
9 |
10 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
11 | )
12 |
13 | // GetGovParams returns the gov params from the gov module.
14 | func (gqh *IntegrationHandler) GetGovParams(paramsType string) (*govtypes.QueryParamsResponse, error) {
15 | possibleTypes := []string{"deposit", "tallying", "voting"}
16 | if !slices.Contains(possibleTypes, paramsType) {
17 | return nil, fmt.Errorf("invalid params type: %s\npossible types: %s", paramsType, possibleTypes)
18 | }
19 |
20 | govClient := gqh.network.GetGovClient()
21 | return govClient.Params(gqh.network.GetContext(), &govtypes.QueryParamsRequest{ParamsType: paramsType})
22 | }
23 |
24 | // GetProposal returns the proposal from the gov module.
25 | func (gqh *IntegrationHandler) GetProposal(proposalID uint64) (*govtypes.QueryProposalResponse, error) {
26 | govClient := gqh.network.GetGovClient()
27 | return govClient.Proposal(gqh.network.GetContext(), &govtypes.QueryProposalRequest{ProposalId: proposalID})
28 | }
29 |
--------------------------------------------------------------------------------
/testutil/integration/common/grpc/grpc.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package grpc
5 |
6 | import (
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/cosmos/cosmos-sdk/x/authz"
9 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
10 | distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
11 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
12 | feemarkettypes "github.com/evmos/evmos/v20/x/feemarket/types"
13 | network "github.com/xrplevm/node/v8/testutil/integration/common/network"
14 | )
15 |
16 | // Handler is an interface that defines the common methods that are used to query
17 | // the network's modules via gRPC.
18 | type Handler interface {
19 | // Account methods
20 | GetAccount(address string) (sdk.AccountI, error)
21 |
22 | // Authz methods
23 | GetAuthorizations(grantee, granter string) ([]authz.Authorization, error)
24 | GetAuthorizationsByGrantee(grantee string) ([]authz.Authorization, error)
25 | GetAuthorizationsByGranter(granter string) ([]authz.Authorization, error)
26 | GetGrants(grantee, granter string) ([]*authz.Grant, error)
27 | GetGrantsByGrantee(grantee string) ([]*authz.GrantAuthorization, error)
28 | GetGrantsByGranter(granter string) ([]*authz.GrantAuthorization, error)
29 |
30 | // Bank methods
31 | GetBalance(address sdk.AccAddress, denom string) (*banktypes.QueryBalanceResponse, error)
32 | GetSpendableBalance(address sdk.AccAddress, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error)
33 | GetAllBalances(address sdk.AccAddress) (*banktypes.QueryAllBalancesResponse, error)
34 | GetTotalSupply() (*banktypes.QueryTotalSupplyResponse, error)
35 |
36 | // Staking methods
37 | GetDelegation(delegatorAddress string, validatorAddress string) (*stakingtypes.QueryDelegationResponse, error)
38 | GetDelegatorDelegations(delegatorAddress string) (*stakingtypes.QueryDelegatorDelegationsResponse, error)
39 | GetValidatorDelegations(validatorAddress string) (*stakingtypes.QueryValidatorDelegationsResponse, error)
40 | GetRedelegations(delegatorAddress, srcValidator, dstValidator string) (*stakingtypes.QueryRedelegationsResponse, error)
41 | GetValidatorUnbondingDelegations(validatorAddress string) (*stakingtypes.QueryValidatorUnbondingDelegationsResponse, error)
42 | GetDelegatorUnbondingDelegations(delegatorAddress string) (*stakingtypes.QueryDelegatorUnbondingDelegationsResponse, error)
43 |
44 | // Distribution methods
45 | GetDelegationTotalRewards(delegatorAddress string) (*distrtypes.QueryDelegationTotalRewardsResponse, error)
46 | GetDelegationRewards(delegatorAddress string, validatorAddress string) (*distrtypes.QueryDelegationRewardsResponse, error)
47 | GetDelegatorWithdrawAddr(delegatorAddress string) (*distrtypes.QueryDelegatorWithdrawAddressResponse, error)
48 | GetValidatorCommission(validatorAddress string) (*distrtypes.QueryValidatorCommissionResponse, error)
49 | GetValidatorOutstandingRewards(validatorAddress string) (*distrtypes.QueryValidatorOutstandingRewardsResponse, error)
50 | GetCommunityPool() (*distrtypes.QueryCommunityPoolResponse, error)
51 | GetBondedValidators() (*stakingtypes.QueryValidatorsResponse, error)
52 |
53 | // FeeMarket methods
54 | GetBaseFee() (*feemarkettypes.QueryBaseFeeResponse, error)
55 | }
56 |
57 | var _ Handler = (*IntegrationHandler)(nil)
58 |
59 | // IntegrationHandler is a helper struct to query the network's modules
60 | // via gRPC. This is to simulate the behavior of a real user and avoid querying
61 | // the modules directly.
62 | type IntegrationHandler struct {
63 | network network.Network
64 | }
65 |
66 | // NewIntegrationHandler creates a new IntegrationHandler instance.
67 | func NewIntegrationHandler(network network.Network) *IntegrationHandler {
68 | return &IntegrationHandler{
69 | network: network,
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/testutil/integration/common/grpc/staking.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package grpc
4 |
5 | import (
6 | "context"
7 |
8 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
9 | )
10 |
11 | // GetDelegation returns the delegation for the given delegator and validator addresses.
12 | func (gqh *IntegrationHandler) GetDelegation(delegatorAddress string, validatorAddress string) (*stakingtypes.QueryDelegationResponse, error) {
13 | stakingClient := gqh.network.GetStakingClient()
14 | return stakingClient.Delegation(context.Background(), &stakingtypes.QueryDelegationRequest{
15 | DelegatorAddr: delegatorAddress,
16 | ValidatorAddr: validatorAddress,
17 | })
18 | }
19 |
20 | // GetValidatorDelegations returns the delegations to a given validator.
21 | func (gqh *IntegrationHandler) GetValidatorDelegations(validatorAddress string) (*stakingtypes.QueryValidatorDelegationsResponse, error) {
22 | stakingClient := gqh.network.GetStakingClient()
23 | return stakingClient.ValidatorDelegations(context.Background(), &stakingtypes.QueryValidatorDelegationsRequest{
24 | ValidatorAddr: validatorAddress,
25 | })
26 | }
27 |
28 | // GetDelegatorDelegations returns the delegations to a given delegator.
29 | func (gqh *IntegrationHandler) GetDelegatorDelegations(delegatorAddress string) (*stakingtypes.QueryDelegatorDelegationsResponse, error) {
30 | stakingClient := gqh.network.GetStakingClient()
31 | return stakingClient.DelegatorDelegations(context.Background(), &stakingtypes.QueryDelegatorDelegationsRequest{
32 | DelegatorAddr: delegatorAddress,
33 | })
34 | }
35 |
36 | // GetRedelegations returns the redelegations to a given delegator and validators.
37 | func (gqh *IntegrationHandler) GetRedelegations(delegatorAddress, srcValidator, dstValidator string) (*stakingtypes.QueryRedelegationsResponse, error) {
38 | stakingClient := gqh.network.GetStakingClient()
39 | return stakingClient.Redelegations(context.Background(), &stakingtypes.QueryRedelegationsRequest{
40 | DelegatorAddr: delegatorAddress,
41 | SrcValidatorAddr: srcValidator,
42 | DstValidatorAddr: dstValidator,
43 | })
44 | }
45 |
46 | // GetValidatorUnbondingDelegations returns the unbonding delegations to a given validator.
47 | func (gqh *IntegrationHandler) GetValidatorUnbondingDelegations(validatorAddress string) (*stakingtypes.QueryValidatorUnbondingDelegationsResponse, error) {
48 | stakingClient := gqh.network.GetStakingClient()
49 | return stakingClient.ValidatorUnbondingDelegations(context.Background(), &stakingtypes.QueryValidatorUnbondingDelegationsRequest{
50 | ValidatorAddr: validatorAddress,
51 | })
52 | }
53 |
54 | // GetDelegatorUnbondingDelegations returns all the unbonding delegations for given delegator.
55 | func (gqh *IntegrationHandler) GetDelegatorUnbondingDelegations(delegatorAddress string) (*stakingtypes.QueryDelegatorUnbondingDelegationsResponse, error) {
56 | stakingClient := gqh.network.GetStakingClient()
57 | return stakingClient.DelegatorUnbondingDelegations(context.Background(), &stakingtypes.QueryDelegatorUnbondingDelegationsRequest{
58 | DelegatorAddr: delegatorAddress,
59 | })
60 | }
61 |
62 | // GetValidators returns the list of all bonded validators.
63 | func (gqh *IntegrationHandler) GetBondedValidators() (*stakingtypes.QueryValidatorsResponse, error) {
64 | stakingClient := gqh.network.GetStakingClient()
65 | return stakingClient.Validators(context.Background(), &stakingtypes.QueryValidatorsRequest{
66 | Status: stakingtypes.BondStatusBonded,
67 | })
68 | }
69 |
--------------------------------------------------------------------------------
/testutil/integration/common/keyring/keyring.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package keyring
4 |
5 | import (
6 | "fmt"
7 |
8 | "github.com/ethereum/go-ethereum/common"
9 |
10 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
11 | sdktypes "github.com/cosmos/cosmos-sdk/types"
12 | utiltx "github.com/evmos/evmos/v20/testutil/tx"
13 | )
14 |
15 | type Key struct {
16 | Addr common.Address
17 | AccAddr sdktypes.AccAddress
18 | Priv cryptotypes.PrivKey
19 | }
20 |
21 | func NewKey() Key {
22 | addr, privKey := utiltx.NewAddrKey()
23 | return Key{
24 | Addr: addr,
25 | AccAddr: sdktypes.AccAddress(addr.Bytes()),
26 | Priv: privKey,
27 | }
28 | }
29 |
30 | type Keyring interface {
31 | // GetPrivKey returns the private key of the account at the given keyring index.
32 | GetPrivKey(index int) cryptotypes.PrivKey
33 | // GetAddr returns the address of the account at the given keyring index.
34 | GetAddr(index int) common.Address
35 | // GetAccAddr returns the SDK address of the account at the given keyring index.
36 | GetAccAddr(index int) sdktypes.AccAddress
37 | // GetAllAccAddrs returns all the SDK addresses of the accounts in the keyring.
38 | GetAllAccAddrs() []sdktypes.AccAddress
39 | // GetKey returns the key at the given keyring index
40 | GetKey(index int) Key
41 | // GetKeys returns all the keys
42 | GetKeys() []Key
43 |
44 | // AddKey adds a new account to the keyring
45 | AddKey() int
46 |
47 | // Sign signs message with the specified account.
48 | Sign(index int, msg []byte) ([]byte, error)
49 | }
50 |
51 | // IntegrationKeyring is a keyring designed for integration tests.
52 | type IntegrationKeyring struct {
53 | keys []Key
54 | }
55 |
56 | var _ Keyring = (*IntegrationKeyring)(nil)
57 |
58 | // New returns a new keyring with nAccs accounts.
59 | func New(nAccs int) Keyring {
60 | accs := make([]Key, 0, nAccs)
61 | for i := 0; i < nAccs; i++ {
62 | acc := NewKey()
63 | accs = append(accs, acc)
64 | }
65 | return &IntegrationKeyring{
66 | keys: accs,
67 | }
68 | }
69 |
70 | // GetPrivKey returns the private key of the specified account.
71 | func (kr *IntegrationKeyring) GetPrivKey(index int) cryptotypes.PrivKey {
72 | return kr.keys[index].Priv
73 | }
74 |
75 | // GetAddr returns the address of the specified account.
76 | func (kr *IntegrationKeyring) GetAddr(index int) common.Address {
77 | return kr.keys[index].Addr
78 | }
79 |
80 | // GetAccAddr returns the sdk address of the specified account.
81 | func (kr *IntegrationKeyring) GetAccAddr(index int) sdktypes.AccAddress {
82 | return kr.keys[index].AccAddr
83 | }
84 |
85 | // GetAllAccAddrs returns all the sdk addresses of the accounts in the keyring.
86 | func (kr *IntegrationKeyring) GetAllAccAddrs() []sdktypes.AccAddress {
87 | accs := make([]sdktypes.AccAddress, 0, len(kr.keys))
88 | for _, key := range kr.keys {
89 | accs = append(accs, key.AccAddr)
90 | }
91 | return accs
92 | }
93 |
94 | // GetKey returns the key specified by index
95 | func (kr *IntegrationKeyring) GetKey(index int) Key {
96 | return kr.keys[index]
97 | }
98 |
99 | // GetKey returns the key specified by index
100 | func (kr *IntegrationKeyring) GetKeys() []Key {
101 | return kr.keys
102 | }
103 |
104 | // AddKey adds a new account to the keyring. It returns the index for the key
105 | func (kr *IntegrationKeyring) AddKey() int {
106 | acc := NewKey()
107 | index := len(kr.keys)
108 | kr.keys = append(kr.keys, acc)
109 | return index
110 | }
111 |
112 | // Sign signs message with the specified key.
113 | func (kr *IntegrationKeyring) Sign(index int, msg []byte) ([]byte, error) {
114 | privKey := kr.GetPrivKey(index)
115 | if privKey == nil {
116 | return nil, fmt.Errorf("no private key for account %d", index)
117 | }
118 | return privKey.Sign(msg)
119 | }
120 |
--------------------------------------------------------------------------------
/testutil/integration/common/network/network.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package network
5 |
6 | import (
7 | "testing"
8 | "time"
9 |
10 | sdkmath "cosmossdk.io/math"
11 | abcitypes "github.com/cometbft/cometbft/abci/types"
12 | sdktypes "github.com/cosmos/cosmos-sdk/types"
13 | sdktestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
14 | txtypes "github.com/cosmos/cosmos-sdk/types/tx"
15 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
16 | authz "github.com/cosmos/cosmos-sdk/x/authz"
17 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
18 | distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
19 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
20 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
21 | ibctesting "github.com/cosmos/ibc-go/v8/testing"
22 | feemarkettypes "github.com/evmos/evmos/v20/x/feemarket/types"
23 | )
24 |
25 | // Network is the interface that wraps the common methods to interact with integration test network.
26 | //
27 | // It was designed to avoid users to access module's keepers directly and force integration tests
28 | // to be closer to the real user's behavior.
29 | type Network interface {
30 | GetContext() sdktypes.Context
31 | GetChainID() string
32 | GetDenom() string
33 | GetOtherDenoms() []string
34 | GetValidators() []stakingtypes.Validator
35 | GetMinDepositAmt() sdkmath.Int
36 | NextBlock() error
37 | NextBlockAfter(duration time.Duration) error
38 | NextBlockWithTxs(txBytes ...[]byte) (*abcitypes.ResponseFinalizeBlock, error)
39 |
40 | // Clients
41 | GetAuthClient() authtypes.QueryClient
42 | GetAuthzClient() authz.QueryClient
43 | GetBankClient() banktypes.QueryClient
44 | GetStakingClient() stakingtypes.QueryClient
45 | GetDistrClient() distrtypes.QueryClient
46 | GetFeeMarketClient() feemarkettypes.QueryClient
47 | GetGovClient() govtypes.QueryClient
48 |
49 | BroadcastTxSync(txBytes []byte) (abcitypes.ExecTxResult, error)
50 | Simulate(txBytes []byte) (*txtypes.SimulateResponse, error)
51 | CheckTx(txBytes []byte) (*abcitypes.ResponseCheckTx, error)
52 |
53 | // GetIBCChain returns the IBC test chain.
54 | // NOTE: this is only used for testing IBC related functionality.
55 | // The idea is to deprecate this eventually.
56 | GetIBCChain(t *testing.T, coord *ibctesting.Coordinator) *ibctesting.TestChain
57 | GetEncodingConfig() sdktestutil.TestEncodingConfig
58 | }
59 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/common/clients.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package exrpcommon
4 |
5 | import (
6 | "github.com/cosmos/cosmos-sdk/baseapp"
7 | sdktypes "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/cosmos/cosmos-sdk/types/module/testutil"
9 | authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
10 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
11 | "github.com/cosmos/cosmos-sdk/x/authz"
12 | authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
13 | bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
14 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
15 | distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
16 | distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
17 | govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
18 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
19 | slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
20 | slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
21 | stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
22 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
23 |
24 | erc20keeper "github.com/evmos/evmos/v20/x/erc20/keeper"
25 | erc20types "github.com/evmos/evmos/v20/x/erc20/types"
26 | evmkeeper "github.com/evmos/evmos/v20/x/evm/keeper"
27 | evmtypes "github.com/evmos/evmos/v20/x/evm/types"
28 | feemarketkeeper "github.com/evmos/evmos/v20/x/feemarket/keeper"
29 | feemarkettypes "github.com/evmos/evmos/v20/x/feemarket/types"
30 | poakeeper "github.com/xrplevm/node/v8/x/poa/keeper"
31 | poatypes "github.com/xrplevm/node/v8/x/poa/types"
32 | )
33 |
34 | type NetworkKeepers interface {
35 | GetContext() sdktypes.Context
36 | GetEncodingConfig() testutil.TestEncodingConfig
37 |
38 | ERC20Keeper() erc20keeper.Keeper
39 | EvmKeeper() evmkeeper.Keeper
40 | GovKeeper() *govkeeper.Keeper
41 | BankKeeper() bankkeeper.Keeper
42 | StakingKeeper() *stakingkeeper.Keeper
43 | SlashingKeeper() slashingkeeper.Keeper
44 | DistrKeeper() distrkeeper.Keeper
45 | AccountKeeper() authkeeper.AccountKeeper
46 | AuthzKeeper() authzkeeper.Keeper
47 | FeeMarketKeeper() feemarketkeeper.Keeper
48 | PoaKeeper() poakeeper.Keeper
49 | }
50 |
51 | func getQueryHelper(ctx sdktypes.Context, encCfg testutil.TestEncodingConfig) *baseapp.QueryServiceTestHelper {
52 | interfaceRegistry := encCfg.InterfaceRegistry
53 | // This is needed so that state changes are not committed in precompiles
54 | // simulations.
55 | cacheCtx, _ := ctx.CacheContext()
56 | return baseapp.NewQueryServerTestHelper(cacheCtx, interfaceRegistry)
57 | }
58 |
59 | func GetERC20Client(n NetworkKeepers) erc20types.QueryClient {
60 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
61 | erc20types.RegisterQueryServer(queryHelper, n.ERC20Keeper())
62 | return erc20types.NewQueryClient(queryHelper)
63 | }
64 |
65 | func GetEvmClient(n NetworkKeepers) evmtypes.QueryClient {
66 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
67 | evmtypes.RegisterQueryServer(queryHelper, n.EvmKeeper())
68 | return evmtypes.NewQueryClient(queryHelper)
69 | }
70 |
71 | func GetGovClient(n NetworkKeepers) govtypes.QueryClient {
72 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
73 | govtypes.RegisterQueryServer(queryHelper, govkeeper.NewQueryServer(n.GovKeeper()))
74 | return govtypes.NewQueryClient(queryHelper)
75 | }
76 |
77 | func GetBankClient(n NetworkKeepers) banktypes.QueryClient {
78 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
79 | banktypes.RegisterQueryServer(queryHelper, n.BankKeeper())
80 | return banktypes.NewQueryClient(queryHelper)
81 | }
82 |
83 | func GetFeeMarketClient(n NetworkKeepers) feemarkettypes.QueryClient {
84 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
85 | feemarkettypes.RegisterQueryServer(queryHelper, n.FeeMarketKeeper())
86 | return feemarkettypes.NewQueryClient(queryHelper)
87 | }
88 |
89 | func GetAuthClient(n NetworkKeepers) authtypes.QueryClient {
90 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
91 | authtypes.RegisterQueryServer(queryHelper, authkeeper.NewQueryServer(n.AccountKeeper()))
92 | return authtypes.NewQueryClient(queryHelper)
93 | }
94 |
95 | func GetAuthzClient(n NetworkKeepers) authz.QueryClient {
96 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
97 | authz.RegisterQueryServer(queryHelper, n.AuthzKeeper())
98 | return authz.NewQueryClient(queryHelper)
99 | }
100 |
101 | func GetStakingClient(n NetworkKeepers) stakingtypes.QueryClient {
102 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
103 | stakingtypes.RegisterQueryServer(queryHelper, stakingkeeper.Querier{Keeper: n.StakingKeeper()})
104 | return stakingtypes.NewQueryClient(queryHelper)
105 | }
106 |
107 | func GetSlashingClient(n NetworkKeepers) slashingtypes.QueryClient {
108 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
109 | slashingtypes.RegisterQueryServer(queryHelper, slashingkeeper.Querier{Keeper: n.SlashingKeeper()})
110 | return slashingtypes.NewQueryClient(queryHelper)
111 | }
112 |
113 | func GetDistrClient(n NetworkKeepers) distrtypes.QueryClient {
114 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
115 | distrtypes.RegisterQueryServer(queryHelper, distrkeeper.Querier{Keeper: n.DistrKeeper()})
116 | return distrtypes.NewQueryClient(queryHelper)
117 | }
118 |
119 | func GetPoaClient(n NetworkKeepers) poatypes.QueryClient {
120 | queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig())
121 | poatypes.RegisterQueryServer(queryHelper, poakeeper.Querier{Keeper: n.PoaKeeper()})
122 | return poatypes.NewQueryClient(queryHelper)
123 | }
124 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/common/config.go:
--------------------------------------------------------------------------------
1 | package exrpcommon
2 |
3 | import (
4 | "math/big"
5 |
6 | sdkmath "cosmossdk.io/math"
7 | "github.com/cosmos/cosmos-sdk/baseapp"
8 | sdktypes "github.com/cosmos/cosmos-sdk/types"
9 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
10 | evmostypes "github.com/evmos/evmos/v20/types"
11 | "github.com/xrplevm/node/v8/app"
12 | )
13 |
14 | const (
15 | bip44CoinType = 60
16 | ChainID = "exrp_1440002-1"
17 | )
18 |
19 | // Config defines the configuration for a chain.
20 | // It allows for customization of the network to adjust to
21 | // testing needs.
22 | type Config struct {
23 | ChainID string
24 | EIP155ChainID *big.Int
25 | AmountOfValidators int
26 | PreFundedAccounts []sdktypes.AccAddress
27 | Balances []banktypes.Balance
28 | BondDenom string
29 | MaxValidators uint32
30 | Denom string
31 | CustomGenesisState CustomGenesisState
32 | GenesisBytes []byte
33 | OtherCoinDenom []string
34 | OperatorsAddrs []sdktypes.AccAddress
35 | CustomBaseAppOpts []func(*baseapp.BaseApp)
36 | MinDepositAmt sdkmath.Int
37 | Quorum string
38 | }
39 |
40 | type CustomGenesisState map[string]interface{}
41 |
42 | // DefaultConfig returns the default configuration for a chain.
43 | func DefaultConfig() Config {
44 | return Config{
45 | ChainID: ChainID,
46 | EIP155ChainID: big.NewInt(1440002),
47 | Balances: nil,
48 | Denom: app.BaseDenom,
49 | }
50 | }
51 |
52 | // ConfigOption defines a function that can modify the NetworkConfig.
53 | // The purpose of this is to force to be declarative when the default configuration
54 | // requires to be changed.
55 | type ConfigOption func(*Config)
56 |
57 | // WithChainID sets a custom chainID for the network. It panics if the chainID is invalid.
58 | func WithChainID(chainID string) ConfigOption {
59 | chainIDNum, err := evmostypes.ParseChainID(chainID)
60 | if err != nil {
61 | panic(err)
62 | }
63 | return func(cfg *Config) {
64 | cfg.ChainID = chainID
65 | cfg.EIP155ChainID = chainIDNum
66 | }
67 | }
68 |
69 | // WithAmountOfValidators sets the amount of validators for the network.
70 | func WithAmountOfValidators(amount int) ConfigOption {
71 | return func(cfg *Config) {
72 | cfg.AmountOfValidators = amount
73 | }
74 | }
75 |
76 | // WithPreFundedAccounts sets the pre-funded accounts for the network.
77 | func WithPreFundedAccounts(accounts ...sdktypes.AccAddress) ConfigOption {
78 | return func(cfg *Config) {
79 | cfg.PreFundedAccounts = accounts
80 | }
81 | }
82 |
83 | // WithBalances sets the specific balances for the pre-funded accounts, that
84 | // are being set up for the network.
85 | func WithBalances(balances ...banktypes.Balance) ConfigOption {
86 | return func(cfg *Config) {
87 | cfg.Balances = append(cfg.Balances, balances...)
88 | }
89 | }
90 |
91 | // WithBondDenom sets the bond denom for the network.
92 | func WithBondDenom(denom string) ConfigOption {
93 | return func(cfg *Config) {
94 | cfg.BondDenom = denom
95 | }
96 | }
97 |
98 | // WithMaxValidators sets the max validators for the network.
99 | func WithMaxValidators(maxValidators uint32) ConfigOption {
100 | return func(cfg *Config) {
101 | cfg.MaxValidators = maxValidators
102 | }
103 | }
104 |
105 | // WithDenom sets the denom for the network.
106 | func WithDenom(denom string) ConfigOption {
107 | return func(cfg *Config) {
108 | cfg.Denom = denom
109 | }
110 | }
111 |
112 | // WithCustomGenesis sets the custom genesis of the network for specific modules.
113 | func WithCustomGenesis(customGenesis CustomGenesisState) ConfigOption {
114 | return func(cfg *Config) {
115 | cfg.CustomGenesisState = customGenesis
116 | }
117 | }
118 |
119 | // WithOtherDenoms sets other possible coin denominations for the network.
120 | func WithOtherDenoms(otherDenoms []string) ConfigOption {
121 | return func(cfg *Config) {
122 | cfg.OtherCoinDenom = otherDenoms
123 | }
124 | }
125 |
126 | // WithValidatorOperators overwrites the used operator address for the network instantiation.
127 | func WithValidatorOperators(keys []sdktypes.AccAddress) ConfigOption {
128 | return func(cfg *Config) {
129 | cfg.OperatorsAddrs = keys
130 | }
131 | }
132 |
133 | // WithCustomBaseAppOpts sets custom base app options for the network.
134 | func WithCustomBaseAppOpts(opts ...func(*baseapp.BaseApp)) ConfigOption {
135 | return func(cfg *Config) {
136 | cfg.CustomBaseAppOpts = opts
137 | }
138 | }
139 |
140 | // WithMinDepositAmt sets the min deposit amount for the network.
141 | func WithMinDepositAmt(minDepositAmt sdkmath.Int) ConfigOption {
142 | return func(cfg *Config) {
143 | cfg.MinDepositAmt = minDepositAmt
144 | }
145 | }
146 |
147 | func WithQuorum(quorum string) ConfigOption {
148 | return func(cfg *Config) {
149 | cfg.Quorum = quorum
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/common/consensus.go:
--------------------------------------------------------------------------------
1 | package exrpcommon
2 |
3 | import (
4 | "time"
5 |
6 | cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
7 | cmttypes "github.com/cometbft/cometbft/types"
8 | )
9 |
10 | // DefaultConsensusParams defines the default Tendermint consensus params used in
11 | // Evmos testing.
12 | var DefaultConsensusParams = &cmtproto.ConsensusParams{
13 | Block: &cmtproto.BlockParams{
14 | MaxBytes: 200000,
15 | MaxGas: -1, // no limit
16 | },
17 | Evidence: &cmtproto.EvidenceParams{
18 | MaxAgeNumBlocks: 302400,
19 | MaxAgeDuration: 504 * time.Hour, // 3 weeks is the max duration
20 | MaxBytes: 10000,
21 | },
22 | Validator: &cmtproto.ValidatorParams{
23 | PubKeyTypes: []string{
24 | cmttypes.ABCIPubKeyTypeEd25519,
25 | },
26 | },
27 | }
28 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/common/network.go:
--------------------------------------------------------------------------------
1 | package exrpcommon
2 |
3 | import (
4 | "testing"
5 | "time"
6 |
7 | sdktypes "github.com/cosmos/cosmos-sdk/types"
8 | ibctesting "github.com/cosmos/ibc-go/v8/testing"
9 |
10 | abcitypes "github.com/cometbft/cometbft/abci/types"
11 | sdktestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
12 | txtypes "github.com/cosmos/cosmos-sdk/types/tx"
13 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
14 | )
15 |
16 | type Network interface {
17 | // Keepers
18 | NetworkKeepers
19 |
20 | // Clients
21 | BroadcastTxSync(txBytes []byte) (abcitypes.ExecTxResult, error)
22 | Simulate(txBytes []byte) (*txtypes.SimulateResponse, error)
23 | CheckTx(txBytes []byte) (*abcitypes.ResponseCheckTx, error)
24 |
25 | // GetIBCChain returns the IBC test chain.
26 | // NOTE: this is only used for testing IBC related functionality.
27 | // The idea is to deprecate this eventually.
28 | GetIBCChain(t *testing.T, coord *ibctesting.Coordinator) *ibctesting.TestChain
29 | GetEncodingConfig() sdktestutil.TestEncodingConfig
30 |
31 | // Getters
32 | GetContext() sdktypes.Context
33 | GetChainID() string
34 | GetBondDenom() string
35 | GetDenom() string
36 | GetOtherDenoms() []string
37 | GetValidators() []stakingtypes.Validator
38 |
39 | // ABCI
40 | NextBlock() error
41 | NextBlockAfter(duration time.Duration) error
42 | NextBlockWithTxs(txBytes ...[]byte) (*abcitypes.ResponseFinalizeBlock, error)
43 | }
44 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/common/setup.go:
--------------------------------------------------------------------------------
1 | package exrpcommon
2 |
3 | import (
4 | "fmt"
5 | "os"
6 |
7 | "cosmossdk.io/log"
8 | "github.com/cosmos/cosmos-sdk/baseapp"
9 | sdktypes "github.com/cosmos/cosmos-sdk/types"
10 |
11 | dbm "github.com/cosmos/cosmos-db"
12 | simutils "github.com/cosmos/cosmos-sdk/testutil/sims"
13 | "github.com/cosmos/gogoproto/proto"
14 | "github.com/xrplevm/node/v8/app"
15 |
16 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
17 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
18 | distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
19 | genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
20 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
21 | govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
22 | capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types"
23 | erc20types "github.com/evmos/evmos/v20/x/erc20/types"
24 | evmtypes "github.com/evmos/evmos/v20/x/evm/types"
25 | feemarkettypes "github.com/evmos/evmos/v20/x/feemarket/types"
26 | )
27 |
28 | // GenSetupFn is the type for the module genesis setup functions
29 | type GenSetupFn func(exrpApp *app.App, genesisState app.GenesisState, customGenesis interface{}) (app.GenesisState, error)
30 |
31 | var genesisSetupFunctions = map[string]GenSetupFn{
32 | evmtypes.ModuleName: GenStateSetter[*evmtypes.GenesisState](evmtypes.ModuleName),
33 | erc20types.ModuleName: GenStateSetter[*erc20types.GenesisState](erc20types.ModuleName),
34 | govtypes.ModuleName: GenStateSetter[*govtypesv1.GenesisState](govtypes.ModuleName),
35 | feemarkettypes.ModuleName: GenStateSetter[*feemarkettypes.GenesisState](feemarkettypes.ModuleName),
36 | distrtypes.ModuleName: GenStateSetter[*distrtypes.GenesisState](distrtypes.ModuleName),
37 | banktypes.ModuleName: GenStateSetter[*banktypes.GenesisState](banktypes.ModuleName),
38 | authtypes.ModuleName: GenStateSetter[*authtypes.GenesisState](authtypes.ModuleName),
39 | capabilitytypes.ModuleName: GenStateSetter[*capabilitytypes.GenesisState](capabilitytypes.ModuleName),
40 | genutiltypes.ModuleName: GenStateSetter[*genutiltypes.GenesisState](genutiltypes.ModuleName),
41 | }
42 |
43 | // GenStateSetter is a generic function to set module-specific genesis state
44 | func GenStateSetter[T proto.Message](moduleName string) GenSetupFn {
45 | return func(exrpApp *app.App, genesisState app.GenesisState, customGenesis interface{}) (app.GenesisState, error) {
46 | moduleGenesis, ok := customGenesis.(T)
47 | if !ok {
48 | return nil, fmt.Errorf("invalid type %T for %s module genesis state", customGenesis, moduleName)
49 | }
50 |
51 | genesisState[moduleName] = exrpApp.AppCodec().MustMarshalJSON(moduleGenesis)
52 | return genesisState, nil
53 | }
54 | }
55 |
56 | // CustomizeGenesis modifies genesis state if there're any custom genesis state
57 | // for specific modules
58 | func CustomizeGenesis(exrpApp *app.App, customGen CustomGenesisState, genesisState app.GenesisState) (app.GenesisState, error) {
59 | var err error
60 | for mod, modGenState := range customGen {
61 | if fn, found := genesisSetupFunctions[mod]; found {
62 | genesisState, err = fn(exrpApp, genesisState, modGenState)
63 | if err != nil {
64 | return genesisState, err
65 | }
66 | } else {
67 | panic(fmt.Sprintf("module %s not found in genesis setup functions", mod))
68 | }
69 | }
70 | return genesisState, err
71 | }
72 |
73 | func SetupSdkConfig() {
74 | accountPubKeyPrefix := app.AccountAddressPrefix + "pub"
75 | validatorAddressPrefix := app.AccountAddressPrefix + "valoper"
76 | validatorPubKeyPrefix := app.AccountAddressPrefix + "valoperpub"
77 | consNodeAddressPrefix := app.AccountAddressPrefix + "valcons"
78 | consNodePubKeyPrefix := app.AccountAddressPrefix + "valconspub"
79 |
80 | // Set config
81 | config := sdktypes.GetConfig()
82 | config.SetBech32PrefixForAccount(app.AccountAddressPrefix, accountPubKeyPrefix)
83 | config.SetBech32PrefixForValidator(validatorAddressPrefix, validatorPubKeyPrefix)
84 | config.SetBech32PrefixForConsensusNode(consNodeAddressPrefix, consNodePubKeyPrefix)
85 | config.SetCoinType(bip44CoinType)
86 | config.SetPurpose(sdktypes.Purpose) // Shared
87 | config.Seal()
88 | }
89 |
90 | func MustGetIntegrationTestNodeHome() string {
91 | wd, err := os.Getwd()
92 | if err != nil {
93 | panic(err)
94 | }
95 |
96 | return wd + "/../../"
97 | }
98 |
99 | // createExrpApp creates an exrp app
100 | func CreateExrpApp(chainID string, customBaseAppOptions ...func(*baseapp.BaseApp)) *app.App {
101 | testNodeHome := MustGetIntegrationTestNodeHome()
102 | // Create exrp app
103 | db := dbm.NewMemDB()
104 | logger := log.NewNopLogger()
105 | loadLatest := true
106 | skipUpgradeHeights := map[int64]bool{}
107 | homePath := testNodeHome
108 | invCheckPeriod := uint(5)
109 | appOptions := simutils.NewAppOptionsWithFlagHome(homePath)
110 | baseAppOptions := append(customBaseAppOptions, baseapp.SetChainID(chainID)) //nolint:gocritic
111 |
112 | return app.New(
113 | logger,
114 | db,
115 | nil,
116 | loadLatest,
117 | skipUpgradeHeights,
118 | homePath,
119 | invCheckPeriod,
120 | appOptions,
121 | baseAppOptions...,
122 | )
123 | }
124 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/integration/abci.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package exrpintegration
4 |
5 | import (
6 | "time"
7 |
8 | storetypes "cosmossdk.io/store/types"
9 | abcitypes "github.com/cometbft/cometbft/abci/types"
10 | cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
11 | cmttypes "github.com/cometbft/cometbft/types"
12 | )
13 |
14 | // NextBlock is a private helper function that runs the EndBlocker logic, commits the changes,
15 | // updates the header and runs the BeginBlocker
16 | func (n *IntegrationNetwork) NextBlock() error {
17 | return n.NextBlockAfter(time.Second)
18 | }
19 |
20 | // NextBlockAfter is a private helper function that runs the FinalizeBlock logic, updates the context and
21 | // commits the changes to have a block time after the given duration.
22 | func (n *IntegrationNetwork) NextBlockAfter(duration time.Duration) error {
23 | _, err := n.finalizeBlockAndCommit(duration, nil, nil)
24 | return err
25 | }
26 |
27 | // NextBlockWithTxs is a helper function that runs the FinalizeBlock logic
28 | // with the provided tx bytes, updates the context and
29 | // commits the changes to have a block time after the given duration.
30 | func (n *IntegrationNetwork) NextBlockWithTxs(txBytes ...[]byte) (*abcitypes.ResponseFinalizeBlock, error) {
31 | return n.finalizeBlockAndCommit(time.Second, n.valFlags, nil, txBytes...)
32 | }
33 |
34 | // NextNBlocksWithValidatorFlags is a helper function that runs the FinalizeBlock logic
35 | // with the provided validator flags, updates the context and
36 | // commits the changes to have a block time after the given duration.
37 | func (n *IntegrationNetwork) NextNBlocksWithValidatorFlags(blocks int64, validatorFlags []cmtproto.BlockIDFlag) error {
38 | for i := int64(0); i < blocks; i++ {
39 | _, err := n.finalizeBlockAndCommit(time.Second, validatorFlags, nil)
40 | if err != nil {
41 | return err
42 | }
43 | }
44 | return nil
45 | }
46 |
47 | // NextBlockWithMisBehaviors is a helper function that runs the FinalizeBlock logic
48 | // with the provided misbehaviors, updates the context and
49 | // commits the changes to have a block time after the given duration.
50 | func (n *IntegrationNetwork) NextBlockWithMisBehaviors(misbehaviors []abcitypes.Misbehavior) error {
51 | _, err := n.finalizeBlockAndCommit(time.Second, n.valFlags, misbehaviors)
52 | return err
53 | }
54 |
55 | // finalizeBlockAndCommit is a private helper function that runs the FinalizeBlock logic
56 | // with the provided txBytes, updates the context and
57 | // commits the changes to have a block time after the given duration.
58 | func (n *IntegrationNetwork) finalizeBlockAndCommit(duration time.Duration, vFlags []cmtproto.BlockIDFlag, misbehaviors []abcitypes.Misbehavior, txBytes ...[]byte) (*abcitypes.ResponseFinalizeBlock, error) {
59 | header := n.ctx.BlockHeader()
60 | // Update block header and BeginBlock
61 | header.Height++
62 | header.AppHash = n.app.LastCommitID().Hash
63 | // Calculate new block time after duration
64 | newBlockTime := header.Time.Add(duration)
65 | header.Time = newBlockTime
66 |
67 | var validatorFlags []cmtproto.BlockIDFlag
68 | if len(vFlags) > 0 {
69 | validatorFlags = vFlags
70 | } else {
71 | validatorFlags = n.valFlags
72 | }
73 |
74 | // FinalizeBlock to run endBlock, deliverTx & beginBlock logic
75 | req := BuildFinalizeBlockReq(header, n.valSet.Validators, validatorFlags, misbehaviors, txBytes...)
76 |
77 | res, err := n.app.FinalizeBlock(req)
78 | if err != nil {
79 | return nil, err
80 | }
81 |
82 | newCtx := n.app.BaseApp.NewContextLegacy(false, header)
83 |
84 | // Update context header
85 | newCtx = newCtx.WithMinGasPrices(n.ctx.MinGasPrices())
86 | newCtx = newCtx.WithKVGasConfig(n.ctx.KVGasConfig())
87 | newCtx = newCtx.WithTransientKVGasConfig(n.ctx.TransientKVGasConfig())
88 | newCtx = newCtx.WithConsensusParams(n.ctx.ConsensusParams())
89 | // This might have to be changed with time if we want to test gas limits
90 | newCtx = newCtx.WithBlockGasMeter(storetypes.NewInfiniteGasMeter())
91 | newCtx = newCtx.WithVoteInfos(req.DecidedLastCommit.GetVotes())
92 | n.ctx = newCtx
93 |
94 | // commit changes
95 | _, err = n.app.Commit()
96 |
97 | return res, err
98 | }
99 |
100 | // buildFinalizeBlockReq is a helper function to build
101 | // properly the FinalizeBlock request
102 | func BuildFinalizeBlockReq(header cmtproto.Header, validators []*cmttypes.Validator, validatorFlags []cmtproto.BlockIDFlag, misbehaviors []abcitypes.Misbehavior, txs ...[]byte) *abcitypes.RequestFinalizeBlock {
103 | // add validator's commit info to allocate corresponding tokens to validators
104 | ci := GetCommitInfo(validators, validatorFlags)
105 | return &abcitypes.RequestFinalizeBlock{
106 | Misbehavior: misbehaviors,
107 | Height: header.Height,
108 | DecidedLastCommit: ci,
109 | Hash: header.AppHash,
110 | NextValidatorsHash: header.ValidatorsHash,
111 | ProposerAddress: header.ProposerAddress,
112 | Time: header.Time,
113 | Txs: txs,
114 | }
115 | }
116 |
117 | func GetCommitInfo(validators []*cmttypes.Validator, validatorFlags []cmtproto.BlockIDFlag) abcitypes.CommitInfo {
118 | voteInfos := make([]abcitypes.VoteInfo, len(validators))
119 | for i, val := range validators {
120 | voteInfos[i] = abcitypes.VoteInfo{
121 | Validator: abcitypes.Validator{
122 | Address: val.Address,
123 | Power: val.VotingPower,
124 | },
125 | BlockIdFlag: validatorFlags[i],
126 | }
127 | }
128 | return abcitypes.CommitInfo{Votes: voteInfos}
129 | }
130 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/integration/config.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package exrpintegration
5 |
6 | import (
7 | "fmt"
8 |
9 | sdktypes "github.com/cosmos/cosmos-sdk/types"
10 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
11 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
12 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
13 | testtx "github.com/evmos/evmos/v20/testutil/tx"
14 | exrpcommon "github.com/xrplevm/node/v8/testutil/integration/exrp/common"
15 | )
16 |
17 | // DefaultIntegrationConfig returns the default configuration for a chain.
18 | func DefaultIntegrationConfig() exrpcommon.Config {
19 | account, _ := testtx.NewAccAddressAndKey()
20 | config := exrpcommon.DefaultConfig()
21 | config.AmountOfValidators = 3
22 | config.PreFundedAccounts = []sdktypes.AccAddress{account}
23 | return config
24 | }
25 |
26 | // getGenAccountsAndBalances takes the network configuration and returns the used
27 | // genesis accounts and balances.
28 | //
29 | // NOTE: If the balances are set, the pre-funded accounts are ignored.
30 | func getGenAccountsAndBalances(cfg exrpcommon.Config, validators []stakingtypes.Validator) (genAccounts []authtypes.GenesisAccount, balances []banktypes.Balance) {
31 | if len(cfg.Balances) > 0 {
32 | balances = cfg.Balances
33 | accounts := getAccAddrsFromBalances(balances)
34 | genAccounts = createGenesisAccounts(accounts)
35 | } else {
36 | genAccounts = createGenesisAccounts(cfg.PreFundedAccounts)
37 | balances = createBalances(cfg.PreFundedAccounts, append(cfg.OtherCoinDenom, cfg.Denom))
38 | }
39 |
40 | // append validators to genesis accounts and balances
41 | valAccs := make([]sdktypes.AccAddress, len(validators))
42 | for i, v := range validators {
43 | valAddr, err := sdktypes.ValAddressFromBech32(v.OperatorAddress)
44 | if err != nil {
45 | panic(fmt.Sprintf("failed to derive validator address from %q: %s", v.OperatorAddress, err.Error()))
46 | }
47 | valAccs[i] = sdktypes.AccAddress(valAddr.Bytes())
48 | }
49 | genAccounts = append(genAccounts, createGenesisAccounts(valAccs)...)
50 |
51 | return
52 | }
53 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/integration/ibc.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package exrpintegration
4 |
5 | import (
6 | "testing"
7 |
8 | ibctesting "github.com/cosmos/ibc-go/v8/testing"
9 | )
10 |
11 | // GetIBCChain returns a TestChain instance for the given network.
12 | // Note: the sender accounts are not populated. Do not use this accounts to send transactions during tests.
13 | // The keyring should be used instead.
14 | func (n *IntegrationNetwork) GetIBCChain(t *testing.T, coord *ibctesting.Coordinator) *ibctesting.TestChain {
15 | return &ibctesting.TestChain{
16 | TB: t,
17 | Coordinator: coord,
18 | ChainID: n.GetChainID(),
19 | App: n.app,
20 | CurrentHeader: n.ctx.BlockHeader(),
21 | QueryServer: n.app.GetIBCKeeper(),
22 | TxConfig: n.app.GetTxConfig(),
23 | Codec: n.app.AppCodec(),
24 | Vals: n.valSet,
25 | NextVals: n.valSet,
26 | Signers: n.valSigners,
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/integration/keepers.go:
--------------------------------------------------------------------------------
1 | package exrpintegration
2 |
3 | import (
4 | authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
5 | authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
6 | bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
7 | distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
8 | govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
9 | slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
10 | stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
11 |
12 | erc20keeper "github.com/evmos/evmos/v20/x/erc20/keeper"
13 | evmkeeper "github.com/evmos/evmos/v20/x/evm/keeper"
14 | feemarketkeeper "github.com/evmos/evmos/v20/x/feemarket/keeper"
15 | poakeeper "github.com/xrplevm/node/v8/x/poa/keeper"
16 | )
17 |
18 | func (n *IntegrationNetwork) BankKeeper() bankkeeper.Keeper {
19 | return n.app.BankKeeper
20 | }
21 |
22 | func (n *IntegrationNetwork) ERC20Keeper() erc20keeper.Keeper {
23 | return n.app.Erc20Keeper
24 | }
25 |
26 | func (n *IntegrationNetwork) EvmKeeper() evmkeeper.Keeper {
27 | return *n.app.EvmKeeper
28 | }
29 |
30 | func (n *IntegrationNetwork) GovKeeper() *govkeeper.Keeper {
31 | return &n.app.GovKeeper
32 | }
33 |
34 | func (n *IntegrationNetwork) StakingKeeper() *stakingkeeper.Keeper {
35 | return n.app.StakingKeeper.Keeper
36 | }
37 |
38 | func (n *IntegrationNetwork) SlashingKeeper() slashingkeeper.Keeper {
39 | return n.app.SlashingKeeper
40 | }
41 |
42 | func (n *IntegrationNetwork) DistrKeeper() distrkeeper.Keeper {
43 | return n.app.DistrKeeper
44 | }
45 |
46 | func (n *IntegrationNetwork) AccountKeeper() authkeeper.AccountKeeper {
47 | return n.app.AccountKeeper
48 | }
49 |
50 | func (n *IntegrationNetwork) AuthzKeeper() authzkeeper.Keeper {
51 | return n.app.AuthzKeeper
52 | }
53 |
54 | func (n *IntegrationNetwork) FeeMarketKeeper() feemarketkeeper.Keeper {
55 | return n.app.FeeMarketKeeper
56 | }
57 |
58 | func (n *IntegrationNetwork) PoaKeeper() poakeeper.Keeper {
59 | return n.app.PoaKeeper
60 | }
61 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/integration/unit_network.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package exrpintegration
4 |
5 | import (
6 | sdktypes "github.com/cosmos/cosmos-sdk/types"
7 | "github.com/ethereum/go-ethereum/common"
8 | "github.com/evmos/evmos/v20/x/evm/statedb"
9 | inflationtypes "github.com/evmos/evmos/v20/x/inflation/v1/types"
10 | "github.com/xrplevm/node/v8/app"
11 | exrpcommon "github.com/xrplevm/node/v8/testutil/integration/exrp/common"
12 | )
13 |
14 | // UnitTestIntegrationNetwork is the implementation of the Network interface for unit tests.
15 | // It embeds the IntegrationNetwork struct to reuse its methods and
16 | // makes the App public for easier testing.
17 | type UnitTestIntegrationNetwork struct {
18 | IntegrationNetwork
19 | App *app.App
20 | }
21 |
22 | var _ Network = (*UnitTestIntegrationNetwork)(nil)
23 |
24 | // NewUnitTestNetwork configures and initializes a new Evmos Network instance with
25 | // the given configuration options. If no configuration options are provided
26 | // it uses the default configuration.
27 | //
28 | // It panics if an error occurs.
29 | // Note: Only uses for Unit Tests
30 | func NewUnitTestNetwork(opts ...exrpcommon.ConfigOption) *UnitTestIntegrationNetwork {
31 | network := New(opts...)
32 | return &UnitTestIntegrationNetwork{
33 | IntegrationNetwork: *network,
34 | App: network.app,
35 | }
36 | }
37 |
38 | // GetStateDB returns the state database for the current block.
39 | func (n *UnitTestIntegrationNetwork) GetStateDB() *statedb.StateDB {
40 | headerHash := n.GetContext().HeaderHash()
41 | return statedb.New(
42 | n.GetContext(),
43 | n.App.EvmKeeper,
44 | statedb.NewEmptyTxConfig(common.BytesToHash(headerHash)),
45 | )
46 | }
47 |
48 | // FundAccount funds the given account with the given amount of coins.
49 | func (n *UnitTestIntegrationNetwork) FundAccount(addr sdktypes.AccAddress, coins sdktypes.Coins) error {
50 | ctx := n.GetContext()
51 |
52 | if err := n.app.BankKeeper.MintCoins(ctx, inflationtypes.ModuleName, coins); err != nil {
53 | return err
54 | }
55 |
56 | return n.app.BankKeeper.SendCoinsFromModuleToAccount(ctx, inflationtypes.ModuleName, addr, coins)
57 | }
58 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/upgrade/abci.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package exrpupgrade
4 |
5 | import (
6 | "time"
7 |
8 | storetypes "cosmossdk.io/store/types"
9 | abcitypes "github.com/cometbft/cometbft/abci/types"
10 | cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
11 | cmttypes "github.com/cometbft/cometbft/types"
12 | )
13 |
14 | // NextBlock is a private helper function that runs the EndBlocker logic, commits the changes,
15 | // updates the header and runs the BeginBlocker
16 | func (n *UpgradeIntegrationNetwork) NextBlock() error {
17 | return n.NextBlockAfter(time.Second)
18 | }
19 |
20 | // NextBlockAfter is a private helper function that runs the FinalizeBlock logic, updates the context and
21 | // commits the changes to have a block time after the given duration.
22 | func (n *UpgradeIntegrationNetwork) NextBlockAfter(duration time.Duration) error {
23 | _, err := n.finalizeBlockAndCommit(duration)
24 | return err
25 | }
26 |
27 | // NextBlockWithTxs is a helper function that runs the FinalizeBlock logic
28 | // with the provided tx bytes, updates the context and
29 | // commits the changes to have a block time after the given duration.
30 | func (n *UpgradeIntegrationNetwork) NextBlockWithTxs(txBytes ...[]byte) (*abcitypes.ResponseFinalizeBlock, error) {
31 | return n.finalizeBlockAndCommit(time.Second, txBytes...)
32 | }
33 |
34 | // finalizeBlockAndCommit is a private helper function that runs the FinalizeBlock logic
35 | // with the provided txBytes, updates the context and
36 | // commits the changes to have a block time after the given duration.
37 | func (n *UpgradeIntegrationNetwork) finalizeBlockAndCommit(duration time.Duration, txBytes ...[]byte) (*abcitypes.ResponseFinalizeBlock, error) {
38 | header := n.ctx.BlockHeader()
39 | // Update block header and BeginBlock
40 | header.Height++
41 | header.AppHash = n.app.LastCommitID().Hash
42 | // Calculate new block time after duration
43 | newBlockTime := header.Time.Add(duration)
44 | header.Time = newBlockTime
45 |
46 | // FinalizeBlock to run endBlock, deliverTx & beginBlock logic
47 | req := BuildFinalizeBlockReq(header, n.valSet.Validators, txBytes...)
48 |
49 | res, err := n.app.FinalizeBlock(req)
50 | if err != nil {
51 | return nil, err
52 | }
53 |
54 | newCtx := n.app.BaseApp.NewContextLegacy(false, header)
55 |
56 | // Update context header
57 | newCtx = newCtx.WithMinGasPrices(n.ctx.MinGasPrices())
58 | newCtx = newCtx.WithKVGasConfig(n.ctx.KVGasConfig())
59 | newCtx = newCtx.WithTransientKVGasConfig(n.ctx.TransientKVGasConfig())
60 | newCtx = newCtx.WithConsensusParams(n.ctx.ConsensusParams())
61 | // This might have to be changed with time if we want to test gas limits
62 | newCtx = newCtx.WithBlockGasMeter(storetypes.NewInfiniteGasMeter())
63 | newCtx = newCtx.WithVoteInfos(req.DecidedLastCommit.GetVotes())
64 | n.ctx = newCtx
65 |
66 | // commit changes
67 | _, err = n.app.Commit()
68 |
69 | return res, err
70 | }
71 |
72 | // buildFinalizeBlockReq is a helper function to build
73 | // properly the FinalizeBlock request
74 | func BuildFinalizeBlockReq(header cmtproto.Header, validators []*cmttypes.Validator, txs ...[]byte) *abcitypes.RequestFinalizeBlock {
75 | // add validator's commit info to allocate corresponding tokens to validators
76 | ci := GetCommitInfo(validators)
77 | return &abcitypes.RequestFinalizeBlock{
78 | Misbehavior: nil,
79 | Height: header.Height,
80 | DecidedLastCommit: ci,
81 | Hash: header.AppHash,
82 | NextValidatorsHash: header.ValidatorsHash,
83 | ProposerAddress: header.ProposerAddress,
84 | Time: header.Time,
85 | Txs: txs,
86 | }
87 | }
88 |
89 | func GetCommitInfo(validators []*cmttypes.Validator) abcitypes.CommitInfo {
90 | voteInfos := make([]abcitypes.VoteInfo, len(validators))
91 | for i, val := range validators {
92 | voteInfos[i] = abcitypes.VoteInfo{
93 | Validator: abcitypes.Validator{
94 | Address: val.Address,
95 | Power: val.VotingPower,
96 | },
97 | BlockIdFlag: cmtproto.BlockIDFlagCommit,
98 | }
99 | }
100 | return abcitypes.CommitInfo{Votes: voteInfos}
101 | }
102 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/upgrade/config.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package exrpupgrade
5 |
6 | import (
7 | "os"
8 |
9 | exrpcommon "github.com/xrplevm/node/v8/testutil/integration/exrp/common"
10 | )
11 |
12 | func DefaultUpgradeConfig() exrpcommon.Config {
13 | return exrpcommon.DefaultConfig()
14 | }
15 |
16 | // WithGenesisFile sets the genesis file for the network.
17 | func WithGenesisFile(genesisFile string) exrpcommon.ConfigOption {
18 | return func(cfg *exrpcommon.Config) {
19 | genesisBytes, err := os.ReadFile(genesisFile)
20 | if err != nil {
21 | panic(err)
22 | }
23 | cfg.GenesisBytes = genesisBytes
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/upgrade/ibc.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package exrpupgrade
4 |
5 | import (
6 | "testing"
7 |
8 | ibctesting "github.com/cosmos/ibc-go/v8/testing"
9 | )
10 |
11 | // GetIBCChain returns a TestChain instance for the given network.
12 | // Note: the sender accounts are not populated. Do not use this accounts to send transactions during tests.
13 | // The keyring should be used instead.
14 | func (n *UpgradeIntegrationNetwork) GetIBCChain(t *testing.T, coord *ibctesting.Coordinator) *ibctesting.TestChain {
15 | return &ibctesting.TestChain{
16 | TB: t,
17 | Coordinator: coord,
18 | ChainID: n.GetChainID(),
19 | App: n.app,
20 | CurrentHeader: n.ctx.BlockHeader(),
21 | QueryServer: n.app.GetIBCKeeper(),
22 | TxConfig: n.app.GetTxConfig(),
23 | Codec: n.app.AppCodec(),
24 | Vals: n.valSet,
25 | NextVals: n.valSet,
26 | Signers: n.valSigners,
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/upgrade/keepers.go:
--------------------------------------------------------------------------------
1 | package exrpupgrade
2 |
3 | import (
4 | authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
5 | authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
6 | bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
7 | distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
8 | govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
9 | slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
10 | stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
11 |
12 | erc20keeper "github.com/evmos/evmos/v20/x/erc20/keeper"
13 | evmkeeper "github.com/evmos/evmos/v20/x/evm/keeper"
14 | feemarketkeeper "github.com/evmos/evmos/v20/x/feemarket/keeper"
15 | poakeeper "github.com/xrplevm/node/v8/x/poa/keeper"
16 | )
17 |
18 | func (n *UpgradeIntegrationNetwork) BankKeeper() bankkeeper.Keeper {
19 | return n.app.BankKeeper
20 | }
21 |
22 | func (n *UpgradeIntegrationNetwork) ERC20Keeper() erc20keeper.Keeper {
23 | return n.app.Erc20Keeper
24 | }
25 |
26 | func (n *UpgradeIntegrationNetwork) EvmKeeper() evmkeeper.Keeper {
27 | return *n.app.EvmKeeper
28 | }
29 |
30 | func (n *UpgradeIntegrationNetwork) GovKeeper() *govkeeper.Keeper {
31 | return &n.app.GovKeeper
32 | }
33 |
34 | func (n *UpgradeIntegrationNetwork) StakingKeeper() *stakingkeeper.Keeper {
35 | return n.app.StakingKeeper.Keeper
36 | }
37 |
38 | func (n *UpgradeIntegrationNetwork) SlashingKeeper() slashingkeeper.Keeper {
39 | return n.app.SlashingKeeper
40 | }
41 |
42 | func (n *UpgradeIntegrationNetwork) DistrKeeper() distrkeeper.Keeper {
43 | return n.app.DistrKeeper
44 | }
45 |
46 | func (n *UpgradeIntegrationNetwork) AccountKeeper() authkeeper.AccountKeeper {
47 | return n.app.AccountKeeper
48 | }
49 |
50 | func (n *UpgradeIntegrationNetwork) AuthzKeeper() authzkeeper.Keeper {
51 | return n.app.AuthzKeeper
52 | }
53 |
54 | func (n *UpgradeIntegrationNetwork) FeeMarketKeeper() feemarketkeeper.Keeper {
55 | return n.app.FeeMarketKeeper
56 | }
57 |
58 | func (n *UpgradeIntegrationNetwork) PoaKeeper() poakeeper.Keeper {
59 | return n.app.PoaKeeper
60 | }
61 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/upgrade/unit_network.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package exrpupgrade
4 |
5 | import (
6 | sdktypes "github.com/cosmos/cosmos-sdk/types"
7 | "github.com/ethereum/go-ethereum/common"
8 | "github.com/evmos/evmos/v20/x/evm/statedb"
9 | inflationtypes "github.com/evmos/evmos/v20/x/inflation/v1/types"
10 | "github.com/xrplevm/node/v8/app"
11 | exrpcommon "github.com/xrplevm/node/v8/testutil/integration/exrp/common"
12 | )
13 |
14 | // UnitTestUpgradeNetwork is the implementation of the Network interface for unit tests.
15 | // It embeds the IntegrationNetwork struct to reuse its methods and
16 | // makes the App public for easier testing.
17 | type UnitTestUpgradeNetwork struct {
18 | UpgradeIntegrationNetwork
19 | App *app.App
20 | }
21 |
22 | var _ Network = (*UnitTestUpgradeNetwork)(nil)
23 |
24 | // NewUnitTestNetwork configures and initializes a new Evmos Network instance with
25 | // the given configuration options. If no configuration options are provided
26 | // it uses the default configuration.
27 | //
28 | // It panics if an error occurs.
29 | // Note: Only uses for Unit Tests
30 | func NewUnitTestUpgradeNetwork(opts ...exrpcommon.ConfigOption) *UnitTestUpgradeNetwork {
31 | network := New(opts...)
32 | return &UnitTestUpgradeNetwork{
33 | UpgradeIntegrationNetwork: *network,
34 | App: network.app,
35 | }
36 | }
37 |
38 | // GetStateDB returns the state database for the current block.
39 | func (n *UnitTestUpgradeNetwork) GetStateDB() *statedb.StateDB {
40 | headerHash := n.GetContext().HeaderHash()
41 | return statedb.New(
42 | n.GetContext(),
43 | n.App.EvmKeeper,
44 | statedb.NewEmptyTxConfig(common.BytesToHash(headerHash)),
45 | )
46 | }
47 |
48 | // FundAccount funds the given account with the given amount of coins.
49 | func (n *UnitTestUpgradeNetwork) FundAccount(addr sdktypes.AccAddress, coins sdktypes.Coins) error {
50 | ctx := n.GetContext()
51 |
52 | if err := n.app.BankKeeper.MintCoins(ctx, inflationtypes.ModuleName, coins); err != nil {
53 | return err
54 | }
55 |
56 | return n.app.BankKeeper.SendCoinsFromModuleToAccount(ctx, inflationtypes.ModuleName, addr, coins)
57 | }
58 |
--------------------------------------------------------------------------------
/testutil/integration/exrp/utils/abci.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
5 | )
6 |
7 | type ValidatorFlagOverride struct {
8 | Index int
9 | Flag cmtproto.BlockIDFlag
10 | }
11 |
12 | func NewValidatorFlagOverride(index int, flag cmtproto.BlockIDFlag) ValidatorFlagOverride {
13 | return ValidatorFlagOverride{
14 | Index: index,
15 | Flag: flag,
16 | }
17 | }
18 |
19 | func NewValidatorFlags(n int, overrides ...ValidatorFlagOverride) []cmtproto.BlockIDFlag {
20 | flags := make([]cmtproto.BlockIDFlag, n)
21 | for i := range flags {
22 | flags[i] = cmtproto.BlockIDFlagCommit
23 | }
24 |
25 | for _, override := range overrides {
26 | flags[override.Index] = override.Flag
27 | }
28 |
29 | return flags
30 | }
31 |
--------------------------------------------------------------------------------
/testutil/sample/sample.go:
--------------------------------------------------------------------------------
1 | package sample
2 |
3 | import (
4 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
5 | sdk "github.com/cosmos/cosmos-sdk/types"
6 | )
7 |
8 | // AccAddress returns a sample account address
9 | func AccAddress() string {
10 | pk := ed25519.GenPrivKey().PubKey()
11 | addr := pk.Address()
12 | return sdk.AccAddress(addr).String()
13 | }
14 |
--------------------------------------------------------------------------------
/tools/cosmovisor/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.20-alpine AS build
2 |
3 | ENV COSMOS_VERSION=v0.46.12
4 |
5 | RUN apk update
6 | RUN apk add --no-cache gcc libc-dev make git
7 |
8 | WORKDIR /root
9 | RUN git clone --depth 1 --branch $COSMOS_VERSION https://github.com/cosmos/cosmos-sdk.git
10 | WORKDIR /root/cosmos-sdk/cosmovisor
11 | RUN make cosmovisor
12 |
13 |
14 | FROM alpine:3.17.3
15 |
16 | ENV DAEMON_HOME=/root/.exrpd
17 | ENV DAEMON_NAME=exrpd
18 | ENV DAEMON_ALLOW_DOWNLOAD_BINARIES=true
19 | ENV DAEMON_RESTART_AFTER_UPGRADE=true
20 |
21 | COPY --from=build /root/cosmos-sdk/cosmovisor/cosmovisor /usr/local/bin/cosmovisor
22 | COPY --from=peersyst/xrp-evm-blockchain:latest /usr/bin/exrpd /usr/local/bin/exrpd
23 | COPY --from=peersyst/exrp:v2.0.0 /usr/bin/exrpd /usr/local/bin/exrpd_v2.0.0
24 | COPY --from=peersyst/exrp:v3.0.0 /usr/bin/exrpd /usr/local/bin/exrpd_v3.0.0
25 |
26 | ADD tools/cosmovisor/init.sh /usr/local/bin/initialize
27 | RUN chmod +x /usr/local/bin/initialize
28 |
29 | RUN apk add gcompat
30 | RUN ln -sf ../../lib/libgcompat.so.0 /usr/lib/libresolv.so.2
31 |
32 | CMD ["cosmovisor"]
33 |
--------------------------------------------------------------------------------
/tools/cosmovisor/init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | mkdir -p $DAEMON_HOME/cosmovisor/genesis/bin
4 | ln -s /usr/local/bin/exrpd $DAEMON_HOME/cosmovisor/genesis/bin/exrpd
5 | mkdir -p $DAEMON_HOME/cosmovisor/upgrades/v2.0.0/bin
6 | cp /usr/local/bin/exrpd_v2.0.0 $DAEMON_HOME/cosmovisor/upgrades/v2.0.0/bin/exrpd
7 | mkdir -p $DAEMON_HOME/cosmovisor/upgrades/v3.0.0/bin
8 | cp /usr/local/bin/exrpd_v3.0.0 $DAEMON_HOME/cosmovisor/upgrades/v3.0.0/bin/exrpd
9 |
10 | ln -s $DAEMON_HOME/cosmovisor/upgrades/v2.0.0 $DAEMON_HOME/cosmovisor/current
--------------------------------------------------------------------------------
/tools/tools.go:
--------------------------------------------------------------------------------
1 | //go:build tools
2 |
3 | package tools
4 |
5 | import (
6 | _ "github.com/cosmos/gogoproto/protoc-gen-gocosmos"
7 | _ "github.com/golang/protobuf/protoc-gen-go"
8 | _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway"
9 | _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger"
10 | _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
11 | )
12 |
--------------------------------------------------------------------------------
/x/poa/ante/poa.go:
--------------------------------------------------------------------------------
1 | package ante
2 |
3 | import (
4 | "errors"
5 |
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
8 | )
9 |
10 | type PoaDecorator struct{}
11 |
12 | func NewPoaDecorator() PoaDecorator {
13 | return PoaDecorator{}
14 | }
15 |
16 | func (cbd PoaDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
17 | // loop through all the messages and check if the message type is allowed
18 | for _, msg := range tx.GetMsgs() {
19 | if sdk.MsgTypeURL(msg) == sdk.MsgTypeURL(&stakingtypes.MsgUndelegate{}) ||
20 | sdk.MsgTypeURL(msg) == sdk.MsgTypeURL(&stakingtypes.MsgBeginRedelegate{}) ||
21 | sdk.MsgTypeURL(msg) == sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}) ||
22 | sdk.MsgTypeURL(msg) == sdk.MsgTypeURL(&stakingtypes.MsgCancelUnbondingDelegation{}) {
23 | return ctx, errors.New("tx type not allowed")
24 | }
25 | }
26 |
27 | return next(ctx, tx, simulate)
28 | }
29 |
--------------------------------------------------------------------------------
/x/poa/ante/poa_test.go:
--------------------------------------------------------------------------------
1 | package ante
2 |
3 | import (
4 | "errors"
5 | "testing"
6 | "time"
7 |
8 | storetypes "cosmossdk.io/store/types"
9 |
10 | tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
11 | sdktestutil "github.com/cosmos/cosmos-sdk/testutil"
12 | sdk "github.com/cosmos/cosmos-sdk/types"
13 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
14 | "github.com/golang/mock/gomock"
15 | "github.com/stretchr/testify/require"
16 | "github.com/xrplevm/node/v8/x/poa/testutil"
17 | "github.com/xrplevm/node/v8/x/poa/types"
18 | )
19 |
20 | func setupPoaDecorator(t *testing.T) (
21 | PoaDecorator,
22 | sdk.Context,
23 | ) {
24 | key := storetypes.NewKVStoreKey(types.StoreKey)
25 | tsKey := storetypes.NewTransientStoreKey("transient_test")
26 | testCtx := sdktestutil.DefaultContextWithDB(t, key, tsKey)
27 | ctx := testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: time.Now()})
28 |
29 | return NewPoaDecorator(), ctx
30 | }
31 |
32 | func TestPoaDecorator_AnteHandle(t *testing.T) {
33 | tt := []struct {
34 | name string
35 | msgs []sdk.Msg
36 | expectedError error
37 | }{
38 | {
39 | name: "should return error - tx not allowed",
40 | msgs: []sdk.Msg{
41 | &stakingtypes.MsgUndelegate{},
42 | &stakingtypes.MsgBeginRedelegate{},
43 | &stakingtypes.MsgDelegate{},
44 | &stakingtypes.MsgCancelUnbondingDelegation{},
45 | },
46 | expectedError: errors.New("tx type not allowed"),
47 | },
48 | {
49 | name: "should not return error",
50 | msgs: []sdk.Msg{
51 | &stakingtypes.MsgEditValidator{},
52 | },
53 | },
54 | }
55 |
56 | for _, tc := range tt {
57 | pd, ctx := setupPoaDecorator(t)
58 |
59 | ctrl := gomock.NewController(t)
60 | txMock := testutil.NewMockTx(ctrl)
61 | txMock.EXPECT().GetMsgs().Return(tc.msgs).AnyTimes()
62 |
63 | mockNext := func(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) {
64 | return ctx, nil
65 | }
66 |
67 | _, err := pd.AnteHandle(ctx, txMock, false, mockNext)
68 | if tc.expectedError != nil {
69 | require.Error(t, err)
70 | require.Equal(t, tc.expectedError, err)
71 | } else {
72 | require.NoError(t, err)
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/x/poa/keeper/common_test.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "testing"
5 | "time"
6 |
7 | storetypes "cosmossdk.io/store/types"
8 | tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
9 | "github.com/cosmos/cosmos-sdk/baseapp"
10 |
11 | sdktestutil "github.com/cosmos/cosmos-sdk/testutil"
12 | sdk "github.com/cosmos/cosmos-sdk/types"
13 | moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
14 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
15 | "github.com/golang/mock/gomock"
16 | "github.com/xrplevm/node/v8/x/poa/testutil"
17 | "github.com/xrplevm/node/v8/x/poa/types"
18 |
19 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
20 | )
21 |
22 | const (
23 | accountAddressPrefix = "ethm"
24 | bip44CoinType = 60
25 | )
26 |
27 | func setupSdkConfig() {
28 | accountPubKeyPrefix := accountAddressPrefix + "pub"
29 | validatorAddressPrefix := accountAddressPrefix + "valoper"
30 | validatorPubKeyPrefix := accountAddressPrefix + "valoperpub"
31 | consNodeAddressPrefix := accountAddressPrefix + "valcons"
32 | consNodePubKeyPrefix := accountAddressPrefix + "valconspub"
33 |
34 | // Set config
35 | config := sdk.GetConfig()
36 | config.SetBech32PrefixForAccount(accountAddressPrefix, accountPubKeyPrefix)
37 | config.SetBech32PrefixForValidator(validatorAddressPrefix, validatorPubKeyPrefix)
38 | config.SetBech32PrefixForConsensusNode(consNodeAddressPrefix, consNodePubKeyPrefix)
39 | config.SetCoinType(bip44CoinType)
40 | config.SetPurpose(sdk.Purpose) // Shared
41 | }
42 |
43 | func getStakingKeeperMock(t *testing.T, ctx sdk.Context, setExpectations func(ctx sdk.Context, stakingKeeper *testutil.MockStakingKeeper)) *testutil.MockStakingKeeper {
44 | ctrl := gomock.NewController(t)
45 | stakingKeeper := testutil.NewMockStakingKeeper(ctrl)
46 | setExpectations(ctx, stakingKeeper)
47 | return stakingKeeper
48 | }
49 |
50 | func getBankKeeperMock(t *testing.T, ctx sdk.Context, setExpectations func(ctx sdk.Context, bankKeeper *testutil.MockBankKeeper)) *testutil.MockBankKeeper {
51 | ctrl := gomock.NewController(t)
52 | bankKeeper := testutil.NewMockBankKeeper(ctrl)
53 | setExpectations(ctx, bankKeeper)
54 | return bankKeeper
55 | }
56 |
57 | func getCtxMock(t *testing.T, key *storetypes.KVStoreKey, tsKey *storetypes.TransientStoreKey) sdk.Context {
58 | setupSdkConfig()
59 |
60 | testCtx := sdktestutil.DefaultContextWithDB(t, key, tsKey)
61 | ctx := testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: time.Now()})
62 | return ctx
63 | }
64 |
65 | func getMockedPoAKeeper(t *testing.T, key *storetypes.KVStoreKey, tsKey *storetypes.TransientStoreKey, ctx sdk.Context, stakingKeeper *testutil.MockStakingKeeper, bankKeeper *testutil.MockBankKeeper) *Keeper {
66 | encCfg := moduletestutil.MakeTestEncodingConfig()
67 |
68 | types.RegisterInterfaces(encCfg.InterfaceRegistry)
69 | stakingtypes.RegisterInterfaces(encCfg.InterfaceRegistry)
70 |
71 | msr := baseapp.NewMsgServiceRouter()
72 | msr.SetInterfaceRegistry(encCfg.InterfaceRegistry)
73 |
74 | ctrl := gomock.NewController(t)
75 | stakingMsr := testutil.NewMockStakingMsgServer(ctrl)
76 |
77 | stakingMsr.EXPECT().CreateValidator(gomock.Any(), gomock.Any()).Return(&stakingtypes.MsgCreateValidatorResponse{}, nil).AnyTimes()
78 |
79 | poaKeeper := NewKeeper(
80 | encCfg.Codec,
81 | paramtypes.NewSubspace(encCfg.Codec, encCfg.Amino, key, tsKey, "poa"),
82 | msr,
83 | bankKeeper,
84 | stakingKeeper,
85 | "ethm1wunfhl05vc8r8xxnnp8gt62wa54r6y52pg03zq",
86 | )
87 | poaKeeper.SetParams(ctx, types.DefaultParams())
88 | types.RegisterMsgServer(msr, NewMsgServerImpl(*poaKeeper))
89 | stakingtypes.RegisterMsgServer(msr, stakingMsr)
90 |
91 | return poaKeeper
92 | }
93 |
94 | func setupPoaKeeper(t *testing.T, setStakingExpectations func(ctx sdk.Context, stakingKeeper *testutil.MockStakingKeeper), setBankExpectations func(ctx sdk.Context, bankKeeper *testutil.MockBankKeeper)) (*Keeper, sdk.Context) {
95 | key := storetypes.NewKVStoreKey(types.StoreKey)
96 | tsKey := storetypes.NewTransientStoreKey("test")
97 |
98 | ctx := getCtxMock(t, key, tsKey)
99 | stakingKeeper := getStakingKeeperMock(t, ctx, setStakingExpectations)
100 | bankKeeper := getBankKeeperMock(t, ctx, setBankExpectations)
101 |
102 | return getMockedPoAKeeper(t, key, tsKey, ctx, stakingKeeper, bankKeeper), ctx
103 | }
104 |
--------------------------------------------------------------------------------
/x/poa/keeper/genesis.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 | "github.com/xrplevm/node/v8/x/poa/types"
6 | )
7 |
8 | // InitGenesis initializes the module's state from a provided genesis state.
9 | func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) {
10 | // this line is used by starport scaffolding # genesis/module/init
11 | k.SetParams(ctx, genState.Params)
12 | }
13 |
14 | // ExportGenesis returns the module's exported genesis
15 | func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
16 | genesis := types.DefaultGenesis()
17 | genesis.Params = k.GetParams(ctx)
18 |
19 | // this line is used by starport scaffolding # genesis/module/export
20 |
21 | return genesis
22 | }
23 |
--------------------------------------------------------------------------------
/x/poa/keeper/msg_server.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "github.com/xrplevm/node/v8/x/poa/types"
5 | )
6 |
7 | type msgServer struct {
8 | Keeper
9 | }
10 |
11 | // NewMsgServerImpl returns an implementation of the MsgServer interface
12 | // for the provided Keeper.
13 | func NewMsgServerImpl(keeper Keeper) types.MsgServer {
14 | return &msgServer{Keeper: keeper}
15 | }
16 |
17 | var _ types.MsgServer = msgServer{}
18 |
--------------------------------------------------------------------------------
/x/poa/keeper/msg_server_add_validator.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "context"
5 |
6 | "cosmossdk.io/errors"
7 |
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | gov "github.com/cosmos/cosmos-sdk/x/gov/types"
10 | "github.com/xrplevm/node/v8/x/poa/types"
11 | )
12 |
13 | func (k msgServer) AddValidator(goCtx context.Context, msg *types.MsgAddValidator) (*types.MsgAddValidatorResponse, error) {
14 | if k.authority != msg.Authority {
15 | return nil, errors.Wrapf(gov.ErrInvalidSigner, "expected %s got %s", k.authority, msg.Authority)
16 | }
17 |
18 | ctx := sdk.UnwrapSDKContext(goCtx)
19 | err := k.ExecuteAddValidator(ctx, msg)
20 | if err != nil {
21 | return nil, err
22 | }
23 |
24 | return &types.MsgAddValidatorResponse{}, nil
25 | }
26 |
--------------------------------------------------------------------------------
/x/poa/keeper/msg_server_add_validator_test.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | types1 "github.com/cosmos/cosmos-sdk/codec/types"
8 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
9 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
10 | "github.com/golang/mock/gomock"
11 | "github.com/stretchr/testify/require"
12 | "github.com/xrplevm/node/v8/x/poa/testutil"
13 | "github.com/xrplevm/node/v8/x/poa/types"
14 | )
15 |
16 | func TestMsgServer_AddValidator(t *testing.T) {
17 | poaKeeper, ctx := poaKeeperTestSetup(t)
18 |
19 | ctrl := gomock.NewController(t)
20 | pubKey := testutil.NewMockPubKey(ctrl)
21 | msgPubKey, _ := types1.NewAnyWithValue(pubKey)
22 | msgServer := NewMsgServerImpl(*poaKeeper)
23 |
24 | tt := []struct {
25 | name string
26 | authority string
27 | validatorAddress string
28 | expectedErr error
29 | }{
30 | {
31 | name: "should fail - invalid authority address",
32 | authority: "invalidauthority",
33 | validatorAddress: "ethm1a0pd5cyew47pvgf7rd7axxy3humv9ev0nnkprp",
34 | expectedErr: govtypes.ErrInvalidSigner,
35 | },
36 | {
37 | name: "should fail - invalid validator address",
38 | authority: poaKeeper.GetAuthority(),
39 | validatorAddress: "invalidvalidatoraddress",
40 | expectedErr: errors.New("decoding bech32 failed"),
41 | },
42 | {
43 | name: "should pass",
44 | authority: poaKeeper.GetAuthority(),
45 | validatorAddress: "ethm1a0pd5cyew47pvgf7rd7axxy3humv9ev0nnkprp",
46 | },
47 | }
48 |
49 | for _, tc := range tt {
50 | t.Run(tc.name, func(t *testing.T) {
51 | msg := &types.MsgAddValidator{
52 | Authority: tc.authority,
53 | ValidatorAddress: tc.validatorAddress,
54 | Description: stakingtypes.Description{
55 | Moniker: "test",
56 | Identity: "test",
57 | Website: "test",
58 | SecurityContact: "test",
59 | Details: "test",
60 | },
61 | Pubkey: msgPubKey,
62 | }
63 |
64 | _, err := msgServer.AddValidator(ctx, msg)
65 | if tc.expectedErr != nil {
66 | require.Error(t, err)
67 | require.Contains(t, err.Error(), tc.expectedErr.Error())
68 | } else {
69 | require.NoError(t, err)
70 | }
71 | })
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/x/poa/keeper/msg_server_remove_validator.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "context"
5 |
6 | "cosmossdk.io/errors"
7 |
8 | gov "github.com/cosmos/cosmos-sdk/x/gov/types"
9 |
10 | sdk "github.com/cosmos/cosmos-sdk/types"
11 | "github.com/xrplevm/node/v8/x/poa/types"
12 | )
13 |
14 | func (k msgServer) RemoveValidator(goCtx context.Context, msg *types.MsgRemoveValidator) (*types.MsgRemoveValidatorResponse, error) {
15 | if k.authority != msg.Authority {
16 | return nil, errors.Wrapf(gov.ErrInvalidSigner, "expected %s got %s", k.authority, msg.Authority)
17 | }
18 |
19 | ctx := sdk.UnwrapSDKContext(goCtx)
20 | err := k.ExecuteRemoveValidator(ctx, msg.ValidatorAddress)
21 | if err != nil {
22 | return nil, err
23 | }
24 |
25 | return &types.MsgRemoveValidatorResponse{}, nil
26 | }
27 |
--------------------------------------------------------------------------------
/x/poa/keeper/msg_server_remove_validator_test.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
8 | "github.com/stretchr/testify/require"
9 | "github.com/xrplevm/node/v8/x/poa/types"
10 | )
11 |
12 | func TestMsgServer_RemoveValidator(t *testing.T) {
13 | poaKeeper, ctx := poaKeeperTestSetup(t)
14 |
15 | msgServer := NewMsgServerImpl(*poaKeeper)
16 |
17 | tt := []struct {
18 | name string
19 | authority string
20 | validatorAddress string
21 | expectedErr error
22 | }{
23 | {
24 | name: "should fail - invalid authority address",
25 | authority: "invalidauthority",
26 | validatorAddress: "ethmvaloper1a0pd5cyew47pvgf7rd7axxy3humv9ev0urudmu",
27 | expectedErr: govtypes.ErrInvalidSigner,
28 | },
29 | {
30 | name: "should fail - invalid validator address",
31 | authority: poaKeeper.GetAuthority(),
32 | validatorAddress: "invalidvalidatoraddress",
33 | expectedErr: errors.New("decoding bech32 failed"),
34 | },
35 | {
36 | name: "should pass",
37 | authority: poaKeeper.GetAuthority(),
38 | validatorAddress: "ethmvaloper1a0pd5cyew47pvgf7rd7axxy3humv9ev0urudmu",
39 | },
40 | }
41 |
42 | for _, tc := range tt {
43 | t.Run(tc.name, func(t *testing.T) {
44 | msg := &types.MsgRemoveValidator{
45 | Authority: tc.authority,
46 | ValidatorAddress: tc.validatorAddress,
47 | }
48 |
49 | _, err := msgServer.RemoveValidator(ctx, msg)
50 | if tc.expectedErr != nil {
51 | require.Error(t, err)
52 | require.Contains(t, err.Error(), tc.expectedErr.Error())
53 | } else {
54 | require.NoError(t, err)
55 | }
56 | })
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/x/poa/keeper/params.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 | "github.com/xrplevm/node/v8/x/poa/types"
6 | )
7 |
8 | // GetParams get all parameters as types.Params
9 | func (k Keeper) GetParams(_ sdk.Context) types.Params {
10 | return types.NewParams()
11 | }
12 |
13 | // SetParams set the params
14 | func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
15 | k.paramstore.SetParamSet(ctx, ¶ms)
16 | }
17 |
--------------------------------------------------------------------------------
/x/poa/keeper/query.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "github.com/xrplevm/node/v8/x/poa/types"
5 | )
6 |
7 | var _ types.QueryServer = Keeper{}
8 |
--------------------------------------------------------------------------------
/x/poa/keeper/query_params.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "context"
5 |
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | "github.com/xrplevm/node/v8/x/poa/types"
8 | "google.golang.org/grpc/codes"
9 | "google.golang.org/grpc/status"
10 | )
11 |
12 | func (k Keeper) Params(goCtx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
13 | if req == nil {
14 | return nil, status.Error(codes.InvalidArgument, "invalid request")
15 | }
16 | ctx := sdk.UnwrapSDKContext(goCtx)
17 |
18 | return &types.QueryParamsResponse{Params: k.GetParams(ctx)}, nil
19 | }
20 |
--------------------------------------------------------------------------------
/x/poa/module.go:
--------------------------------------------------------------------------------
1 | package poa
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "fmt"
7 |
8 | "cosmossdk.io/core/appmodule"
9 |
10 | // this line is used by starport scaffolding # 1
11 |
12 | "github.com/cosmos/cosmos-sdk/client"
13 | "github.com/cosmos/cosmos-sdk/codec"
14 | cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
15 | sdk "github.com/cosmos/cosmos-sdk/types"
16 | "github.com/cosmos/cosmos-sdk/types/module"
17 | "github.com/grpc-ecosystem/grpc-gateway/runtime"
18 | "github.com/xrplevm/node/v8/x/poa/keeper"
19 | "github.com/xrplevm/node/v8/x/poa/types"
20 | )
21 |
22 | var (
23 | _ module.AppModuleBasic = (*AppModule)(nil)
24 | _ module.AppModuleSimulation = (*AppModule)(nil)
25 | _ module.HasGenesis = (*AppModule)(nil)
26 | _ appmodule.AppModule = (*AppModule)(nil)
27 | )
28 |
29 | // ----------------------------------------------------------------------------
30 | // AppModuleBasic
31 | // ----------------------------------------------------------------------------
32 |
33 | // AppModuleBasic implements the AppModuleBasic interface that defines the independent methods a Cosmos SDK module needs to implement.
34 | type AppModuleBasic struct {
35 | cdc codec.BinaryCodec
36 | }
37 |
38 | func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic {
39 | return AppModuleBasic{cdc: cdc}
40 | }
41 |
42 | // Name returns the name of the module as a string
43 | func (AppModuleBasic) Name() string {
44 | return types.ModuleName
45 | }
46 |
47 | // RegisterLegacyAminoCodec registers the amino codec for the module, which is used to marshal and unmarshal structs to/from []byte in order to persist them in the module's KVStore
48 | func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
49 | types.RegisterCodec(cdc)
50 | }
51 |
52 | // RegisterInterfaces registers a module's interface types and their concrete implementations as proto.Message
53 | func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) {
54 | types.RegisterInterfaces(reg)
55 | }
56 |
57 | // DefaultGenesis returns a default GenesisState for the module, marshaled to json.RawMessage. The default GenesisState need to be defined by the module developer and is primarily used for testing
58 | func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
59 | return cdc.MustMarshalJSON(types.DefaultGenesis())
60 | }
61 |
62 | // ValidateGenesis used to validate the GenesisState, given in its json.RawMessage form
63 | func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error {
64 | var genState types.GenesisState
65 | if err := cdc.UnmarshalJSON(bz, &genState); err != nil {
66 | return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
67 | }
68 | return genState.Validate()
69 | }
70 |
71 | // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module
72 | func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
73 | if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
74 | panic(err)
75 | }
76 | }
77 |
78 | // ----------------------------------------------------------------------------
79 | // AppModule
80 | // ----------------------------------------------------------------------------
81 |
82 | // AppModule implements the AppModule interface that defines the inter-dependent methods that modules need to implement
83 | type AppModule struct {
84 | AppModuleBasic
85 | keeper keeper.Keeper
86 | bk types.BankKeeper
87 | sk types.StakingKeeper
88 | ak types.AccountKeeper
89 | registry cdctypes.InterfaceRegistry
90 | }
91 |
92 | func NewAppModule(
93 | cdc codec.Codec,
94 | keeper keeper.Keeper,
95 | bk types.BankKeeper,
96 | sk types.StakingKeeper,
97 | ak types.AccountKeeper,
98 | registry cdctypes.InterfaceRegistry,
99 | ) AppModule {
100 | return AppModule{
101 | AppModuleBasic: NewAppModuleBasic(cdc),
102 | keeper: keeper,
103 | bk: bk,
104 | sk: sk,
105 | ak: ak,
106 | registry: registry,
107 | }
108 | }
109 |
110 | // RegisterServices registers a gRPC query service to respond to the module-specific gRPC queries
111 | func (am AppModule) RegisterServices(cfg module.Configurator) {
112 | types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
113 | types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
114 | }
115 |
116 | // RegisterInvariants registers the invariants of the module. If an invariant deviates from its predicted value, the InvariantRegistry triggers appropriate logic (most often the chain will be halted)
117 | func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
118 |
119 | // InitGenesis performs the module's genesis initialization. It returns no validator updates.
120 | func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) {
121 | var genState types.GenesisState
122 | // Initialize global index to index in genesis state
123 | cdc.MustUnmarshalJSON(gs, &genState)
124 |
125 | am.keeper.InitGenesis(ctx, genState)
126 |
127 | // To create module account
128 | am.ak.GetModuleAccount(ctx, am.Name())
129 | }
130 |
131 | // ExportGenesis returns the module's exported genesis state as raw JSON bytes.
132 | func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
133 | genState := am.keeper.ExportGenesis(ctx)
134 | return cdc.MustMarshalJSON(genState)
135 | }
136 |
137 | // ConsensusVersion is a sequence number for state-breaking change of the module. It should be incremented on each consensus-breaking change introduced by the module. To avoid wrong/empty versions, the initial version should be set to 1
138 | func (AppModule) ConsensusVersion() uint64 { return 1 }
139 |
140 | // IsOnePerModuleType implements the depinject.OnePerModuleType interface.
141 | func (am AppModule) IsOnePerModuleType() {}
142 |
143 | // IsAppModule implements the appmodule.AppModule interface.
144 | func (am AppModule) IsAppModule() {}
145 |
--------------------------------------------------------------------------------
/x/poa/module_simulation.go:
--------------------------------------------------------------------------------
1 | package poa
2 |
3 | import (
4 | "math/rand"
5 |
6 | "github.com/cosmos/cosmos-sdk/baseapp"
7 | "github.com/cosmos/cosmos-sdk/types/module"
8 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
9 |
10 | "github.com/cosmos/cosmos-sdk/x/simulation"
11 |
12 | "github.com/xrplevm/node/v8/testutil/sample"
13 | poasimulation "github.com/xrplevm/node/v8/x/poa/simulation"
14 | "github.com/xrplevm/node/v8/x/poa/types"
15 | )
16 |
17 | // avoid unused import issue
18 | var (
19 | _ = sample.AccAddress
20 | _ = simulation.MsgEntryKind
21 | _ = baseapp.Paramspace
22 | _ = rand.Rand{}
23 | )
24 |
25 | const (
26 | // this line is used by starport scaffolding # simapp/module/const
27 | )
28 |
29 | // GenerateGenesisState creates a randomized GenState of the module
30 | func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
31 | accs := make([]string, len(simState.Accounts))
32 | for i, acc := range simState.Accounts {
33 | accs[i] = acc.Address.String()
34 | }
35 | poaGenesis := types.GenesisState{
36 | Params: types.DefaultParams(),
37 | // this line is used by starport scaffolding # simapp/module/genesisState
38 | }
39 | simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(&poaGenesis)
40 | }
41 |
42 | // ProposalMsgs returns msgs used for governance proposals for simulations.
43 | func (am AppModule) ProposalMsgs(_ module.SimulationState) []simtypes.WeightedProposalMsg {
44 | return poasimulation.ProposalMsgs()
45 | }
46 |
47 | // RegisterStoreDecoder registers a decoder
48 | func (am AppModule) RegisterStoreDecoder(_ simtypes.StoreDecoderRegistry) {}
49 |
50 | // WeightedOperations returns the all the gov module operations with their respective weights.
51 | func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation {
52 | operations := make([]simtypes.WeightedOperation, 0)
53 | // this line is used by starport scaffolding # simapp/module/operation
54 |
55 | return operations
56 | }
57 |
--------------------------------------------------------------------------------
/x/poa/simulation/proposals.go:
--------------------------------------------------------------------------------
1 | package simulation
2 |
3 | import (
4 | "math/rand"
5 |
6 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/cosmos/cosmos-sdk/types/address"
9 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
10 | "github.com/cosmos/cosmos-sdk/x/simulation"
11 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
12 | "github.com/xrplevm/node/v8/x/poa/types"
13 | )
14 |
15 | const (
16 | //nolint:gosec
17 | OpWeightMsgAddValidator = "op_weight_msg_add_validator"
18 | DefaultWeightMsgAddValidator int = 100
19 |
20 | //nolint:gosec
21 | OpWeightMsgRemoveValidator = "op_weight_msg_remove_validator"
22 | DefaultWeightMsgRemoveValidator int = 5
23 | )
24 |
25 | func ProposalMsgs() []simtypes.WeightedProposalMsg {
26 | return []simtypes.WeightedProposalMsg{
27 | simulation.NewWeightedProposalMsg(
28 | OpWeightMsgAddValidator,
29 | DefaultWeightMsgAddValidator,
30 | simulateMsgAddValidator,
31 | ),
32 | simulation.NewWeightedProposalMsg(
33 | OpWeightMsgRemoveValidator,
34 | DefaultWeightMsgRemoveValidator,
35 | simulateMsgRemoveValidator,
36 | ),
37 | }
38 | }
39 |
40 | // MsgAddValidator simulation functions
41 |
42 | // randomDescription generates a random description for a validator
43 | func randomDescription(r *rand.Rand) stakingtypes.Description {
44 | return stakingtypes.Description{
45 | Moniker: simtypes.RandStringOfLength(r, 10),
46 | Identity: simtypes.RandStringOfLength(r, 10),
47 | Website: simtypes.RandStringOfLength(r, 10),
48 | SecurityContact: simtypes.RandStringOfLength(r, 10),
49 | Details: simtypes.RandStringOfLength(r, 10),
50 | }
51 | }
52 |
53 | // randomMsgAddValidator generates a random MsgAddValidator message
54 | func randomMsgAddValidator(r *rand.Rand, authAddr sdk.AccAddress) (*types.MsgAddValidator, error) {
55 | validatorAccs := simtypes.RandomAccounts(r, 1)
56 |
57 | validatorAcc := validatorAccs[0]
58 | pubkey, err := codectypes.NewAnyWithValue(validatorAcc.PubKey)
59 | if err != nil {
60 | return nil, err
61 | }
62 |
63 | return &types.MsgAddValidator{
64 | Authority: authAddr.String(),
65 | Description: randomDescription(r),
66 | ValidatorAddress: validatorAcc.Address.String(),
67 | Pubkey: pubkey,
68 | }, nil
69 | }
70 |
71 | // SimulateMsgAddValidator simulates the MsgAddValidator message
72 | func simulateMsgAddValidator(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) sdk.Msg {
73 | var authAddr sdk.AccAddress = address.Module("gov")
74 |
75 | randMsg, err := randomMsgAddValidator(r, authAddr)
76 | if err != nil {
77 | panic(err)
78 | }
79 | return randMsg
80 | }
81 |
82 | // MsgRemoveValidator simulation functions
83 |
84 | // randomMsgRemoveValidator generates a random MsgRemoveValidator message
85 | func randomMsgRemoveValidator(r *rand.Rand, authAddr sdk.AccAddress, accs []simtypes.Account) *types.MsgRemoveValidator {
86 | rmValidator, _ := simtypes.RandomAcc(r, accs)
87 |
88 | return &types.MsgRemoveValidator{
89 | Authority: authAddr.String(),
90 | ValidatorAddress: rmValidator.Address.String(),
91 | }
92 | }
93 |
94 | // SimulateMsgRemoveValidator simulates the MsgRemoveValidator message
95 | func simulateMsgRemoveValidator(r *rand.Rand, _ sdk.Context, accs []simtypes.Account) sdk.Msg {
96 | var authAddr sdk.AccAddress = address.Module("gov")
97 |
98 | randMsg := randomMsgRemoveValidator(r, authAddr, accs)
99 | return randMsg
100 | }
101 |
--------------------------------------------------------------------------------
/x/poa/simulation/proposals_test.go:
--------------------------------------------------------------------------------
1 | package simulation
2 |
3 | import (
4 | "fmt"
5 | "math/rand"
6 | "testing"
7 |
8 | tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
9 | "github.com/cosmos/cosmos-sdk/types/address"
10 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
11 | "github.com/stretchr/testify/require"
12 | "github.com/xrplevm/node/v8/x/poa/types"
13 |
14 | sdk "github.com/cosmos/cosmos-sdk/types"
15 | )
16 |
17 | func TestProposalMsgs(t *testing.T) {
18 | s := rand.NewSource(1)
19 | //nolint:gosec
20 | r := rand.New(s)
21 |
22 | ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil)
23 | accounts := simtypes.RandomAccounts(r, 3)
24 |
25 | // execute ProposalMsgs function
26 | weightedProposalMsgs := ProposalMsgs()
27 | require.Equal(t, 2, len(weightedProposalMsgs))
28 |
29 | w0 := weightedProposalMsgs[0]
30 |
31 | // tests w0 interface:
32 | require.Equal(t, OpWeightMsgAddValidator, w0.AppParamsKey())
33 | require.Equal(t, DefaultWeightMsgAddValidator, w0.DefaultWeight())
34 |
35 | msg := w0.MsgSimulatorFn()(r, ctx, accounts)
36 | msgAddValidator, ok := msg.(*types.MsgAddValidator)
37 | require.True(t, ok)
38 |
39 | fmt.Println(msgAddValidator)
40 | require.Equal(t, sdk.AccAddress(address.Module("gov")).String(), msgAddValidator.Authority)
41 |
42 | w1 := weightedProposalMsgs[1]
43 |
44 | // tests w0 interface:
45 | require.Equal(t, OpWeightMsgRemoveValidator, w1.AppParamsKey())
46 | require.Equal(t, DefaultWeightMsgRemoveValidator, w1.DefaultWeight())
47 |
48 | msg = w1.MsgSimulatorFn()(r, ctx, accounts)
49 | msgRemoveValidator, ok := msg.(*types.MsgRemoveValidator)
50 | require.True(t, ok)
51 |
52 | fmt.Println(msgRemoveValidator)
53 | require.Equal(t, sdk.AccAddress(address.Module("gov")).String(), msgRemoveValidator.Authority)
54 | }
55 |
--------------------------------------------------------------------------------
/x/poa/testutil/expected_msg_server.go:
--------------------------------------------------------------------------------
1 | package testutil
2 |
3 | import (
4 | context "context"
5 |
6 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
7 | )
8 |
9 | // MsgServer is the server API for Msg service.
10 | type StakingMsgServer interface {
11 | // CreateValidator defines a method for creating a new validator.
12 | CreateValidator(context.Context, *stakingtypes.MsgCreateValidator) (*stakingtypes.MsgCreateValidatorResponse, error)
13 | // EditValidator defines a method for editing an existing validator.
14 | EditValidator(context.Context, *stakingtypes.MsgEditValidator) (*stakingtypes.MsgEditValidatorResponse, error)
15 | // Delegate defines a method for performing a delegation of coins
16 | // from a delegator to a validator.
17 | Delegate(context.Context, *stakingtypes.MsgDelegate) (*stakingtypes.MsgDelegateResponse, error)
18 | // BeginRedelegate defines a method for performing a redelegation
19 | // of coins from a delegator and source validator to a destination validator.
20 | BeginRedelegate(context.Context, *stakingtypes.MsgBeginRedelegate) (*stakingtypes.MsgBeginRedelegateResponse, error)
21 | // Undelegate defines a method for performing an undelegation from a
22 | // delegate and a validator.
23 | Undelegate(context.Context, *stakingtypes.MsgUndelegate) (*stakingtypes.MsgUndelegateResponse, error)
24 | // CancelUnbondingDelegation defines a method for performing canceling the unbonding delegation
25 | // and delegate back to previous validator.
26 | //
27 | // Since: cosmos-sdk 0.46
28 | CancelUnbondingDelegation(context.Context, *stakingtypes.MsgCancelUnbondingDelegation) (*stakingtypes.MsgCancelUnbondingDelegationResponse, error)
29 | // UpdateParams defines an operation for updating the x/staking module
30 | // parameters.
31 | // Since: cosmos-sdk 0.47
32 | UpdateParams(context.Context, *stakingtypes.MsgUpdateParams) (*stakingtypes.MsgUpdateParamsResponse, error)
33 | }
34 |
--------------------------------------------------------------------------------
/x/poa/testutil/keys.go:
--------------------------------------------------------------------------------
1 | package testutil
2 |
3 | import (
4 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
5 | )
6 |
7 | type PubKey interface {
8 | cryptotypes.PubKey
9 | }
10 |
--------------------------------------------------------------------------------
/x/poa/testutil/keys_mock.go:
--------------------------------------------------------------------------------
1 | // Code generated by MockGen. DO NOT EDIT.
2 | // Source: x/poa/testutil/keys.go
3 |
4 | // Package testutil is a generated GoMock package.
5 | package testutil
6 |
7 | import (
8 | reflect "reflect"
9 |
10 | types "github.com/cosmos/cosmos-sdk/crypto/types"
11 | gomock "github.com/golang/mock/gomock"
12 | )
13 |
14 | // MockPubKey is a mock of PubKey interface.
15 | type MockPubKey struct {
16 | ctrl *gomock.Controller
17 | recorder *MockPubKeyMockRecorder
18 | }
19 |
20 | // MockPubKeyMockRecorder is the mock recorder for MockPubKey.
21 | type MockPubKeyMockRecorder struct {
22 | mock *MockPubKey
23 | }
24 |
25 | // NewMockPubKey creates a new mock instance.
26 | func NewMockPubKey(ctrl *gomock.Controller) *MockPubKey {
27 | mock := &MockPubKey{ctrl: ctrl}
28 | mock.recorder = &MockPubKeyMockRecorder{mock}
29 | return mock
30 | }
31 |
32 | // EXPECT returns an object that allows the caller to indicate expected use.
33 | func (m *MockPubKey) EXPECT() *MockPubKeyMockRecorder {
34 | return m.recorder
35 | }
36 |
37 | // Address mocks base method.
38 | func (m *MockPubKey) Address() types.Address {
39 | m.ctrl.T.Helper()
40 | ret := m.ctrl.Call(m, "Address")
41 | ret0, _ := ret[0].(types.Address)
42 | return ret0
43 | }
44 |
45 | // Address indicates an expected call of Address.
46 | func (mr *MockPubKeyMockRecorder) Address() *gomock.Call {
47 | mr.mock.ctrl.T.Helper()
48 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Address", reflect.TypeOf((*MockPubKey)(nil).Address))
49 | }
50 |
51 | // Bytes mocks base method.
52 | func (m *MockPubKey) Bytes() []byte {
53 | m.ctrl.T.Helper()
54 | ret := m.ctrl.Call(m, "Bytes")
55 | ret0, _ := ret[0].([]byte)
56 | return ret0
57 | }
58 |
59 | // Bytes indicates an expected call of Bytes.
60 | func (mr *MockPubKeyMockRecorder) Bytes() *gomock.Call {
61 | mr.mock.ctrl.T.Helper()
62 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bytes", reflect.TypeOf((*MockPubKey)(nil).Bytes))
63 | }
64 |
65 | // Equals mocks base method.
66 | func (m *MockPubKey) Equals(arg0 types.PubKey) bool {
67 | m.ctrl.T.Helper()
68 | ret := m.ctrl.Call(m, "Equals", arg0)
69 | ret0, _ := ret[0].(bool)
70 | return ret0
71 | }
72 |
73 | // Equals indicates an expected call of Equals.
74 | func (mr *MockPubKeyMockRecorder) Equals(arg0 interface{}) *gomock.Call {
75 | mr.mock.ctrl.T.Helper()
76 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Equals", reflect.TypeOf((*MockPubKey)(nil).Equals), arg0)
77 | }
78 |
79 | // ProtoMessage mocks base method.
80 | func (m *MockPubKey) ProtoMessage() {
81 | m.ctrl.T.Helper()
82 | m.ctrl.Call(m, "ProtoMessage")
83 | }
84 |
85 | // ProtoMessage indicates an expected call of ProtoMessage.
86 | func (mr *MockPubKeyMockRecorder) ProtoMessage() *gomock.Call {
87 | mr.mock.ctrl.T.Helper()
88 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProtoMessage", reflect.TypeOf((*MockPubKey)(nil).ProtoMessage))
89 | }
90 |
91 | // Reset mocks base method.
92 | func (m *MockPubKey) Reset() {
93 | m.ctrl.T.Helper()
94 | m.ctrl.Call(m, "Reset")
95 | }
96 |
97 | // Reset indicates an expected call of Reset.
98 | func (mr *MockPubKeyMockRecorder) Reset() *gomock.Call {
99 | mr.mock.ctrl.T.Helper()
100 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockPubKey)(nil).Reset))
101 | }
102 |
103 | // String mocks base method.
104 | func (m *MockPubKey) String() string {
105 | m.ctrl.T.Helper()
106 | ret := m.ctrl.Call(m, "String")
107 | ret0, _ := ret[0].(string)
108 | return ret0
109 | }
110 |
111 | // String indicates an expected call of String.
112 | func (mr *MockPubKeyMockRecorder) String() *gomock.Call {
113 | mr.mock.ctrl.T.Helper()
114 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "String", reflect.TypeOf((*MockPubKey)(nil).String))
115 | }
116 |
117 | // Type mocks base method.
118 | func (m *MockPubKey) Type() string {
119 | m.ctrl.T.Helper()
120 | ret := m.ctrl.Call(m, "Type")
121 | ret0, _ := ret[0].(string)
122 | return ret0
123 | }
124 |
125 | // Type indicates an expected call of Type.
126 | func (mr *MockPubKeyMockRecorder) Type() *gomock.Call {
127 | mr.mock.ctrl.T.Helper()
128 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*MockPubKey)(nil).Type))
129 | }
130 |
131 | // VerifySignature mocks base method.
132 | func (m *MockPubKey) VerifySignature(msg, sig []byte) bool {
133 | m.ctrl.T.Helper()
134 | ret := m.ctrl.Call(m, "VerifySignature", msg, sig)
135 | ret0, _ := ret[0].(bool)
136 | return ret0
137 | }
138 |
139 | // VerifySignature indicates an expected call of VerifySignature.
140 | func (mr *MockPubKeyMockRecorder) VerifySignature(msg, sig interface{}) *gomock.Call {
141 | mr.mock.ctrl.T.Helper()
142 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifySignature", reflect.TypeOf((*MockPubKey)(nil).VerifySignature), msg, sig)
143 | }
144 |
--------------------------------------------------------------------------------
/x/poa/testutil/staking_hooks.go:
--------------------------------------------------------------------------------
1 | package testutil
2 |
3 | import (
4 | "context"
5 |
6 | "cosmossdk.io/math"
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | )
9 |
10 | type StakingHooks interface {
11 | AfterValidatorCreated(ctx context.Context, valAddr sdk.ValAddress) error // Must be called when a validator is created
12 | BeforeValidatorModified(ctx context.Context, valAddr sdk.ValAddress) error // Must be called when a validator's state changes
13 | AfterValidatorRemoved(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is deleted
14 |
15 | AfterValidatorBonded(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is bonded
16 | AfterValidatorBeginUnbonding(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator begins unbonding
17 |
18 | BeforeDelegationCreated(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is created
19 | BeforeDelegationSharesModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation's shares are modified
20 | BeforeDelegationRemoved(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is removed
21 | AfterDelegationModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error
22 | BeforeValidatorSlashed(ctx context.Context, valAddr sdk.ValAddress, fraction math.LegacyDec) error
23 | AfterUnbondingInitiated(ctx context.Context, id uint64) error
24 | }
25 |
--------------------------------------------------------------------------------
/x/poa/testutil/tx.go:
--------------------------------------------------------------------------------
1 | package testutil
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 | protov2 "google.golang.org/protobuf/proto"
6 | )
7 |
8 | type Tx interface {
9 | sdk.HasMsgs
10 |
11 | // GetMsgsV2 gets the transaction's messages as google.golang.org/protobuf/proto.Message's.
12 | GetMsgsV2() ([]protov2.Message, error)
13 | }
14 |
--------------------------------------------------------------------------------
/x/poa/testutil/tx_mock.go:
--------------------------------------------------------------------------------
1 | // Code generated by MockGen. DO NOT EDIT.
2 | // Source: x/poa/testutil/tx.go
3 |
4 | // Package testutil is a generated GoMock package.
5 | package testutil
6 |
7 | import (
8 | reflect "reflect"
9 |
10 | types "github.com/cosmos/cosmos-sdk/types"
11 | gomock "github.com/golang/mock/gomock"
12 | proto "google.golang.org/protobuf/proto"
13 | )
14 |
15 | // MockTx is a mock of Tx interface.
16 | type MockTx struct {
17 | ctrl *gomock.Controller
18 | recorder *MockTxMockRecorder
19 | }
20 |
21 | // MockTxMockRecorder is the mock recorder for MockTx.
22 | type MockTxMockRecorder struct {
23 | mock *MockTx
24 | }
25 |
26 | // NewMockTx creates a new mock instance.
27 | func NewMockTx(ctrl *gomock.Controller) *MockTx {
28 | mock := &MockTx{ctrl: ctrl}
29 | mock.recorder = &MockTxMockRecorder{mock}
30 | return mock
31 | }
32 |
33 | // EXPECT returns an object that allows the caller to indicate expected use.
34 | func (m *MockTx) EXPECT() *MockTxMockRecorder {
35 | return m.recorder
36 | }
37 |
38 | // GetMsgs mocks base method.
39 | func (m *MockTx) GetMsgs() []types.Msg {
40 | m.ctrl.T.Helper()
41 | ret := m.ctrl.Call(m, "GetMsgs")
42 | ret0, _ := ret[0].([]types.Msg)
43 | return ret0
44 | }
45 |
46 | // GetMsgs indicates an expected call of GetMsgs.
47 | func (mr *MockTxMockRecorder) GetMsgs() *gomock.Call {
48 | mr.mock.ctrl.T.Helper()
49 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMsgs", reflect.TypeOf((*MockTx)(nil).GetMsgs))
50 | }
51 |
52 | // GetMsgsV2 mocks base method.
53 | func (m *MockTx) GetMsgsV2() ([]proto.Message, error) {
54 | m.ctrl.T.Helper()
55 | ret := m.ctrl.Call(m, "GetMsgsV2")
56 | ret0, _ := ret[0].([]proto.Message)
57 | ret1, _ := ret[1].(error)
58 | return ret0, ret1
59 | }
60 |
61 | // GetMsgsV2 indicates an expected call of GetMsgsV2.
62 | func (mr *MockTxMockRecorder) GetMsgsV2() *gomock.Call {
63 | mr.mock.ctrl.T.Helper()
64 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMsgsV2", reflect.TypeOf((*MockTx)(nil).GetMsgsV2))
65 | }
66 |
--------------------------------------------------------------------------------
/x/poa/types/codec.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "github.com/cosmos/cosmos-sdk/codec"
5 | cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | "github.com/cosmos/cosmos-sdk/types/msgservice"
8 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
9 | )
10 |
11 | func RegisterCodec(cdc *codec.LegacyAmino) {
12 | cdc.RegisterConcrete(&MsgAddValidator{}, "poa/AddValidator", nil)
13 | cdc.RegisterConcrete(&MsgRemoveValidator{}, "poa/RemoveValidator", nil)
14 | // this line is used by starport scaffolding # 2
15 | }
16 |
17 | func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
18 | registry.RegisterImplementations((*sdk.Msg)(nil),
19 | &MsgAddValidator{},
20 | )
21 | registry.RegisterImplementations((*sdk.Msg)(nil),
22 | &MsgRemoveValidator{},
23 | )
24 | registry.RegisterImplementations(
25 | (*govtypes.Content)(nil),
26 | )
27 | // this line is used by starport scaffolding # 3
28 |
29 | msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
30 | }
31 |
32 | var (
33 | Amino = codec.NewLegacyAmino()
34 | ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry())
35 | )
36 |
--------------------------------------------------------------------------------
/x/poa/types/errors.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | // DONTCOVER
4 |
5 | import (
6 | sdkerrors "cosmossdk.io/errors"
7 | )
8 |
9 | // x/poa module sentinel errors
10 | var (
11 | ErrAddressHasBankTokens = sdkerrors.Register(ModuleName, 1, "address already has bank tokens")
12 | ErrAddressHasBondedTokens = sdkerrors.Register(ModuleName, 2, "address already has bonded tokens")
13 | ErrAddressHasUnbondingTokens = sdkerrors.Register(ModuleName, 3, "address already has unbonding tokens")
14 | ErrAddressHasDelegatedTokens = sdkerrors.Register(ModuleName, 4, "address already has delegated tokens")
15 | ErrInvalidValidatorStatus = sdkerrors.Register(ModuleName, 5, "invalid validator status")
16 | ErrAddressIsNotAValidator = sdkerrors.Register(ModuleName, 6, "address is not a validator")
17 | ErrMaxValidatorsReached = sdkerrors.Register(ModuleName, 7, "maximum number of validators reached")
18 | )
19 |
--------------------------------------------------------------------------------
/x/poa/types/events.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | const (
4 | EventTypeAddValidator = "add_validator"
5 | EventTypeRemoveValidator = "remove_validator"
6 | AttributeValidator = "address"
7 | AttributeHeight = "height"
8 | AttributeStakingTokens = "staking_tokens"
9 | AttributeBankTokens = "bank_tokens"
10 | )
11 |
--------------------------------------------------------------------------------
/x/poa/types/expected_keepers.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "context"
5 |
6 | "cosmossdk.io/math"
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
9 | slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
10 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
11 | )
12 |
13 | // AccountKeeper defines the expected account keeper used for simulations (noalias)
14 | type AccountKeeper interface {
15 | GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI
16 | GetModuleAccount(ctx context.Context, moduleName string) sdk.ModuleAccountI
17 | // Methods imported from account should be defined here
18 | }
19 |
20 | // BankKeeper defines the expected interface needed to retrieve account balances.
21 | type BankKeeper interface {
22 | SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins
23 | GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin
24 | MintCoins(ctx context.Context, moduleName string, amt sdk.Coins) error
25 | BurnCoins(ctx context.Context, moduleName string, amt sdk.Coins) error
26 | SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
27 | SendCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
28 | IterateAllBalances(ctx context.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool))
29 | }
30 |
31 | // StakingKeeper defines the expected interface needed to retrieve account balances.
32 | type StakingKeeper interface {
33 | GetParams(ctx context.Context) (stakingtypes.Params, error)
34 | GetValidator(ctx context.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, err error)
35 | GetValidators(ctx context.Context, maxRetrieve uint32) (validators []stakingtypes.Validator, err error)
36 | GetAllValidators(ctx context.Context) (validators []stakingtypes.Validator, err error)
37 | GetAllDelegations(ctx context.Context) (delegations []stakingtypes.Delegation, err error)
38 | GetAllDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress) ([]stakingtypes.Delegation, error)
39 | GetUnbondingDelegationsFromValidator(ctx context.Context, validator sdk.ValAddress) ([]stakingtypes.UnbondingDelegation, error)
40 | SlashUnbondingDelegation(ctx context.Context, ubd stakingtypes.UnbondingDelegation, infractionHeight int64, slashFactor math.LegacyDec) (totalSlashAmount math.Int, err error)
41 | RemoveDelegation(ctx context.Context, delegation stakingtypes.Delegation) error
42 | RemoveValidatorTokensAndShares(ctx context.Context, validator stakingtypes.Validator, sharesToRemove math.LegacyDec) (stakingtypes.Validator, math.Int, error)
43 | RemoveValidatorTokens(ctx context.Context, validator stakingtypes.Validator, tokensToRemove math.Int) (stakingtypes.Validator, error)
44 | BondDenom(ctx context.Context) (string, error)
45 | Unbond(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares math.LegacyDec) (amount math.Int, err error)
46 | Hooks() stakingtypes.StakingHooks
47 | }
48 |
49 | type SlashingKeeper interface {
50 | GetParams(ctx context.Context) (params slashingtypes.Params, err error)
51 | }
52 |
53 | type GovKeeper interface {
54 | SubmitProposal(ctx context.Context, messages []sdk.Msg, metadata string) (v1.Proposal, error)
55 | }
56 |
--------------------------------------------------------------------------------
/x/poa/types/genesis.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | // this line is used by starport scaffolding # genesis/types/import
5 | )
6 |
7 | // DefaultIndex is the default global index
8 | const DefaultIndex uint64 = 1
9 |
10 | // DefaultGenesis returns the default genesis state
11 | func DefaultGenesis() *GenesisState {
12 | return &GenesisState{
13 | // this line is used by starport scaffolding # genesis/types/default
14 | Params: DefaultParams(),
15 | }
16 | }
17 |
18 | // Validate performs basic genesis state validation returning an error upon any
19 | // failure.
20 | func (gs GenesisState) Validate() error {
21 | // this line is used by starport scaffolding # genesis/types/validate
22 |
23 | return gs.Params.Validate()
24 | }
25 |
--------------------------------------------------------------------------------
/x/poa/types/keys.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | const (
4 | // ModuleName defines the module name
5 | ModuleName = "poa"
6 |
7 | // StoreKey defines the primary module store key
8 | StoreKey = ModuleName
9 |
10 | // RouterKey defines the module's message routing key
11 | RouterKey = ModuleName
12 |
13 | // MemStoreKey defines the in-memory store key
14 | MemStoreKey = "mem_" + ModuleName
15 | )
16 |
17 | func KeyPrefix(p string) []byte {
18 | return []byte(p)
19 | }
20 |
--------------------------------------------------------------------------------
/x/poa/types/message_add_validator.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
5 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
8 | )
9 |
10 | var (
11 | _ sdk.Msg = &MsgAddValidator{}
12 | _ codectypes.UnpackInterfacesMessage = (*MsgAddValidator)(nil)
13 | )
14 |
15 | func NewMsgAddValidator(authority string, address string, pubKey cryptotypes.PubKey, description stakingtypes.Description) (*MsgAddValidator, error) {
16 | var pkAny *codectypes.Any
17 | if pubKey != nil {
18 | var err error
19 | if pkAny, err = codectypes.NewAnyWithValue(pubKey); err != nil {
20 | return nil, err
21 | }
22 | }
23 | return &MsgAddValidator{
24 | Authority: authority,
25 | ValidatorAddress: address,
26 | Pubkey: pkAny,
27 | Description: description,
28 | }, nil
29 | }
30 |
31 | // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
32 | func (msg *MsgAddValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
33 | var pubKey cryptotypes.PubKey
34 | return unpacker.UnpackAny(msg.Pubkey, &pubKey)
35 | }
36 |
--------------------------------------------------------------------------------
/x/poa/types/message_remove_validator.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 | )
6 |
7 | var _ sdk.Msg = &MsgRemoveValidator{}
8 |
9 | func NewMsgRemoveValidator(authority string, address string) *MsgRemoveValidator {
10 | return &MsgRemoveValidator{
11 | Authority: authority,
12 | ValidatorAddress: address,
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/x/poa/types/params.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
5 | )
6 |
7 | var _ paramtypes.ParamSet = (*Params)(nil)
8 |
9 | // ParamKeyTable the param key table for launch module
10 | func ParamKeyTable() paramtypes.KeyTable {
11 | return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
12 | }
13 |
14 | // NewParams creates a new Params instance
15 | func NewParams() Params {
16 | return Params{}
17 | }
18 |
19 | // DefaultParams returns a default set of parameters
20 | func DefaultParams() Params {
21 | return NewParams()
22 | }
23 |
24 | // ParamSetPairs get the params.ParamSet
25 | func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
26 | return paramtypes.ParamSetPairs{}
27 | }
28 |
29 | // Validate validates the set of params
30 | func (p *Params) Validate() error {
31 | return nil
32 | }
33 |
--------------------------------------------------------------------------------
/x/poa/types/types.go:
--------------------------------------------------------------------------------
1 | package types
2 |
--------------------------------------------------------------------------------