diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..5218533
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,6 @@
+*/node_modules
+*/target/*
+.DS_Store
+.dockerignore
+.git
+.gitignore
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..7cc88f0
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.sol linguist-language=Solidity
\ No newline at end of file
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..bd70d3a
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,6 @@
+# CODEOWNERS: https://help.github.com/articles/about-codeowners/
+
+module/ @jackzampolin @mvid @levicook
+orchestrator/ @zmanian @levicook @hannydevelop
+solidity/ @zmanian @jackzampolin @jtremback
+tests/ @mvid @levicook @jackzampolin
diff --git a/.github/workflows/automated-release.yml b/.github/workflows/automated-release.yml
new file mode 100644
index 0000000..ac4a2bc
--- /dev/null
+++ b/.github/workflows/automated-release.yml
@@ -0,0 +1,90 @@
+on:
+ push:
+ # Sequence of patterns matched against refs/tags
+ tags:
+ - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10
+
+name: Automated Release
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ release:
+ name: build-release-assets
+ runs-on: ubuntu-latest
+ steps:
+ # Setup Golang Environemnt
+ - name: setup-go
+ uses: actions/setup-go@v2
+ with:
+ go-version: ^1.16
+ # Setup Rust Environment
+ - name: setup-rust
+ uses: actions-rs/toolchain@v1
+ with:
+ profile: minimal
+ toolchain: stable
+ # Setup Node Environment
+ - name: setup-node
+ uses: actions/setup-node@v2
+ with:
+ node-version: '16'
+ # Checkout repository code
+ - name: checkout-code
+ uses: actions/checkout@v2
+ # Golang Cache
+ - name: go-cache
+ uses: actions/cache@v2
+ with:
+ path: |
+ ~/.cache/go-build
+ ~/go/pkg/mod
+ key: ${{ runner.os }}-go-${{ hashFiles('module/go.sum') }}
+ # Rust Cache
+ - name: rust-cache
+ uses: actions/cache@v2
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ orchestrator/target/
+ key: ${{ runner.os }}-cargo-${{ hashFiles('orchestrator/Cargo.lock') }}
+ # Node Cache
+ - name: node-cache
+ uses: actions/cache@v2
+ with:
+ path: ~/.npm
+ key: ${{ runner.os }}-node-${{ hashFiles('solidity/package-lock.json') }}
+ # Build Go Artifacts
+ - name: build-go
+ run: cd module && make build
+ # Build Node and Solidity Artifacts
+ - name: build-node-solidity
+ run: cd solidity && npm ci && npm run typechain && npm run compile-deployer
+ # Build Rust Artifacts
+ - name: build-rust
+ run: cd orchestrator && cargo install cross && cross build --target x86_64-unknown-linux-musl --release --all
+ # Create Release and Upload artifacts
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ if: startsWith(github.ref, 'refs/tags/')
+ with:
+ files: |
+ orchestrator/target/x86_64-unknown-linux-musl/release/client
+ orchestrator/target/x86_64-unknown-linux-musl/release/gorc
+ orchestrator/target/x86_64-unknown-linux-musl/release/orchestrator
+ orchestrator/target/x86_64-unknown-linux-musl/release/register-delegate-keys
+ orchestrator/target/x86_64-unknown-linux-musl/release/relayer
+ orchestrator/target/x86_64-unknown-linux-musl/release/test-runner
+ module/build/gravity
+ solidity/artifacts/contracts/Gravity.sol/Gravity.json
+ solidity/artifacts/contracts/TestERC20A.sol/TestERC20A.json
+ solidity/artifacts/contracts/TestERC20B.sol/TestERC20B.json
+ solidity/artifacts/contracts/TestERC20C.sol/TestERC20C.json
+ solidity/contract-deployer
+ LICENSE
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
new file mode 100644
index 0000000..aecd684
--- /dev/null
+++ b/.github/workflows/go.yml
@@ -0,0 +1,30 @@
+name: Go tests
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+jobs:
+ go-test:
+ permissions:
+ contents: read
+ packages: write
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: ^1.16
+ - name: Checkout Branch
+ uses: actions/checkout@v2
+ - name: Create Go cache
+ uses: actions/cache@v2
+ with:
+ path: |
+ ~/.cache/go-build
+ ~/go/pkg/mod
+ key: ${{ runner.os }}-go-${{ hashFiles('module/go.sum') }}
+ - name: Run Go tests
+ run: cd module && make test
\ No newline at end of file
diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml
new file mode 100644
index 0000000..ee17673
--- /dev/null
+++ b/.github/workflows/integration-tests.yml
@@ -0,0 +1,287 @@
+name: Integration tests
+
+on:
+ push:
+ branches:
+ - main
+ tags:
+ - 'v*.*.*'
+
+ pull_request:
+
+env:
+ CARGO_TERM_COLOR: always
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+ rust-build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout branch
+ uses: actions/checkout@v2
+ - name: Set up Docker Buildx
+ id: buildx
+ uses: docker/setup-buildx-action@v1
+ - name: Cache Docker layers
+ uses: actions/cache@v2
+ id: docker-cache
+ with:
+ path: /tmp/.buildx-cache
+ # Key is named differently to avoid collision
+ key: ${{ runner.os }}-multi-buildx-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-multi-buildx
+ - name: Container service login
+ uses: docker/login-action@v1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - name: Docker metadata
+ id: meta
+ uses: docker/metadata-action@v3
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-orchestrator
+ tags: |
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern=v{{version}}
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v2
+ with:
+ context: ./orchestrator
+ builder: ${{ steps.buildx.outputs.name }}
+ file: orchestrator/Dockerfile
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=local,src=/tmp/.buildx-cache
+ cache-to: type=local,mode=max,dest=/tmp/.buildx-cache-new
+ - name: Move Docker cache
+ run: |
+ rm -rf /tmp/.buildx-cache
+ mv /tmp/.buildx-cache-new /tmp/.buildx-cache
+
+ test-runner-build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout branch
+ uses: actions/checkout@v2
+ - name: Set up Docker Buildx
+ id: buildx
+ uses: docker/setup-buildx-action@v1
+ - name: Cache Docker layers
+ uses: actions/cache@v2
+ id: docker-cache
+ with:
+ path: /tmp/.buildx-cache
+ # Key is named differently to avoid collision
+ key: ${{ runner.os }}-multi-buildx-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-multi-buildx
+ - name: Container service login
+ uses: docker/login-action@v1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - name: Docker metadata
+ id: meta
+ uses: docker/metadata-action@v3
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-test-runner
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v2
+ with:
+ context: ./orchestrator
+ builder: ${{ steps.buildx.outputs.name }}
+ file: orchestrator/testnet.Dockerfile
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=local,src=/tmp/.buildx-cache
+ cache-to: type=local,mode=max,dest=/tmp/.buildx-cache-new
+ - name: Move Docker cache
+ run: |
+ rm -rf /tmp/.buildx-cache
+ mv /tmp/.buildx-cache-new /tmp/.buildx-cache
+
+ go-build:
+ permissions:
+ contents: read
+ packages: write
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout
+ uses: actions/checkout@v2
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v1
+ - name: Cache Docker layers
+ uses: actions/cache@v2
+ id: docker-cache
+ with:
+ path: /tmp/.buildx-cache
+ # Key is named differently to avoid collision
+ key: ${{ runner.os }}-multi-buildx-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-multi-buildx
+ - name: container-login
+ uses: docker/login-action@v1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - name: labels
+ id: meta
+ uses: docker/metadata-action@v3
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-gravity
+ tags: |
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern=v{{version}}
+ - name: build-and-push
+ uses: docker/build-push-action@v2
+ with:
+ context: ./module
+ file: module/Dockerfile
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ builder: ${{ steps.buildx.outputs.name }}
+ cache-from: type=local,src=/tmp/.buildx-cache
+ cache-to: type=local,mode=max,dest=/tmp/.buildx-cache-new
+ - name: Move Docker cache
+ run: |
+ rm -rf /tmp/.buildx-cache
+ mv /tmp/.buildx-cache-new /tmp/.buildx-cache
+
+ solidity-build:
+ permissions:
+ contents: read
+ packages: write
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout
+ uses: actions/checkout@v2
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v1
+ - name: Cache Docker layers
+ uses: actions/cache@v2
+ id: docker-cache
+ with:
+ path: /tmp/.buildx-cache
+ # Key is named differently to avoid collision
+ key: ${{ runner.os }}-multi-buildx-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-multi-buildx
+ - name: container-login
+ uses: docker/login-action@v1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - name: labels
+ id: meta
+ uses: docker/metadata-action@v3
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-solidity
+ tags: |
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern=v{{version}}
+ - name: build-and-push
+ uses: docker/build-push-action@v2
+ with:
+ context: ./solidity
+ file: solidity/Dockerfile
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ builder: ${{ steps.buildx.outputs.name }}
+ cache-from: type=local,src=/tmp/.buildx-cache
+ cache-to: type=local,mode=max,dest=/tmp/.buildx-cache-new
+ - name: Move Docker cache
+ run: |
+ rm -rf /tmp/.buildx-cache
+ mv /tmp/.buildx-cache-new /tmp/.buildx-cache
+
+ integration-tests:
+ runs-on: ubuntu-latest
+ needs: [ rust-build, go-build, test-runner-build, solidity-build ]
+ strategy:
+ fail-fast: false
+ matrix:
+ test_type: [
+ # working tests
+ "OrchestratorKeys",
+ "ArbitraryLogic",
+
+ # non-working tests
+# "ValidatorOut",
+# "BatchStress",
+# "ValsetStress",
+# "HappyPath",
+# "V2HappyPath",
+ ]
+ steps:
+ - name: Set up Go 1.16
+ uses: actions/setup-go@v2
+ with:
+ go-version: ^1.16
+ - name: checkout
+ uses: actions/checkout@v2
+ - name: go-cache
+ uses: actions/cache@v2
+ with:
+ path: |
+ ~/.cache/go-build
+ ~/go/pkg/mod
+ key: ${{ runner.os }}-go-${{ hashFiles('testnet/go.sum') }}
+ - name: container-login
+ uses: docker/login-action@v1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - name: docker gravity metadata
+ id: meta-gravity
+ uses: docker/metadata-action@v3
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-gravity
+ - name: docker orchestrator metadata
+ id: meta-orchestrator
+ uses: docker/metadata-action@v3
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-orchestrator
+ - name: docker test runner metadata
+ id: meta-test-runner
+ uses: docker/metadata-action@v3
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-test-runner
+ - name: docker contract deployer metadata
+ id: meta-solidity
+ uses: docker/metadata-action@v3
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-solidity
+ - name: pull gravity image
+ run: docker pull ${{ steps.meta-gravity.outputs.tags }}
+ - name: rename gravity image
+ run: docker tag ${{ steps.meta-gravity.outputs.tags }} gravity:prebuilt
+ - name: pull orchestrator image
+ run: docker pull ${{ steps.meta-orchestrator.outputs.tags }}
+ - name: rename orchestrator image
+ run: docker tag ${{ steps.meta-gravity.outputs.tags }} orchestrator:prebuilt
+ - name: pull test-runner image
+ run: docker pull ${{ steps.meta-test-runner.outputs.tags }}
+ - name: rename test-runner image
+ run: docker tag ${{ steps.meta-test-runner.outputs.tags }} test-runner:prebuilt
+ - name: pull contract deployer image
+ run: docker pull ${{ steps.meta-solidity.outputs.tags }}
+ - name: rename contract deployer image
+ run: docker tag ${{ steps.meta-solidity.outputs.tags }} solidity:prebuilt
+ - name: build go test binary
+ run: cd testnet && go test -c
+ - name: Run all up ci test
+ run: ./testnet/testnet.test -test.run Test${{ matrix.test_type }} -test.failfast -test.v
\ No newline at end of file
diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
new file mode 100644
index 0000000..e10b007
--- /dev/null
+++ b/.github/workflows/node.js.yml
@@ -0,0 +1,59 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: Solidity
+
+on:
+ push:
+ branches: [master, main]
+ pull_request:
+ branches: [master, main]
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+
+jobs:
+ node-build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ node-version: [ 16.x ]
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v2
+ with:
+ path: ~/.npm
+ key: ${{ runner.os }}-node-${{ hashFiles('solidity/package-lock.json') }}
+ - uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+ - run: cd solidity && npm ci
+ - run: cd solidity && npm run typechain
+ - run: cd solidity && npm run evm &
+ - run: cd solidity && npm run test
+
+ arbitrary-logic-tests:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ node-version: [16.x]
+ steps:
+ - uses: actions/cache@v2
+ with:
+ path: ~/.npm
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-node-
+ - uses: actions/checkout@v2
+ - name: Test arbitrary logic on mainnet fork
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+ - run: cd solidity && npm ci
+ - run: cd solidity && npm run typechain
+ - run: cd solidity && npm run evm_fork &
+ env:
+ ALCHEMY_ID: ${{ secrets.ALCHEMY_ID }}
+ - run: cd solidity && npm run test_fork
diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml
new file mode 100644
index 0000000..f1248b3
--- /dev/null
+++ b/.github/workflows/proto.yml
@@ -0,0 +1,31 @@
+name: Protobuf
+# Protobuf runs buf (https://buf.build/) lint and check-breakage
+# This workflow is only run when a .proto file has been changed
+on:
+ pull_request:
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ steps:
+ - uses: actions/checkout@master
+ - uses: technote-space/get-diff-action@v4
+ with:
+ PATTERNS: |
+ **/**.proto
+ - name: lint
+ run: cd module && make proto-lint
+ if: env.GIT_DIFF
+
+ breakage:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@master
+ - uses: technote-space/get-diff-action@v4
+ with:
+ PATTERNS: |
+ **/**.proto
+ - name: check-breakage
+ run: cd module && make proto-check-breaking
+ if: env.GIT_DIFF
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
new file mode 100644
index 0000000..e7ff776
--- /dev/null
+++ b/.github/workflows/rust.yml
@@ -0,0 +1,30 @@
+name: Rust tests
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ rust-test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout branch
+ uses: actions/checkout@v2
+ - name: Set up Rust caches
+ uses: actions/cache@v2
+ id: rust-cache
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ orchestrator/target/
+ key: ${{ runner.os }}-cargo-${{ hashFiles('orchestrator/Cargo.lock') }}
+ - name: Run Orchestrator unit tests
+ run: cd orchestrator && cargo test --all --verbose
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1549f6d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,21 @@
+node_modules
+typechain
+target
+tests/test-runner/Cargo.lock
+tests/dockerfile/gravity.tar.gz
+solidity/dist
+testdata/
+orchestrator/bins
+out/
+
+# IDE files
+.idea/
+
+#Hardhat files
+cache
+artifacts
+*.test
+
+.DS_Store
+
+build/
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..7b3401e
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,15 @@
+{
+ "overrides": [
+ {
+ "files": "*.sol",
+ "options": {
+ "printWidth": 100,
+ "tabWidth": 4,
+ "useTabs": true,
+ "singleQuote": false,
+ "bracketSpacing": true,
+ "explicitTypes": "always"
+ }
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..35e0f2d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,75 @@
+.DEFAULT_GOAL := e2e_slow_loris
+
+e2e_build_images:
+ @docker build -t gravity:prebuilt -f module/Dockerfile module/
+ @docker build -t solidity:prebuilt -f solidity/Dockerfile solidity/
+ @docker build -t orchestrator:prebuilt -f orchestrator/Dockerfile orchestrator/
+ @docker build -t test-runner:prebuilt -f orchestrator/testnet.Dockerfile orchestrator/
+
+
+e2e_slow_loris:
+ @make -s e2e_happy_path
+ @make -s e2e_v2_happy_path
+ @make -s e2e_orchestrator_keys
+ @make -s e2e_arbitrary_logic
+ @make -s e2e_validator_out
+ @make -s e2e_batch_stress
+ @make -s e2e_valset_stress
+
+e2e_clean_slate: e2e_build_images
+ @docker rm --force \
+ $(shell docker ps -qa --filter="name=contract_deployer") \
+ $(shell docker ps -qa --filter="name=ethereum") \
+ $(shell docker ps -qa --filter="name=gravity") \
+ $(shell docker ps -qa --filter="name=orchestrator") \
+ $(shell docker ps -qa --filter="name=test_runner") \
+ 1>/dev/null \
+ 2>/dev/null \
+ || true
+ @docker wait \
+ $(shell docker ps -qa --filter="name=contract_deployer") \
+ $(shell docker ps -qa --filter="name=ethereum") \
+ $(shell docker ps -qa --filter="name=gravity") \
+ $(shell docker ps -qa --filter="name=orchestrator") \
+ $(shell docker ps -qa --filter="name=test_runner") \
+ 1>/dev/null \
+ 2>/dev/null \
+ || true
+ @docker network rm testnet 1>/dev/null 2>/dev/null || true
+ @sudo rm -fr testdata
+ @cd testnet && go test -c
+
+e2e_batch_stress: e2e_clean_slate
+ @testnet/testnet.test -test.run TestBatchStress -test.failfast -test.v || make -s fail
+
+e2e_happy_path: e2e_clean_slate
+ @testnet/testnet.test -test.run TestHappyPath -test.failfast -test.v || make -s fail
+
+e2e_validator_out: e2e_clean_slate
+ @testnet/testnet.test -test.run TestValidatorOut -test.failfast -test.v || make -s fail
+
+e2e_valset_stress: e2e_clean_slate
+ @testnet/testnet.test -test.run TestValsetStress -test.failfast -test.v || make -s fail
+
+e2e_v2_happy_path: e2e_clean_slate
+ @testnet/testnet.test -test.run TestV2HappyPath -test.failfast -test.v || make -s fail
+
+e2e_arbitrary_logic: e2e_clean_slate
+ @testnet/testnet.test -test.run TestArbitraryLogic -test.failfast -test.v || make -s fail
+
+e2e_orchestrator_keys: e2e_clean_slate
+ @testnet/testnet.test -test.run TestOrchestratorKeys -test.failfast -test.v || make -s fail
+
+fail:
+ @echo 'test failed; dumping container logs into ./testdata for review'
+ @docker logs contract_deployer > testdata/contract_deployer.log 2>&1 || true
+ @docker logs gravity0 > testdata/gravity0.log 2>&1 || true
+ @docker logs gravity1 > testdata/gravity1.log 2>&1 || true
+ @docker logs gravity2 > testdata/gravity2.log 2>&1 || true
+ @docker logs gravity3 > testdata/gravity3.log 2>&1 || true
+ @docker logs orchestrator0 > testdata/orchestrator0.log 2>&1 || true
+ @docker logs orchestrator1 > testdata/orchestrator1.log 2>&1 || true
+ @docker logs orchestrator2 > testdata/orchestrator2.log 2>&1 || true
+ @docker logs orchestrator3 > testdata/orchestrator3.log 2>&1 || true
+ @docker logs test_runner > testdata/test_runner.log 2>&1 || true
+ @false
diff --git a/docs/architecture/README.md b/docs/architecture/README.md
new file mode 100644
index 0000000..530fa05
--- /dev/null
+++ b/docs/architecture/README.md
@@ -0,0 +1,33 @@
+# Architecture Decision Records (ADR)
+
+This is a location to record all high-level architecture decisions For the Gravity Bridge.
+
+An Architectural Decision (**AD**) is a software design choice that addresses a functional or non-functional requirement that is architecturally significant.
+An Architecturally Significant Requirement (**ASR**) is a requirement that has a measurable effect on a software system’s architecture and quality.
+An Architectural Decision Record (**ADR**) captures a single AD, such as often done when writing personal notes or meeting minutes; the collection of ADRs created and maintained in a project constitute its decision log. All these are within the topic of Architectural Knowledge Management (AKM).
+
+You can read more about the ADR concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t).
+
+## Rationale
+
+ADRs are intended to be the primary mechanism for proposing new feature designs and new processes, for collecting community input on an issue, and for documenting the design decisions.
+An ADR should provide:
+
+- Context on the relevant goals and the current state
+- Proposed changes to achieve the goals
+- Summary of pros and cons
+- References
+- Changelog
+
+Note the distinction between an ADR and a spec. The ADR provides the context, intuition, reasoning, and
+justification for a change in architecture, or for the architecture of something
+new. The spec is much more compressed and streamlined summary of everything as
+it stands today.
+
+If recorded decisions turned out to be lacking, convene a discussion, record the new decisions here, and then modify the code to match.
+
+## ADR Table of Contents
+
+### Accepted
+
+### Proposed
diff --git a/docs/architecture/adr-template.md b/docs/architecture/adr-template.md
new file mode 100644
index 0000000..191cd8e
--- /dev/null
+++ b/docs/architecture/adr-template.md
@@ -0,0 +1,60 @@
+# ADR {ADR-NUMBER}: {TITLE}
+
+## Changelog
+
+- {date}: {changelog}
+
+## Status
+
+{DRAFT | PROPOSED} Not Implemented
+
+> Please have a look at the [PROCESS](./PROCESS.md#adr-status) page.
+> Use DRAFT if the ADR is in a draft stage (draft PR) or PROPOSED if it's in review.
+
+## Abstract
+
+> "If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the ADR.
+> A short (~200 word) description of the issue being addressed.
+
+## Context
+
+> This section describes the forces at play, including technological, political, social, and project local. These forces are probably in tension, and should be called out as such. The language in this section is value-neutral. It is simply describing facts. It should clearly explain the problem and motivation that the proposal aims to resolve.
+> {context body}
+
+## Decision
+
+> This section describes our response to these forces. It is stated in full sentences, with active voice. "We will ..."
+> {decision body}
+
+## Consequences
+
+> This section describes the resulting context, after applying the decision. All consequences should be listed here, not just the "positive" ones. A particular decision may have positive, negative, and neutral consequences, but all of them affect the team and project in the future.
+
+### Backwards Compatibility
+
+> All ADRs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The ADR must explain how the author proposes to deal with these incompatibilities. ADR submissions without a sufficient backwards compatibility treatise may be rejected outright.
+
+### Positive
+
+{positive consequences}
+
+### Negative
+
+{negative consequences}
+
+### Neutral
+
+{neutral consequences}
+
+## Further Discussions
+
+While an ADR is in the DRAFT or PROPOSED stage, this section should contain a summary of issues to be solved in future iterations (usually referencing comments from a pull-request discussion).
+Later, this section can optionally list ideas or improvements the author or reviewers found during the analysis of this ADR.
+
+## Test Cases [optional]
+
+Test cases for an implementation are mandatory for ADRs that are affecting consensus changes. Other ADRs can choose to include links to test cases if applicable.
+
+## References
+
+- {reference link}
diff --git a/docs/design/arbitrary-logic.md b/docs/design/arbitrary-logic.md
new file mode 100644
index 0000000..d2d7dcc
--- /dev/null
+++ b/docs/design/arbitrary-logic.md
@@ -0,0 +1,51 @@
+# Arbitrary logic functionality
+
+Gravity includes the functionality to make arbitrary calls out to other Ethereum contracts. This can be used to allow the Cosmos chain to take actions on Ethereum. This functionality is very general. It can even be used to implement the core token transferring functionality of the bridge. However, there is one important caveat: these arbitrary logic contracts can transact with ERC20 tokens, but not any other kind of asset, such as ERC721. Interacting with non-ERC20 assets would require modifications to the core Gravity contract.
+
+# Architecture
+
+`SetOutgoingLogicCall`
+
+Gravity offers a method which can be called by other modules to create an outgoing logic call. To use this method, a calling module must first assemble a logic call (more on this later). This is then submitted to the Gravity module with `SetOutgoingLogicCall`. From here, it is signed by the validators. Once it has enough signatures, a Gravity relayer will pick it up and submit it to the Gravity contract on Ethereum.
+
+`OutgoingLogicCall`
+
+`SetOutgoingLogicCall` takes an `OutgoingLogicCall` as an argument. Here is an explanation of its parameters:
+
+```golang
+// OutgoingLogicCall represents an individual logic call from Gravity to ETH
+type OutgoingLogicCall struct {
+ Transfers []*ERC20Token `protobuf:"bytes,1,rep,name=transfers,proto3" json:"transfers,omitempty"`
+ Fees []*ERC20Token `protobuf:"bytes,2,rep,name=fees,proto3" json:"fees,omitempty"`
+ LogicContractAddress string `protobuf:"bytes,3,opt,name=logic_contract_address,json=logicContractAddress,proto3" json:"logic_contract_address,omitempty"`
+ Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3" json:"payload,omitempty"`
+ Timeout uint64 `protobuf:"varint,5,opt,name=timeout,proto3" json:"timeout,omitempty"`
+ InvalidationScope []byte `protobuf:"bytes,6,opt,name=invalidation_id,json=invalidationId,proto3" json:"invalidation_id,omitempty"`
+ InvalidationNonce uint64 `protobuf:"varint,7,opt,name=invalidation_nonce,json=invalidationNonce,proto3" json:"invalidation_nonce,omitempty"`
+}
+```
+
+- Transfers: These are tokens that are sent to the logic contract before it is executed. The contract can then take actions using the tokens. For example, Gravity could send the logic contract some Uniswap LP tokens that it would then use to redeem liquidity from Uniswap.
+- Fees: These are tokens that will be paid by the core Gravity.sol contract to the Gravity relayer for executing the logic call. Fees are paid after the logic contract executes, so it is possible to pay the relayer with tokens that logic contract receives after executing, and then sends back to the core Gravity contract.
+- LogicContractAddress: This is the address of the logic contract that the core Gravity contract calls to execute the arbitrary logic. NOTE: this could be the actual logic contract, or it could be a batching contract that calls the logic contract a number of times. Examples of this in the `/solidity/test` folder.
+- Payload: This is the Ethereum abi encoded function call that will be executed on the logic contract. If you are using a batching middleware contract, then this abi encoded function call will itself contain an array of abi encoded function calls on the actual logic contract.
+- Timeout: The logic call will not execute if the block timestamp on Ethereum is higher than the value of this timeout.
+- InvalidationScope and InvalidationNonce: More on these below:
+
+
+## Invalidation
+
+`invalidation_id` and `invalidation_nonce` are used as replay protection in the Gravity arbitrary logic call functionality.
+
+When a submitLogicCall transaction is submitted to the Ethereum contract, the contract checks uses `invalidation_id` to access a key in the invalidation mapping. The value at this key is checked against the supplied `invalidation_nonce`. The logic call is only allowed to go through if the supplied `invalidation_nonce` is higher.
+
+This can be used to implement many different invalidation schemes:
+
+### Easiest: timeout-only invalidation
+If you don't know what this all means, when you send a logic call to the Gravity module from the Cosmos side, just set the `invalidation_id` to an incrementing integer that you keep track of in your module. Set the `invalidation_nonce` to zero each time. This will create a new entry in the invalidation mapping on Ethereum for each logic batch, providing replay protection, while allowing batches to be completely independent.
+
+### Sequential invalidation
+If you don't want it to be possible to submit an early logic call after a later logic call, you can instead set the `invalidation_id` to zero each time, and use an incrementing integer for the `invalidation_nonce`. This makes it so that any logic call that is successfully submitted will invalidate all previous logic calls.
+
+### For example: Token based invalidation
+In Gravity's core submitBatch functionality, we have batches of transactions for a given token invalidate earlier batches of that token, but not earlier batches of other tokens. To implement this on top of the submitLogicCall method, we would set the `invalidation_id` to the token address and keep an incrementing nonce for each token.
diff --git a/docs/design/overview.md b/docs/design/overview.md
new file mode 100644
index 0000000..44a9934
--- /dev/null
+++ b/docs/design/overview.md
@@ -0,0 +1,125 @@
+# Design Overview
+
+This will walk through all the details of the technical design. [`notes.md`](../notes.md) is probably a better reference
+to get an overview. We will attempt to describe the entire technical design here and break out separate documents
+for the details message formats, etc.
+
+## Workflow
+
+The high-level workflow is:
+
+Activation Steps:
+
+- Bootstrap Cosmos SDK chain
+- Install Ethereum contract
+
+Token Transfer Steps:
+
+- Transfer original ERC20 tokens from ETH to Cosmos
+- Transfer pegged tokens from Cosmos to ETH
+- Update Cosmos Validator set on ETH
+
+The first two steps are done once, the other 3 repeated many times.
+
+## Definitions
+
+Words matter and we seek clarity in the terminology, so we can have clarity in our thinking and communication.
+Key concepts that we mention below will be defined here:
+
+- `Operator` - This is a person (or people) who control a Cosmos SDK validator node. This is also called `valoper` or "Validator Operator" in the Cosmos SDK staking section
+- `Full Node` - This is an _Ethereum_ Full Node run by an Operator
+- `Validator` - This is a Cosmos SDK Validating Node (signing blocks)
+- `Eth Signer` (name WIP) - This is a separate binary controlled by an Operator that holds Ethereum private keys used for signing transactions used to move tokens between the two chains.
+- `Oracle` (name WIP) - This is a separate binary controlled by an Operator that holds Cosmos SDK private keys used for bringing data from the Ethereum chain over to the Cosmos chain by submitting `Claims`, these claims aggregate into an `Attestation`
+- `Orchestrator` - a single binary that combines the `Eth Signer`, `Oracle`, and `Relayer` for ease of use by the `Operator`
+- `Relayer` - This is a type of node that submits updates to the Gravity contract on Ethereum. It earns fees from the transactions in a batch.
+- `REST server` - This is the Cosmos SDK "REST Server" that runs on Port 1317, either on the validator node or another Cosmos SDK node controlled by the Operator
+- `Ethereum RPC` - This is the JSON-RPC server for the Ethereum Full Node.
+- `Validator Set` - The set of validators on the Cosmos SDK chain, along with their respective voting power. These are ed25519 public keys used to sign tendermint blocks.
+- `Gravity Tx pool` - Is a transaction pool that exists in the chain store of Cosmos -> Ethereum transactions waiting to be placed into a transaction batch
+- `Transaction batch` - A transaction batch is a set of Ethereum transactions to be sent from the Gravity Ethereum contract at the same time. This helps reduce the costs of submitting a batch. Batches have a maximum size (currently around 100 transactions) and are only involved in the Cosmos -> Ethereum flow
+- `Gravity Batch pool` - Is a transaction pool like structure that exists in the chains to store, separate from the `Gravity Tx pool` it stores transactions that have been placed in batches that are in the process of being signed or being submitted by the `Orchestrator Set`
+- `EthBlockDelay` - Is a agreed upon number of Ethereum blocks all oracle attestations are delayed by. No `Orchestrator` will attest to have seen an event occur on Ethereum until this number of blocks has elapsed as denoted by their trusted Ethereum full node. This should prevent short forks form causing disagreements on the Cosmos side. The current value being considered is 50 blocks.
+- `Observed` - events on Ethereum are considered `Observed` when the `Eth Signers` of 66% of the active Cosmos validator set during a given block has submitted an oracle message attesting to seeing the event.
+- `Validator set delta` - This is a term for the difference between the validator set currently in the Gravity Ethereum contract and the actual validator set on the Cosmos chain. Since the validator set may change every single block there is essentially guaranteed to be some nonzero `Validator set delta` at any given time.
+- `Allowed validator set delta` - This is the maximum allowed `Validator set delta` this parameter is used to determine if the Gravity contract in MsgProposeGravityContract has a validator set 'close enough' to accept. It is also used to determine when validator set updates need to be sent. This is decided by a governance vote _before_ MsgProposeGravityContract can be sent.
+- `Gravity ID` - This is a random 32 byte value required to be included in all Gravity signatures for a particular contract instance. It is passed into the contract constructor on Ethereum and used to prevent signature reuse when contracts may share a validator set or subsets of a validator set. This is also set by a governance vote _before_ MsgProposeGravityContract can be sent.
+- `Gravity contract code hash` - This is the code hash of a known good version of the Gravity contract solidity code. It will be used to verify exactly which version of the bridge will be deployed.
+- `Start Threshold` - This is the percentage of total voting power that must be online and participating in Gravity operations before a bridge can start operating.
+- `Claim` (name WIP) - an Ethereum event signed and submitted to cosmos by a single `Orchestrator` instance
+- `Attestation` (name WIP) - aggregate of claims that eventually becomes `observed` by all orchestrators
+- `Voucher` - represent a bridged ETH token on the Cosmos side. Their denom is has a `gravity` prefix and a hash that is build from contract address and contract token. The denom is considered unique within the system.
+- `Counterpart` - to a `Voucher` is the locked ETH token in the contract
+- `Delegate keys` - when an `Operator` sets up the `Eth Signer` and `Oracle` they assign `Delegate Keys` by sending a message containing these keys using their `Validator` address. There is one delegate Ethereum key, used for signing messages on Ethereum and representing this `Validator` on Ethereum and one delegate Cosmos key that is used to submit `Oracle` messages.
+- `Gravity Contract` - The `Gravity Contract` is the Ethereum contract that holds all of the Gravity bridge bunds on the Ethereum side. It contains a representation of the cosmos validator set using `Delegate Keys` and normalized powers. For example if a validator has 5% of the Cosmos chain validator power, their delegate key will have 5% of the voting power in the `Gravity Contract` these value are regularly updated to keep the Cosmos and Ethereum chain validator sets in sync.
+
+The _Operator_ is the key unit of trust here. Each operator is responsible for maintaining 3 secure processes:
+
+1. Cosmos SDK Validator - signing blocks
+1. Fully synced Ethereum Full Node
+1. `Eth Signer`, which signs things with the `Operator's` Eth keys
+
+## Security Concerns
+
+The **Validator Set** is the actual set of keys with stake behind them, which are slashed for double-signs or other
+misbehavior. We typically consider the security of a chain to be the security of a _Validator Set_. This varies on
+each chain, but is our gold standard. Even IBC offers no more security than the minimum of both involved Validator Sets.
+
+The **Eth Signer** is a binary run alongside the main Cosmos daemon (`gaiad` or equivalent) by the validator set. It exists purely as a matter of code organization and is in charge of signing Ethereum transactions, as well as observing events on Ethereum and bringing them into the Cosmos state. It signs transactions bound for Ethereum with an Ethereum key, and signs over events coming from Ethereum with a Cosmos SDK key. We can add slashing conditions to any mis-signed message by any _Eth Signer_ run by the _Validator Set_ and be able to provide the same security as the _Valiator Set_, just a different module detecting evidence of malice and deciding how much to slash. If we can prove a transaction signed by any _Eth Signer_ of the _Validator Set_ was illegal or malicious, then we can slash on the Cosmos chain side and potentially provide 100% of the security of the _Validator Set_. Note that this also has access to the 3 week unbonding
+period to allow evidence to slash even if they immediately unbond.
+
+The **MultiSig Set** is a (possibly aged) mirror of the _Validator Set_ but with Ethereum keys, and stored on the Ethereum
+contract. If we ensure the _MultiSig Set_ is updated much more often than the unbonding period (eg at least once per week),
+then we can guarantee that all members of the _MultiSig Set_ have slashable atoms for misbehavior. However, in some extreme
+cases of stake shifting, the _MultiSig Set_ and _Validator Set_ could get quite far apart, meaning there is
+many of the members in the _MultiSig Set_ are no longer active validators and may not bother to transfer Eth messages.
+Thus, to avoid censorship attacks/inactivity, we should also update this everytime there is a significant change
+in the Validator Set (eg. > 3-5%). If we maintain those two conditions, the MultiSig Set should offer a similar level of
+security as the Validator Set.
+
+There are now 3 conditions that can be slashed for any validator: Double-signing a block with the tendermint key from the
+**Validator Set**, signing an invalid/malicious event from Ethereum with the Cosmos SDK key held by its _Eth Signer_, or
+signing an invalid/malicious Ethereum transaction with the Ethereum key held by its _Eth Signer_. If all conditions of misbehavior can
+be attributed to a signature from one of these sets, and proven **on the Cosmos chain**, then we can argue that Gravity offers
+a security level equal to the minimum of the Peg-Zone Validator Set, or reorganizing the Ethereum Chain 50 blocks.
+And provide a security equivalent to or greater than IBC.
+
+## Bootstrapping
+
+We assume the act of upgrading the Cosmos-based binary to have gravity module is already complete,
+as approaches to that are discussed in many other places. Here we focus on the _activation_ step.
+
+1. Each `Operator` generates an Ethereum and Cosmos private key for their `EthSigner`. These addresses are signed and submitted by the Operators valoper key in a MsgRegisterEthSigner. The `EthSigner` is now free to use these delegated keys for all Gravity messages.
+1. A governance vote is held on bridge parameters including `Gravity ID`, `Allowed validator set delta`, `start threshold`, and `Gravity contract code hash`
+1. Anyone deploys a Gravity contract using a known codehash and the current validator set of the Cosmos zone to an Ethereum compatible blockchain.
+1. Each `Operator` may or may not configure their `Eth Signer` with the above Gravity contract address
+1. If configured with an address the `Eth Signer` checks the provided address. If the contract passes validation the `Eth Signer` signs and submits a MsgProposeGravityContract. Validation is defined as finding the correct `Gravity contract code hash` and a validator set matching the current set within `Allowed validator set delta`.
+1. A contract address is considered adopted when voting power exceeding the `start threshold` has sent a MsgProposeGravityContract with the same Ethereum address.
+1. Because validator sets change quickly, `Eth Signers` not configured with a contract address observe the Cosmos blockchain for submissions. When an address is submitted they validate it and approve it themselves if it passes. This results in a workflow where once a valid contract is proposed it will be ratified in a matter of a few seconds.
+1. It is possible for the adoption process to fail if a race condition is intentionally created resulting in less than 66% of the validator power approving more than one valid Gravity Ethereum contract. In this case the Orchestrator will check the contract address with the majority of the power (or at random in the case of a perfect tie) and switch it's vote. This leaves only the possible edge case of >33% of `Operators` intentionally selecting a different contract address. This would be a consensus failure and the bridge can not progress.
+1. The bridge ratification process is complete, the contract address is now placed in the store to be referenced and other operations are allowed to move forward.
+
+At this point, we know we have a contract on Ethereum with the proper _MultiSig Set_, that > `start threshold` of the _Orchestrator Set_ is online and agrees with this contract, and that the Cosmos chain has stored this contract address. Only then can we begin to accept transactions to transfer tokens
+
+Note: `start threshold` is some security factor for bootstrapping. 67% is sufficient to release, but we don't want to start until there is a margin of error online (not to fall off with a small change of voting power). This may be 70, 80, 90, or even 95% depending on how much assurances we want that all _Orchestrators_ are operational before starting.
+
+## ETH to Cosmos Oracle
+
+All `Operators` run an `Oracle` binary. This separate process monitors an Ethereum node for new events involving the `Gravity Contract` on the Ethereum chain. Every event that `Oracle` monitors has an event nonce. This nonce is a unique coordinating value for a `Claim`. Since every event that may need to be observed by the `Oracle` has a unique event nonce `Claims` can always refer to a unique event by specifying the event nonce.
+
+- An `Oracle` observes an event on the Ethereum chain, it packages this event into a `Claim` and submits this claim to the cosmos chain
+- Within the Gravity Cosmos module this `Claim` either creates or is added to an existing `Attestation` that matches the details of the `Claim` once more than 66% of the active `Validator` set has made a `Claim` that matches the given `Attestation` the `Attestation` is executed. This may mint tokens, burn tokens, or whatever is appropriate for this particular event.
+- In the event that the validators can not agree >66% on a single `Attestation` the oracle is halted. This means no new events will be relayed from Ethereum until some of the validators change their votes. There is no slashing condition for this, because having one would risk the liveness of the chain itself if there was an expected Ethereum fork.
+
+## Relaying Cosmos to ETH
+
+- A user sends a MsgSendToEth when they want to transfer tokens across to Ethereum. This debits the tokens from their account, and places a transaction in the `Gravity Tx Pool`
+- Someone (permissionlessly) sends a MsgRequestBatch, this produces a new `Transaction batch` in the `Gravity Batch pool`. The creation of this batch occurs in CosmosSDK and is entirely deterministic, and should create the most profitable batch possible out of transactions in the `Gravity Tx Pool`.
+ - The `TransactionBatch` includes a batch nonce.
+ - It also includes the latest `Valset`
+ - The transactions in this batch are removed from the `Gravity Tx Pool`, and cannot be included in a new batch.
+- Batches in the `Gravity Batch Pool` are signed over by the `Validator Set`'s `Eth Signers`.
+ - `Relayers` may now attempt to submit these batches to the Gravity contract. If a batch has enough signatures (2/3+1 of the `Multisig Set`), it's submission will succeed. The decision whether or not to attempt a batch submission is entirely up to a given `Relayer`.
+- Once a batch is `Observed` to have been successfully submitted to Ethereum (this takes at least as long as the `EthBlockDelay`), any batches in the `Gravity Batch Pool` which have a lower nonce, and have not yet been successfully submitted have their transactions returned to the `Gravity Tx Pool` to be tried in a new batch. This is safe because we know that these batches cannot possibly be submitted any more since their nonces are too low.
+
+- When a new MsgRequestBatch comes in a new batch will not be produced unless it is more profitable than any batch currently in the `Gravity Batch Pool`. This means that when there is a batch backlog batches _must_ become progressively more profitable to submit.
diff --git a/docs/design/relaying-semantics.md b/docs/design/relaying-semantics.md
new file mode 100644
index 0000000..7ca33d8
--- /dev/null
+++ b/docs/design/relaying-semantics.md
@@ -0,0 +1,48 @@
+# Gravity bridge relaying semantics
+
+This document is designed to assist developers in implementing alternate Gravity relayers. The two major components of the Orchestrator which interact with Ethereum. The Gravity bridge has been designed for increased efficiency, not for ease of use. This means there are many implicit requirements of these external binaries which this document does it's best to make explicit.
+
+The Gravity `orchestrator` is described in [overview.md](overview.md) it's a combination of three distinct roles that need to be performed by external binaries in the Gravity bridge. This document highlights the requirements of the `relayer` which is one of those roles included in the `orchestrator`.
+
+## Semantics for Validator set update relaying
+
+### Sorting and Ordering of the Validator set and signatures
+
+When updating the validator set in the Gravity contract you must provide a copy of the old validator set. This _MUST_ only be taken from the last ValsetUpdated event on the Ethereum chain.
+
+Providing the old validator set is part of a storage optimization, instead of storing the entire validator set in Ethereum storage it is instead provided by each caller and stored in the much cheaper Ethereum event queue. No sorting of any kind is performed in the Gravity contract, meaning the list of validators and their new signatures must be submitted in exactly the same order as the last call.
+
+For the purpose of normal operation this requirement can be shortened to 'sort the validators by descending power, and by Eth address bytes where power is equal'. Since the Cosmos module produces the validator sets they should always come in order. But a flaw in this sorting method that caused an unsorted validator set to make it's way into the chain would halt valset updates and essentially decouple the bridge unless your implementation is smart enough to take a look at the last submitted order rather than blindly following sorting.
+
+### Deciding what Validator set to relay
+
+The Cosmos chain simply produces a stream of validator sets, it does not make any judgement on how they are relayed. It's up to the relayer implementation to determine how to optimize the gas costs of this relaying operation.
+
+For example lets say we had validator sets `A, B, C, and D` each is created when there is a 5% power difference between the last Gravity validator set snapshot in the store and the currently active validator set.
+
+5% is an arbitrary constant. The specific value chosen here is a tradeoff made by the chain between how up to date the Ethereum validator set is and the cost to keep it updated. The higher this value is the lower the portion of the voting validator set is needed to highjack the bridge in the worst case. If we made a new validator set update every block 66% would need to collude, the 5% change threshold means 61% of the total voting power colluding in a given validator set may be able to steal the funds in the bridge.
+
+```
+A -> B -> C -> D
+ 5% 10% 15%
+```
+
+The relayer should iterate over the event history for the Gravity Ethereum contract, it will determine that validator set A is currently in the Gravity bridge. It can choose to either relay validator sets B, C and then D or simply submit validator set D. Provided all validators have signed D it has more than 66% voting power and can pass on it's own. Without paying potentially several hundred dollars more in EThereum to relay the intermediate sets.
+
+Performing this check locally somehow, before submitting transactions, is essential to a cost effective relayer implementation. You can either use a local Ethereum signing implementation and sum the powers and signatures yourself, or you can simply use the `eth_call()` Ethereum RPC to simulate the call on your EThereum node.
+
+Note that `eth_call()` often has funny gotchas. All calls fail on Geth based implementations if you don't have any Ethereum to pay for gas, while on Parity based implementations your gas inputs are mostly ignored and an accurate gas usage is returned.
+
+## Semantics for transaction batch relaying
+
+In order to submit a transaction batch you also need to submit the last set of validators and their powers as outlined in [the validator set section](### Sorting and Ordering of the Validator set and signatures). This is to facilitate the same storage optimization mentioned there.
+
+### Deciding what batch to relay
+
+Making a decision about which batch to relay is very different from deciding which validator set to relay. Batch relaying is primarily motivated by fees, not by a desire to maintain the integrity of the bridge. So the decision mostly comes down to fee computation, this is further complicated by the concept of 'batch requests'. Which is an unpermissioned transaction that requests the Gravity module generate a new batch for a specific token type.
+
+Batch requests are designed to allow the user to withdraw their tokens from the send to Ethereum tx pool at any time up until a relayer shows interest in actually relaying them. While transactions are in the pool there's no risk of a double spend if the user is allowed to withdraw them by sending a MsgCancelSendToEth. Once the transaction enters a batch due to a 'request batch' that is no longer the case and the users funds must remain locked until the Oracle informs the Gravity module that the batch containing the users tokens has become somehow invalid to submit or has been executed on Ethereum.
+
+A relayer uses the query endpoint `BatchFees` to iterate over the send to Eth tx pool for each token type, the relayer can then observe the price for the ERC20 tokens being relayed on a dex and compute the gas cost of executing the batch (via `eth_call()`) as well as the gas cost of liquidating the earnings on a dex if desired. Once a relayer determines that a batch is good and profitable it can send a `MsgRequestBatch` and the batch will be created for the relayer to relay.
+
+There are also existing batches, which the relayer should also judge for profitability and make an attempt at relaying using much the same method.
diff --git a/ethereum/Dockerfile b/ethereum/Dockerfile
new file mode 100644
index 0000000..82b3678
--- /dev/null
+++ b/ethereum/Dockerfile
@@ -0,0 +1,23 @@
+FROM ethereum/client-go:v1.10.3
+
+RUN apk add --no-cache curl
+
+COPY testdata/testchain/ETHGenesis.json ETHGenesis.json
+
+RUN geth --identity "GravityTestnet" \
+ --nodiscover \
+ --networkid 15 init ETHGenesis.json
+
+ENTRYPOINT geth --identity "GravityTestnet" --nodiscover \
+ --networkid 15 \
+ --mine \
+ --http \
+ --http.port "8545" \
+ --http.addr "0.0.0.0" \
+ --http.corsdomain "*" \
+ --http.vhosts "*" \
+ --miner.threads=1 \
+ --nousb \
+ --verbosity=3 \
+ --miner.etherbase=0xBf660843528035a5A4921534E156a27e64B231fE \
+ --rpc.allow-unprotected-txs
\ No newline at end of file
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..8463c8c
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module github.com/cosmos/gravity-bridge
+
+go 1.15
+
+require github.com/cosmos/gravity-bridge/module v0.1.11 // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..e69de29
diff --git a/gravity-bridge.svg b/gravity-bridge.svg
new file mode 100644
index 0000000..6374a73
--- /dev/null
+++ b/gravity-bridge.svg
@@ -0,0 +1,47 @@
+
+
\ No newline at end of file
diff --git a/module/.golangci.yml b/module/.golangci.yml
new file mode 100644
index 0000000..5782826
--- /dev/null
+++ b/module/.golangci.yml
@@ -0,0 +1,59 @@
+linters:
+ enable:
+ - bodyclose
+ - deadcode
+ - depguard
+ - dogsled
+ # - dupl
+ - errcheck
+ # - funlen
+ # - gochecknoglobals
+ # - gochecknoinits
+ - goconst
+ - gocritic
+ # - gocyclo
+ # - godox
+ - gofmt
+ - goimports
+ - golint
+ - gosec
+ - gosimple
+ - govet
+ - ineffassign
+ - lll
+ - misspell
+ # - maligned
+ - nakedret
+ - prealloc
+ - scopelint
+ - staticcheck
+ - structcheck
+ - stylecheck
+ - typecheck
+ - unconvert
+ # - unparam
+ - unused
+ - varcheck
+ # - whitespace
+ # - wsl
+ # - gocognit
+
+linters-settings:
+ govet:
+ check-shadowing: true
+ errcheck:
+ # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
+ # default is false: such cases aren't reported by default.
+ check-blank: true
+ golint:
+ # minimal confidence for issues, default is 0.8
+ min-confidence: 0
+ prealloc:
+ # XXX: we don't recommend using this linter before doing performance profiling.
+ # For most programs usage of prealloc will be a premature optimization.
+
+ # Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
+ # True by default.
+ simple: false
+ range-loops: true # Report preallocation suggestions on range loops, true by default
+ for-loops: true # Report preallocation suggestions on for loops, false by default
diff --git a/module/.vscode/launch.json b/module/.vscode/launch.json
new file mode 100644
index 0000000..822f1d5
--- /dev/null
+++ b/module/.vscode/launch.json
@@ -0,0 +1,29 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Launch gravityd",
+ "type": "go",
+ "request": "launch",
+ "mode": "exec",
+ "program": "/go/bin/gravityd",
+ "showLog": true,
+ "args": [
+ "--home",
+ "/validator1",
+ "--address",
+ "tcp://7.7.7.1:26655",
+ "--rpc.laddr",
+ "tcp://7.7.7.1:26657",
+ "--p2p.laddr",
+ "tcp://7.7.7.1:26656",
+ "--log_level",
+ "info",
+ "start"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/module/Dockerfile b/module/Dockerfile
new file mode 100644
index 0000000..9feb7d2
--- /dev/null
+++ b/module/Dockerfile
@@ -0,0 +1,47 @@
+# Simple usage with a mounted data directory:
+# > docker build -t simapp .
+#
+# Server:
+# > docker run -it -p 26657:26657 -p 26656:26656 -v ~/.simapp:/root/.simapp simapp gravity init test-chain
+# TODO: need to set validator in genesis so start runs
+# > docker run -it -p 26657:26657 -p 26656:26656 -v ~/.simapp:/root/.simapp simapp gravity start
+#
+# Client: (Note the simapp binary always looks at ~/.simapp we can bind to different local storage)
+# > docker run -it -p 26657:26657 -p 26656:26656 -v ~/.simappcli:/root/.simapp simapp gravity keys add foo
+# > docker run -it -p 26657:26657 -p 26656:26656 -v ~/.simappcli:/root/.simapp simapp gravity keys list
+# TODO: demo connecting rest-server (or is this in server now?)
+FROM golang:alpine AS build-env
+
+# Install minimum necessary dependencies,
+ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3
+RUN apk add --no-cache $PACKAGES
+
+# Set working directory for the build
+WORKDIR /go/src/github.com/althea-net/cosmos-gravity-bridge/module
+
+# Get dependancies - will also be cached if we won't change mod/sum
+COPY go.mod .
+COPY go.sum .
+RUN go mod download
+
+# Add source files
+COPY . .
+
+# install simapp, remove packages
+RUN go build -o build/gravity ./cmd/gravity/main.go
+
+# Final image
+FROM alpine:edge
+
+# Install ca-certificates
+RUN apk add bash
+RUN apk add --update ca-certificates
+WORKDIR /root
+
+# Copy over binaries from the build-env
+COPY --from=build-env /go/src/github.com/althea-net/cosmos-gravity-bridge/module/build/gravity /usr/bin/gravity
+
+EXPOSE 26656 26657 1317 9090
+
+# Run gravity by default
+CMD ["gravity", "--home", "home", "start", "--pruning=nothing"]
\ No newline at end of file
diff --git a/module/Makefile b/module/Makefile
new file mode 100644
index 0000000..eea3e06
--- /dev/null
+++ b/module/Makefile
@@ -0,0 +1,163 @@
+PACKAGES=$(shell go list ./... | grep -v '/simulation')
+VERSION := $(shell git describe --abbrev=6 --dirty --always --tags)
+COMMIT := $(shell git log -1 --format='%H')
+DOCKER := $(shell which docker)
+DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf
+HTTPS_GIT := https://github.com/cosmos/gravity-bridge.git
+
+build_tags = netgo
+ifeq ($(LEDGER_ENABLED),true)
+ ifeq ($(OS),Windows_NT)
+ GCCEXE = $(shell where gcc.exe 2> NUL)
+ ifeq ($(GCCEXE),)
+ $(error gcc.exe not installed for ledger support, please install or set LEDGER_ENABLED=false)
+ else
+ build_tags += ledger
+ endif
+ else
+ UNAME_S = $(shell uname -s)
+ ifeq ($(UNAME_S),OpenBSD)
+ $(warning OpenBSD detected, disabling ledger support (https://github.com/cosmos/cosmos-sdk/issues/1988))
+ else
+ GCC = $(shell command -v gcc 2> /dev/null)
+ ifeq ($(GCC),)
+ $(error gcc not installed for ledger support, please install or set LEDGER_ENABLED=false)
+ else
+ build_tags += ledger
+ endif
+ endif
+ endif
+endif
+
+ifeq (cleveldb,$(findstring cleveldb,$(GAIA_BUILD_OPTIONS)))
+ build_tags += gcc
+endif
+build_tags += $(BUILD_TAGS)
+build_tags := $(strip $(build_tags))
+
+whitespace :=
+whitespace += $(whitespace)
+comma := ,
+build_tags_comma_sep := $(subst $(whitespace),$(comma),$(build_tags))
+
+ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=gravity \
+ -X github.com/cosmos/cosmos-sdk/version.AppName=gravity \
+ -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
+ -X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \
+ -X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \
+
+BUILD_FLAGS := -ldflags '$(ldflags)' -gcflags="all=-N -l"
+
+all: install
+
+install: go.sum
+ go install $(BUILD_FLAGS) ./cmd/gravity
+
+go.sum: go.mod
+ @echo "--> Ensure dependencies have not been modified"
+ GO111MODULE=on go mod verify
+
+test:
+ @go test -mod=readonly $(PACKAGES)
+
+build:
+ go build -o build/gravity $(BUILD_FLAGS) ./cmd/gravity/main.go
+
+docker-build:
+ docker build -t github.com/althea-net/gravity:latest
+
+# look into .golangci.yml for enabling / disabling linters
+lint:
+ @echo "--> Running linter"
+ @golangci-lint run
+ @go mod verify
+
+###############################################################################
+### Protobuf ###
+###############################################################################
+
+proto-all: proto-format proto-lint proto-gen
+
+proto-format:
+ @echo "Formatting Protobuf files"
+ $(DOCKER) run --rm -v $(CURDIR):/workspace \
+ --workdir /workspace tendermintdev/docker-build-proto \
+ find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {} \;
+
+
+proto-gen:
+ @echo "Generating Protobuf files"
+ # todo: figure out why this old method was failing
+ # $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen:v0.1 sh ./contrib/local/protocgen.sh
+ @sh ./contrib/local/protocgen.sh
+
+proto-lint:
+ @$(DOCKER_BUF) lint --error-format=json
+
+proto-check-breaking:
+ @echo $(DOCKER_BUF) breaking --against "$(HTTPS_GIT)#branch=main"
+ @$(DOCKER_BUF) breaking --against "$(HTTPS_GIT)#branch=main"
+
+TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.0-rc3/proto/tendermint
+GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos
+COSMOS_PROTO_URL = https://raw.githubusercontent.com/regen-network/cosmos-proto/master
+COSMOS_SDK_PROTO_URL = https://raw.githubusercontent.com/cosmos/cosmos-sdk/master/proto/cosmos/base
+GOOGLE_PROTO_URL = https://raw.githubusercontent.com/googleapis/googleapis/master/google/api
+PROTOBUF_GOOGLE_URL = https://raw.githubusercontent.com/protocolbuffers/protobuf/master/src/google/protobuf
+
+TM_CRYPTO_TYPES = third_party/proto/tendermint/crypto
+TM_ABCI_TYPES = third_party/proto/tendermint/abci
+TM_TYPES = third_party/proto/tendermint/types
+TM_VERSION = third_party/proto/tendermint/version
+TM_LIBS = third_party/proto/tendermint/libs/bits
+
+GOGO_PROTO_TYPES = third_party/proto/gogoproto
+COSMOS_PROTO_TYPES = third_party/proto/cosmos_proto
+GOOGLE_PROTO_TYPES = third_party/proto/google/api
+PROTOBUF_GOOGLE_TYPES = third_party/proto/google/protobuf
+
+SDK_ABCI_TYPES = third_party/proto/cosmos/base/abci/v1beta1
+SDK_QUERY_TYPES = third_party/proto/cosmos/base/query/v1beta1
+SDK_COIN_TYPES = third_party/proto/cosmos/base/v1beta1
+
+proto-update-deps:
+ mkdir -p $(GOGO_PROTO_TYPES)
+ curl -sSL $(GOGO_PROTO_URL)/gogoproto/gogo.proto > $(GOGO_PROTO_TYPES)/gogo.proto
+
+ mkdir -p $(COSMOS_PROTO_TYPES)
+ curl -sSL $(COSMOS_PROTO_URL)/cosmos.proto > $(COSMOS_PROTO_TYPES)/cosmos.proto
+
+ mkdir -p $(TM_ABCI_TYPES)
+ curl -sSL $(TM_URL)/abci/types.proto > $(TM_ABCI_TYPES)/types.proto
+
+ mkdir -p $(TM_VERSION)
+ curl -sSL $(TM_URL)/version/types.proto > $(TM_VERSION)/types.proto
+
+ mkdir -p $(TM_TYPES)
+ curl -sSL $(TM_URL)/types/types.proto > $(TM_TYPES)/types.proto
+ curl -sSL $(TM_URL)/types/evidence.proto > $(TM_TYPES)/evidence.proto
+ curl -sSL $(TM_URL)/types/params.proto > $(TM_TYPES)/params.proto
+
+ mkdir -p $(TM_CRYPTO_TYPES)
+ curl -sSL $(TM_URL)/crypto/proof.proto > $(TM_CRYPTO_TYPES)/proof.proto
+ curl -sSL $(TM_URL)/crypto/keys.proto > $(TM_CRYPTO_TYPES)/keys.proto
+
+ mkdir -p $(TM_LIBS)
+ curl -sSL $(TM_URL)/libs/bits/types.proto > $(TM_LIBS)/types.proto
+
+ mkdir -p $(SDK_ABCI_TYPES)
+ curl -sSL $(COSMOS_SDK_PROTO_URL)/abci/v1beta1/abci.proto > $(SDK_ABCI_TYPES)/abci.proto
+
+ mkdir -p $(SDK_QUERY_TYPES)
+ curl -sSL $(COSMOS_SDK_PROTO_URL)/query/v1beta1/pagination.proto > $(SDK_QUERY_TYPES)/pagination.proto
+
+ mkdir -p $(SDK_COIN_TYPES)
+ curl -sSL $(COSMOS_SDK_PROTO_URL)/v1beta1/coin.proto > $(SDK_COIN_TYPES)/coin.proto
+
+ mkdir -p $(GOOGLE_PROTO_TYPES)
+ curl -sSL $(GOOGLE_PROTO_URL)/annotations.proto > $(GOOGLE_PROTO_TYPES)/annotations.proto
+ curl -sSL $(GOOGLE_PROTO_URL)/http.proto > $(GOOGLE_PROTO_TYPES)/http.proto
+ curl -sSL $(GOOGLE_PROTO_URL)/httpbody.proto > $(GOOGLE_PROTO_TYPES)/httpbody.proto
+
+ mkdir -p $(PROTOBUF_GOOGLE_TYPES)
+ curl -sSL $(PROTOBUF_GOOGLE_URL)/any.proto > $(PROTOBUF_GOOGLE_TYPES)/any.proto
diff --git a/module/README.md b/module/README.md
new file mode 100644
index 0000000..a5f086d
--- /dev/null
+++ b/module/README.md
@@ -0,0 +1,60 @@
+## Building
+
+On first run:
+make proto-update-deps
+make proto-tools
+To build:
+make
+
+## Early MVP
+
+Happy path implementations
+
+### Oracle
+
+#### Assumptions
+
+- An orchestrator may want to submit multiple claims with a msg (withdrawal batch update + MultiSig Set update )
+- Nonces are not unique without a context (withdrawal nonce and MultiSig Set update can have same nonce (=height))
+- A nonce is unique in it's context and never reused
+- Multiple claims by an orchestrator for the same ETH event are forbidden
+- We know the ETH event types beforehand (and handle them as ClaimTypes)
+- For an **observation** status in Attestation the power AND count thresholds must be exceeded
+- Fraction type allows higher precision math than %. For example with 2/3
+
+A good start to follow the process would be the `x/gravity/handler_test.go` file
+
+### Outgoing TX Pool
+
+#### Features
+
+- Unique denominator for gravity vouchers in cosmos (🚧 cut to 15 chars and without a separator due to sdk limitations in v0.38.4)
+- Voucher burning 🔥 (minting in test ⛏️ )
+- Store/ resolve bridged ETH denominator and contract
+- Persistent transaction pool
+- Transactions sorted by fees (on a second index)
+- Extended test setup
+
+#### Assumptions
+
+- We have only 1 chainID and 1 ETH contract
+
+### Bundle Outgoing TX into Batches
+
+#### Features
+
+- `BatchTx` type with `OutgoingTransferTx` and `TransferCoin`
+- Logic to build batch from pending TXs based on fee desc order
+- Logic to cancel a batch and revert TXs back to pending pool
+- Incremental and unique IDs for batches to be used for `nonces`
+- `VoucherDenom` as first class type
+
+## Not covered/ implemented
+
+- [ ] unhappy cases
+- [ ] proper unit + integration tests
+- [ ] message validation
+- [ ] Genesis I/O
+- [ ] Parameters
+- [ ] authZ: EthereumChainID whitelisted
+- [ ] authZ: bridge contract address whitelisted
diff --git a/module/app/address.go b/module/app/address.go
new file mode 100644
index 0000000..77ee777
--- /dev/null
+++ b/module/app/address.go
@@ -0,0 +1,13 @@
+package app
+
+import (
+ sdk "github.com/cosmos/cosmos-sdk/types"
+)
+
+// SetAddressConfig sets the gravity app's address configuration.
+func SetAddressConfig() {
+ config := sdk.GetConfig()
+
+ config.SetAddressVerifier(VerifyAddressFormat)
+ config.Seal()
+}
diff --git a/module/app/app.go b/module/app/app.go
new file mode 100644
index 0000000..1eac22a
--- /dev/null
+++ b/module/app/app.go
@@ -0,0 +1,765 @@
+package app
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ "path/filepath"
+
+ "github.com/cosmos/cosmos-sdk/baseapp"
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
+ "github.com/cosmos/cosmos-sdk/client/rpc"
+ "github.com/cosmos/cosmos-sdk/codec"
+ "github.com/cosmos/cosmos-sdk/codec/types"
+ ccodec "github.com/cosmos/cosmos-sdk/crypto/codec"
+ "github.com/cosmos/cosmos-sdk/server/api"
+ "github.com/cosmos/cosmos-sdk/server/config"
+ servertypes "github.com/cosmos/cosmos-sdk/server/types"
+ "github.com/cosmos/cosmos-sdk/simapp"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/cosmos/cosmos-sdk/types/module"
+ "github.com/cosmos/cosmos-sdk/version"
+ "github.com/cosmos/cosmos-sdk/x/auth"
+ "github.com/cosmos/cosmos-sdk/x/auth/ante"
+ authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
+ authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
+ authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
+ authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
+ authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
+ "github.com/cosmos/cosmos-sdk/x/auth/vesting"
+ "github.com/cosmos/cosmos-sdk/x/bank"
+ bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
+ banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
+ "github.com/cosmos/cosmos-sdk/x/capability"
+ capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
+ capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
+ "github.com/cosmos/cosmos-sdk/x/crisis"
+ crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
+ crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
+ distr "github.com/cosmos/cosmos-sdk/x/distribution"
+ distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client"
+ distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
+ distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
+ "github.com/cosmos/cosmos-sdk/x/evidence"
+ evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
+ evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
+ "github.com/cosmos/cosmos-sdk/x/genutil"
+ genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
+ "github.com/cosmos/cosmos-sdk/x/gov"
+ govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
+ govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
+ "github.com/cosmos/cosmos-sdk/x/mint"
+ mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
+ minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
+ "github.com/cosmos/cosmos-sdk/x/params"
+ paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
+ paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
+ paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
+ paramsproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
+ "github.com/cosmos/cosmos-sdk/x/slashing"
+ slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
+ slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
+ "github.com/cosmos/cosmos-sdk/x/staking"
+ stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+ "github.com/cosmos/cosmos-sdk/x/upgrade"
+ upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
+ upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
+ upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
+ gravityparams "github.com/cosmos/gravity-bridge/module/app/params"
+ "github.com/cosmos/gravity-bridge/module/x/gravity"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/keeper"
+ gravitytypes "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+ ibctransfer "github.com/cosmos/ibc-go/modules/apps/transfer"
+ ibctransferkeeper "github.com/cosmos/ibc-go/modules/apps/transfer/keeper"
+ ibctransfertypes "github.com/cosmos/ibc-go/modules/apps/transfer/types"
+ ibc "github.com/cosmos/ibc-go/modules/core"
+ ibcclient "github.com/cosmos/ibc-go/modules/core/02-client"
+ ibcclienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types"
+ ibcporttypes "github.com/cosmos/ibc-go/modules/core/05-port/types"
+ ibchost "github.com/cosmos/ibc-go/modules/core/24-host"
+ ibckeeper "github.com/cosmos/ibc-go/modules/core/keeper"
+ "github.com/gorilla/mux"
+ "github.com/rakyll/statik/fs"
+ "github.com/spf13/cast"
+ abci "github.com/tendermint/tendermint/abci/types"
+ tmjson "github.com/tendermint/tendermint/libs/json"
+ "github.com/tendermint/tendermint/libs/log"
+ tmos "github.com/tendermint/tendermint/libs/os"
+ dbm "github.com/tendermint/tm-db"
+
+ // unnamed import of statik for swagger UI support
+ _ "github.com/cosmos/cosmos-sdk/client/docs/statik"
+)
+
+const (
+ appName = "app"
+
+ // MaxAddrLen is the maximum allowed length (in bytes) for an address.
+ //
+ // NOTE: In the SDK, the default value is 255.
+ MaxAddrLen = 20
+)
+
+var (
+ // DefaultNodeHome sets the folder where the applcation data and configuration will be stored
+ DefaultNodeHome string
+
+ // ModuleBasics The module BasicManager is in charge of setting up basic,
+ // non-dependant module elements, such as codec registration
+ // and genesis verification.
+ ModuleBasics = module.NewBasicManager(
+ auth.AppModuleBasic{},
+ genutil.AppModuleBasic{},
+ bank.AppModuleBasic{},
+ capability.AppModuleBasic{},
+ staking.AppModuleBasic{},
+ mint.AppModuleBasic{},
+ distr.AppModuleBasic{},
+ gov.NewAppModuleBasic(
+ paramsclient.ProposalHandler,
+ distrclient.ProposalHandler,
+ upgradeclient.ProposalHandler,
+ upgradeclient.CancelProposalHandler,
+ ),
+ params.AppModuleBasic{},
+ crisis.AppModuleBasic{},
+ slashing.AppModuleBasic{},
+ ibc.AppModuleBasic{},
+ upgrade.AppModuleBasic{},
+ evidence.AppModuleBasic{},
+ ibctransfer.AppModuleBasic{},
+ vesting.AppModuleBasic{},
+ gravity.AppModuleBasic{},
+ )
+
+ // module account permissions
+ // NOTE: We believe that this is giving various modules access to functions of the supply module? We will probably need to use this.
+ maccPerms = map[string][]string{
+ authtypes.FeeCollectorName: nil,
+ distrtypes.ModuleName: nil,
+ minttypes.ModuleName: {authtypes.Minter},
+ stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
+ stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
+ govtypes.ModuleName: {authtypes.Burner},
+ ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
+ gravitytypes.ModuleName: {authtypes.Minter, authtypes.Burner},
+ }
+
+ // module accounts that are allowed to receive tokens
+ allowedReceivingModAcc = map[string]bool{
+ distrtypes.ModuleName: true,
+ }
+
+ // verify app interface at compile time
+ _ simapp.App = (*Gravity)(nil)
+ _ servertypes.Application = (*Gravity)(nil)
+)
+
+// MakeCodec creates the application codec. The codec is sealed before it is
+// returned.
+func MakeCodec() *codec.LegacyAmino {
+ var cdc = codec.NewLegacyAmino()
+ ModuleBasics.RegisterLegacyAminoCodec(cdc)
+ vesting.AppModuleBasic{}.RegisterLegacyAminoCodec(cdc)
+ sdk.RegisterLegacyAminoCodec(cdc)
+ ccodec.RegisterCrypto(cdc)
+ cdc.Seal()
+ return cdc
+}
+
+// Gravity extended ABCI application
+type Gravity struct {
+ *baseapp.BaseApp
+ legacyAmino *codec.LegacyAmino
+ appCodec codec.Codec
+ interfaceRegistry types.InterfaceRegistry
+
+ invCheckPeriod uint
+
+ // keys to access the substores
+ keys map[string]*sdk.KVStoreKey
+ tKeys map[string]*sdk.TransientStoreKey
+ memKeys map[string]*sdk.MemoryStoreKey
+
+ // keepers
+ accountKeeper authkeeper.AccountKeeper
+ bankKeeper bankkeeper.Keeper
+ capabilityKeeper *capabilitykeeper.Keeper
+ stakingKeeper stakingkeeper.Keeper
+ slashingKeeper slashingkeeper.Keeper
+ mintKeeper mintkeeper.Keeper
+ distrKeeper distrkeeper.Keeper
+ govKeeper govkeeper.Keeper
+ crisisKeeper crisiskeeper.Keeper
+ upgradeKeeper upgradekeeper.Keeper
+ paramsKeeper paramskeeper.Keeper
+ ibcKeeper *ibckeeper.Keeper
+ evidenceKeeper evidencekeeper.Keeper
+ transferKeeper ibctransferkeeper.Keeper
+ gravityKeeper keeper.Keeper
+
+ // make scoped keepers public for test purposes
+ ScopedIBCKeeper capabilitykeeper.ScopedKeeper
+ ScopedTransferKeeper capabilitykeeper.ScopedKeeper
+
+ // Module Manager
+ mm *module.Manager
+
+ // simulation manager
+ sm *module.SimulationManager
+}
+
+func init() {
+ userHomeDir, err := os.UserHomeDir()
+ if err != nil {
+ panic(err)
+ }
+
+ DefaultNodeHome = filepath.Join(userHomeDir, ".gravity")
+}
+
+func NewGravityApp(
+ logger log.Logger,
+ db dbm.DB,
+ traceStore io.Writer,
+ loadLatest bool,
+ skipUpgradeHeights map[int64]bool,
+ homePath string,
+ invCheckPeriod uint,
+ encodingConfig gravityparams.EncodingConfig,
+ appOpts servertypes.AppOptions,
+ baseAppOptions ...func(*baseapp.BaseApp),
+) *Gravity {
+
+ appCodec := encodingConfig.Marshaler
+ legacyAmino := encodingConfig.Amino
+ interfaceRegistry := encodingConfig.InterfaceRegistry
+
+ bApp := baseapp.NewBaseApp(appName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...)
+ bApp.SetCommitMultiStoreTracer(traceStore)
+ bApp.SetVersion(version.Version)
+ bApp.SetInterfaceRegistry(interfaceRegistry)
+
+ keys := sdk.NewKVStoreKeys(
+ authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
+ minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
+ govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey,
+ evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey,
+ gravitytypes.StoreKey,
+ )
+ tKeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
+ memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
+
+ var app = &Gravity{
+ BaseApp: bApp,
+ legacyAmino: legacyAmino,
+ appCodec: appCodec,
+ interfaceRegistry: interfaceRegistry,
+ invCheckPeriod: invCheckPeriod,
+ keys: keys,
+ tKeys: tKeys,
+ memKeys: memKeys,
+ }
+
+ app.paramsKeeper = initParamsKeeper(appCodec, legacyAmino, keys[paramstypes.StoreKey], tKeys[paramstypes.TStoreKey])
+ bApp.SetParamStore(app.paramsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramskeeper.ConsensusParamsKeyTable()))
+
+ app.capabilityKeeper = capabilitykeeper.NewKeeper(
+ appCodec,
+ keys[capabilitytypes.StoreKey],
+ memKeys[capabilitytypes.MemStoreKey],
+ )
+ scopedIBCKeeper := app.capabilityKeeper.ScopeToModule(ibchost.ModuleName)
+ scopedTransferKeeper := app.capabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
+
+ // Applications that wish to enforce statically created ScopedKeepers should
+ // call `Seal` after creating their scoped modules in the app via
+ // `ScopeToModule`.
+ app.capabilityKeeper.Seal()
+
+ app.accountKeeper = authkeeper.NewAccountKeeper(
+ appCodec,
+ keys[authtypes.StoreKey],
+ app.GetSubspace(authtypes.ModuleName),
+ authtypes.ProtoBaseAccount,
+ maccPerms,
+ )
+
+ app.bankKeeper = bankkeeper.NewBaseKeeper(
+ appCodec,
+ keys[banktypes.StoreKey],
+ app.accountKeeper,
+ app.GetSubspace(banktypes.ModuleName),
+ app.BlockedAddrs(),
+ )
+
+ stakingKeeper := stakingkeeper.NewKeeper(
+ appCodec,
+ keys[stakingtypes.StoreKey],
+ app.accountKeeper,
+ app.bankKeeper,
+ app.GetSubspace(stakingtypes.ModuleName),
+ )
+
+ app.mintKeeper = mintkeeper.NewKeeper(
+ appCodec,
+ keys[minttypes.StoreKey],
+ app.GetSubspace(minttypes.ModuleName),
+ &stakingKeeper,
+ app.accountKeeper,
+ app.bankKeeper,
+ authtypes.FeeCollectorName,
+ )
+
+ app.distrKeeper = distrkeeper.NewKeeper(
+ appCodec,
+ keys[distrtypes.StoreKey],
+ app.GetSubspace(distrtypes.ModuleName),
+ app.accountKeeper,
+ app.bankKeeper,
+ &stakingKeeper,
+ authtypes.FeeCollectorName,
+ app.ModuleAccountAddrs(),
+ )
+
+ app.slashingKeeper = slashingkeeper.NewKeeper(
+ appCodec,
+ keys[slashingtypes.StoreKey],
+ &stakingKeeper,
+ app.GetSubspace(slashingtypes.ModuleName),
+ )
+
+ app.crisisKeeper = crisiskeeper.NewKeeper(
+ app.GetSubspace(crisistypes.ModuleName),
+ invCheckPeriod,
+ app.bankKeeper,
+ authtypes.FeeCollectorName,
+ )
+
+ app.upgradeKeeper = upgradekeeper.NewKeeper(
+ skipUpgradeHeights,
+ keys[upgradetypes.StoreKey],
+ appCodec,
+ homePath,
+ app.BaseApp,
+ )
+
+ app.stakingKeeper = *stakingKeeper.SetHooks(
+ stakingtypes.NewMultiStakingHooks(
+ app.distrKeeper.Hooks(),
+ app.slashingKeeper.Hooks(),
+ app.gravityKeeper.Hooks(),
+ ),
+ )
+
+ app.ibcKeeper = ibckeeper.NewKeeper(
+ appCodec,
+ keys[ibchost.StoreKey],
+ app.GetSubspace(ibchost.ModuleName),
+ app.stakingKeeper,
+ app.upgradeKeeper,
+ scopedIBCKeeper,
+ )
+
+ govRouter := govtypes.NewRouter()
+ govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
+ AddRoute(paramsproposal.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)).
+ AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper)).
+ AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.upgradeKeeper)).
+ AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.ibcKeeper.ClientKeeper))
+
+ app.govKeeper = govkeeper.NewKeeper(
+ appCodec,
+ keys[govtypes.StoreKey],
+ app.GetSubspace(govtypes.ModuleName),
+ app.accountKeeper,
+ app.bankKeeper,
+ &stakingKeeper,
+ govRouter,
+ )
+
+ app.transferKeeper = ibctransferkeeper.NewKeeper(
+ appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
+ app.ibcKeeper.ChannelKeeper, &app.ibcKeeper.PortKeeper,
+ app.accountKeeper, app.bankKeeper, scopedTransferKeeper,
+ )
+ transferModule := ibctransfer.NewAppModule(app.transferKeeper)
+
+ ibcRouter := ibcporttypes.NewRouter()
+ ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule)
+ app.ibcKeeper.SetRouter(ibcRouter)
+
+ evidenceKeeper := evidencekeeper.NewKeeper(
+ appCodec,
+ keys[evidencetypes.StoreKey],
+ &stakingKeeper,
+ app.slashingKeeper,
+ )
+ app.evidenceKeeper = *evidenceKeeper
+
+ app.gravityKeeper = keeper.NewKeeper(
+ appCodec,
+ keys[gravitytypes.StoreKey],
+ app.GetSubspace(gravitytypes.ModuleName),
+ app.accountKeeper,
+ stakingKeeper,
+ app.bankKeeper,
+ app.slashingKeeper,
+ sdk.DefaultPowerReduction,
+ )
+
+ var skipGenesisInvariants = cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants))
+
+ app.mm = module.NewManager(
+ genutil.NewAppModule(
+ app.accountKeeper,
+ app.stakingKeeper,
+ app.BaseApp.DeliverTx,
+ encodingConfig.TxConfig,
+ ),
+ auth.NewAppModule(
+ appCodec,
+ app.accountKeeper,
+ nil,
+ ),
+ vesting.NewAppModule(
+ app.accountKeeper,
+ app.bankKeeper,
+ ),
+ bank.NewAppModule(
+ appCodec,
+ app.bankKeeper,
+ app.accountKeeper,
+ ),
+ capability.NewAppModule(
+ appCodec,
+ *app.capabilityKeeper,
+ ),
+ crisis.NewAppModule(
+ &app.crisisKeeper,
+ skipGenesisInvariants,
+ ),
+ gov.NewAppModule(
+ appCodec,
+ app.govKeeper,
+ app.accountKeeper,
+ app.bankKeeper,
+ ),
+ mint.NewAppModule(
+ appCodec,
+ app.mintKeeper,
+ app.accountKeeper,
+ ),
+ slashing.NewAppModule(
+ appCodec,
+ app.slashingKeeper,
+ app.accountKeeper,
+ app.bankKeeper,
+ app.stakingKeeper,
+ ),
+ distr.NewAppModule(
+ appCodec,
+ app.distrKeeper,
+ app.accountKeeper,
+ app.bankKeeper,
+ app.stakingKeeper,
+ ),
+ staking.NewAppModule(appCodec,
+ app.stakingKeeper,
+ app.accountKeeper,
+ app.bankKeeper,
+ ),
+ upgrade.NewAppModule(app.upgradeKeeper),
+ evidence.NewAppModule(app.evidenceKeeper),
+ ibc.NewAppModule(app.ibcKeeper),
+ params.NewAppModule(app.paramsKeeper),
+ transferModule,
+ gravity.NewAppModule(
+ app.gravityKeeper,
+ app.bankKeeper,
+ ),
+ )
+
+ app.mm.SetOrderBeginBlockers(
+ upgradetypes.ModuleName,
+ capabilitytypes.ModuleName,
+ minttypes.ModuleName,
+ distrtypes.ModuleName,
+ slashingtypes.ModuleName,
+ evidencetypes.ModuleName,
+ stakingtypes.ModuleName,
+ ibchost.ModuleName,
+ gravitytypes.ModuleName,
+ )
+ app.mm.SetOrderEndBlockers(
+ crisistypes.ModuleName,
+ govtypes.ModuleName,
+ stakingtypes.ModuleName,
+ gravitytypes.ModuleName,
+ )
+ app.mm.SetOrderInitGenesis(
+ capabilitytypes.ModuleName,
+ authtypes.ModuleName,
+ banktypes.ModuleName,
+ distrtypes.ModuleName,
+ stakingtypes.ModuleName,
+ slashingtypes.ModuleName,
+ govtypes.ModuleName,
+ minttypes.ModuleName,
+ crisistypes.ModuleName,
+ ibchost.ModuleName,
+ genutiltypes.ModuleName,
+ evidencetypes.ModuleName,
+ ibctransfertypes.ModuleName,
+ gravitytypes.ModuleName,
+ )
+
+ app.mm.RegisterInvariants(&app.crisisKeeper)
+ app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino)
+ app.mm.RegisterServices(module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()))
+
+ app.sm = module.NewSimulationManager(
+ auth.NewAppModule(appCodec, app.accountKeeper, authsims.RandomGenesisAccounts),
+ bank.NewAppModule(appCodec, app.bankKeeper, app.accountKeeper),
+ capability.NewAppModule(appCodec, *app.capabilityKeeper),
+ gov.NewAppModule(appCodec, app.govKeeper, app.accountKeeper, app.bankKeeper),
+ mint.NewAppModule(appCodec, app.mintKeeper, app.accountKeeper),
+ staking.NewAppModule(appCodec, app.stakingKeeper, app.accountKeeper, app.bankKeeper),
+ distr.NewAppModule(appCodec, app.distrKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper),
+ slashing.NewAppModule(appCodec, app.slashingKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper),
+ params.NewAppModule(app.paramsKeeper),
+ evidence.NewAppModule(app.evidenceKeeper),
+ ibc.NewAppModule(app.ibcKeeper),
+ transferModule,
+ )
+
+ app.sm.RegisterStoreDecoders()
+
+ app.MountKVStores(keys)
+ app.MountTransientStores(tKeys)
+ app.MountMemoryStores(memKeys)
+
+ anteHandler, err := ante.NewAnteHandler(
+ ante.HandlerOptions{
+ AccountKeeper: app.accountKeeper,
+ BankKeeper: app.bankKeeper,
+ SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
+ FeegrantKeeper: nil,
+ SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
+ },
+ )
+ if err != nil {
+ panic(fmt.Errorf("failed to create ante handler: %s", err))
+ }
+
+ app.SetAnteHandler(anteHandler)
+ app.SetInitChainer(app.InitChainer)
+ app.SetBeginBlocker(app.BeginBlocker)
+ app.SetEndBlocker(app.EndBlocker)
+
+ if loadLatest {
+ if err := app.LoadLatestVersion(); err != nil {
+ tmos.Exit(err.Error())
+ }
+ }
+
+ app.ScopedIBCKeeper = scopedIBCKeeper
+ app.ScopedTransferKeeper = scopedTransferKeeper
+
+ return app
+}
+
+// MakeCodecs constructs the *std.Codec and *codec.LegacyAmino instances used by
+// simapp. It is useful for tests and clients who do not want to construct the
+// full simapp
+func MakeCodecs() (codec.Codec, *codec.LegacyAmino) {
+ config := MakeEncodingConfig()
+ return config.Marshaler, config.Amino
+}
+
+// Name returns the name of the App
+func (app *Gravity) Name() string { return app.BaseApp.Name() }
+
+// BeginBlocker application updates every begin block
+func (app *Gravity) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
+ return app.mm.BeginBlock(ctx, req)
+}
+
+// EndBlocker application updates every end block
+func (app *Gravity) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
+ return app.mm.EndBlock(ctx, req)
+}
+
+// InitChainer application update at chain initialization
+func (app *Gravity) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
+ var genesisState simapp.GenesisState
+ if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
+ panic(err)
+ }
+ return app.mm.InitGenesis(ctx, app.appCodec, genesisState)
+}
+
+// LoadHeight loads a particular height
+func (app *Gravity) LoadHeight(height int64) error {
+ return app.LoadVersion(height)
+}
+
+// ModuleAccountAddrs returns all the app's module account addresses.
+func (app *Gravity) ModuleAccountAddrs() map[string]bool {
+ modAccAddrs := make(map[string]bool)
+ for acc := range maccPerms {
+ modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true
+ }
+
+ return modAccAddrs
+}
+
+// BlockedAddrs returns all the app's module account addresses that are not
+// allowed to receive external tokens.
+func (app *Gravity) BlockedAddrs() map[string]bool {
+ blockedAddrs := make(map[string]bool)
+ for acc := range maccPerms {
+ blockedAddrs[authtypes.NewModuleAddress(acc).String()] = !allowedReceivingModAcc[acc]
+ }
+
+ return blockedAddrs
+}
+
+// LegacyAmino returns SimApp's amino codec.
+//
+// NOTE: This is solely to be used for testing purposes as it may be desirable
+// for modules to register their own custom testing types.
+func (app *Gravity) LegacyAmino() *codec.LegacyAmino {
+ return app.legacyAmino
+}
+
+// AppCodec returns SimApp's app codec.
+//
+// NOTE: This is solely to be used for testing purposes as it may be desirable
+// for modules to register their own custom testing types.
+func (app *Gravity) AppCodec() codec.Codec {
+ return app.appCodec
+}
+
+// InterfaceRegistry returns SimApp's InterfaceRegistry
+func (app *Gravity) InterfaceRegistry() types.InterfaceRegistry {
+ return app.interfaceRegistry
+}
+
+// GetKey returns the KVStoreKey for the provided store key.
+//
+// NOTE: This is solely to be used for testing purposes.
+func (app *Gravity) GetKey(storeKey string) *sdk.KVStoreKey {
+ return app.keys[storeKey]
+}
+
+// GetTKey returns the TransientStoreKey for the provided store key.
+//
+// NOTE: This is solely to be used for testing purposes.
+func (app *Gravity) GetTKey(storeKey string) *sdk.TransientStoreKey {
+ return app.tKeys[storeKey]
+}
+
+// GetMemKey returns the MemStoreKey for the provided mem key.
+//
+// NOTE: This is solely used for testing purposes.
+func (app *Gravity) GetMemKey(storeKey string) *sdk.MemoryStoreKey {
+ return app.memKeys[storeKey]
+}
+
+// GetSubspace returns a param subspace for a given module name.
+func (app *Gravity) GetSubspace(moduleName string) paramstypes.Subspace {
+ subspace, _ := app.paramsKeeper.GetSubspace(moduleName)
+ return subspace
+}
+
+// SimulationManager implements the SimulationApp interface
+func (app *Gravity) SimulationManager() *module.SimulationManager {
+ return app.sm
+}
+
+// RegisterAPIRoutes registers all application module routes with the provided
+// API server.
+func (app *Gravity) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
+ clientCtx := apiSvr.ClientCtx
+
+ rpc.RegisterRoutes(clientCtx, apiSvr.Router)
+ authrest.RegisterTxRoutes(clientCtx, apiSvr.Router)
+ authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
+ ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router)
+ ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
+
+ // TODO: build the custom gravity swagger files and add here?
+ if apiConfig.Swagger {
+ RegisterSwaggerAPI(clientCtx, apiSvr.Router)
+ }
+}
+
+// RegisterSwaggerAPI registers swagger route with API Server
+// TODO: build the custom gravity swagger files and add here?
+func RegisterSwaggerAPI(ctx client.Context, rtr *mux.Router) {
+ statikFS, err := fs.New()
+ if err != nil {
+ panic(err)
+ }
+
+ staticServer := http.FileServer(statikFS)
+ rtr.PathPrefix("/swagger/").Handler(http.StripPrefix("/swagger/", staticServer))
+}
+
+// RegisterTxService implements the Application.RegisterTxService method.
+func (app *Gravity) RegisterTxService(clientCtx client.Context) {
+ authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry)
+}
+
+// RegisterTendermintService implements the Application.RegisterTendermintService method.
+func (app *Gravity) RegisterTendermintService(clientCtx client.Context) {
+ tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry)
+}
+
+// GetMaccPerms returns a mapping of the application's module account permissions.
+func GetMaccPerms() map[string][]string {
+ modAccPerms := make(map[string][]string)
+ for k, v := range maccPerms {
+ modAccPerms[k] = v
+ }
+
+ return modAccPerms
+}
+
+// initParamsKeeper init params keeper and its subspaces
+func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper {
+ paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)
+
+ paramsKeeper.Subspace(authtypes.ModuleName)
+ paramsKeeper.Subspace(banktypes.ModuleName)
+ paramsKeeper.Subspace(stakingtypes.ModuleName)
+ paramsKeeper.Subspace(minttypes.ModuleName)
+ paramsKeeper.Subspace(distrtypes.ModuleName)
+ paramsKeeper.Subspace(slashingtypes.ModuleName)
+ paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable())
+ paramsKeeper.Subspace(crisistypes.ModuleName)
+ paramsKeeper.Subspace(ibctransfertypes.ModuleName)
+ paramsKeeper.Subspace(gravitytypes.ModuleName)
+ paramsKeeper.Subspace(ibchost.ModuleName)
+
+ return paramsKeeper
+}
+
+func VerifyAddressFormat(bz []byte) error {
+ if len(bz) == 0 {
+ return sdkerrors.Wrap(sdkerrors.ErrUnknownAddress, "invalid address; cannot be empty")
+ }
+ if len(bz) != MaxAddrLen {
+ return sdkerrors.Wrapf(
+ sdkerrors.ErrUnknownAddress,
+ "invalid address length; got: %d, max: %d", len(bz), MaxAddrLen,
+ )
+ }
+
+ return nil
+}
diff --git a/module/app/config.go b/module/app/config.go
new file mode 100644
index 0000000..5e8062f
--- /dev/null
+++ b/module/app/config.go
@@ -0,0 +1,75 @@
+package app
+
+import (
+ "flag"
+
+ "github.com/cosmos/cosmos-sdk/types/simulation"
+)
+
+// List of available flags for the simulator
+var (
+ FlagGenesisFileValue string
+ FlagParamsFileValue string
+ FlagExportParamsPathValue string
+ FlagExportParamsHeightValue int
+ FlagExportStatePathValue string
+ FlagExportStatsPathValue string
+ FlagSeedValue int64
+ FlagInitialBlockHeightValue int
+ FlagNumBlocksValue int
+ FlagBlockSizeValue int
+ FlagLeanValue bool
+ FlagCommitValue bool
+ FlagOnOperationValue bool // TODO: Remove in favor of binary search for invariant violation
+ FlagAllInvariantsValue bool
+
+ FlagEnabledValue bool
+ FlagVerboseValue bool
+ FlagPeriodValue uint
+ FlagGenesisTimeValue int64
+)
+
+// GetSimulatorFlags gets the values of all the available simulation flags
+func GetSimulatorFlags() {
+ // config fields
+ flag.StringVar(&FlagGenesisFileValue, "Genesis", "", "custom simulation genesis file; cannot be used with params file")
+ flag.StringVar(&FlagParamsFileValue, "Params", "", "custom simulation params file which overrides any random params; cannot be used with genesis")
+ flag.StringVar(&FlagExportParamsPathValue, "ExportParamsPath", "", "custom file path to save the exported params JSON")
+ flag.IntVar(&FlagExportParamsHeightValue, "ExportParamsHeight", 0, "height to which export the randomly generated params")
+ flag.StringVar(&FlagExportStatePathValue, "ExportStatePath", "", "custom file path to save the exported app state JSON")
+ flag.StringVar(&FlagExportStatsPathValue, "ExportStatsPath", "", "custom file path to save the exported simulation statistics JSON")
+ flag.Int64Var(&FlagSeedValue, "Seed", 42, "simulation random seed")
+ flag.IntVar(&FlagInitialBlockHeightValue, "InitialBlockHeight", 1, "initial block to start the simulation")
+ flag.IntVar(&FlagNumBlocksValue, "NumBlocks", 500, "number of new blocks to simulate from the initial block height")
+ flag.IntVar(&FlagBlockSizeValue, "BlockSize", 200, "operations per block")
+ flag.BoolVar(&FlagLeanValue, "Lean", false, "lean simulation log output")
+ flag.BoolVar(&FlagCommitValue, "Commit", false, "have the simulation commit")
+ flag.BoolVar(&FlagOnOperationValue, "SimulateEveryOperation", false, "run slow invariants every operation")
+ flag.BoolVar(&FlagAllInvariantsValue, "PrintAllInvariants", false, "print all invariants if a broken invariant is found")
+
+ // simulation flags
+ flag.BoolVar(&FlagEnabledValue, "Enabled", false, "enable the simulation")
+ flag.BoolVar(&FlagVerboseValue, "Verbose", false, "verbose log output")
+ flag.UintVar(&FlagPeriodValue, "Period", 0, "run slow invariants only once every period assertions")
+ flag.Int64Var(&FlagGenesisTimeValue, "GenesisTime", 0, "override genesis UNIX time instead of using a random UNIX time")
+}
+
+// NewConfigFromFlags creates a simulation from the retrieved values of the flags.
+func NewConfigFromFlags() simulation.Config {
+ return simulation.Config{
+ GenesisFile: FlagGenesisFileValue,
+ ParamsFile: FlagParamsFileValue,
+ ExportParamsPath: FlagExportParamsPathValue,
+ ExportParamsHeight: FlagExportParamsHeightValue,
+ ExportStatePath: FlagExportStatePathValue,
+ ExportStatsPath: FlagExportStatsPathValue,
+ Seed: FlagSeedValue,
+ InitialBlockHeight: FlagInitialBlockHeightValue,
+ NumBlocks: FlagNumBlocksValue,
+ BlockSize: FlagBlockSizeValue,
+ Lean: FlagLeanValue,
+ Commit: FlagCommitValue,
+ OnOperation: FlagOnOperationValue,
+ AllInvariants: FlagAllInvariantsValue,
+ }
+}
diff --git a/module/app/encoding.go b/module/app/encoding.go
new file mode 100644
index 0000000..55abdb2
--- /dev/null
+++ b/module/app/encoding.go
@@ -0,0 +1,16 @@
+package app
+
+import (
+ "github.com/cosmos/cosmos-sdk/std"
+ gravityparams "github.com/cosmos/gravity-bridge/module/app/params"
+)
+
+// MakeEncodingConfig creates an EncodingConfig for gravity.
+func MakeEncodingConfig() gravityparams.EncodingConfig {
+ encodingConfig := gravityparams.MakeEncodingConfig()
+ std.RegisterLegacyAminoCodec(encodingConfig.Amino)
+ std.RegisterInterfaces(encodingConfig.InterfaceRegistry)
+ ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino)
+ ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry)
+ return encodingConfig
+}
diff --git a/module/app/export.go b/module/app/export.go
new file mode 100644
index 0000000..01d20c7
--- /dev/null
+++ b/module/app/export.go
@@ -0,0 +1,196 @@
+package app
+
+import (
+ "encoding/json"
+ "log"
+
+ servertypes "github.com/cosmos/cosmos-sdk/server/types"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
+ "github.com/cosmos/cosmos-sdk/x/staking"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+ tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
+)
+
+// ExportAppStateAndValidators exports the state of the application for a genesis
+// file.
+func (app *Gravity) ExportAppStateAndValidators(
+ forZeroHeight bool, jailWhiteList []string,
+) (servertypes.ExportedApp, error) {
+
+ ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
+
+ height := app.LastBlockHeight() + 1
+ if forZeroHeight {
+ height = 0
+ app.prepForZeroHeightGenesis(ctx, jailWhiteList)
+ }
+
+ genState := app.mm.ExportGenesis(ctx, app.appCodec)
+ appState, err := json.MarshalIndent(genState, "", " ")
+ if err != nil {
+ return servertypes.ExportedApp{}, err
+ }
+
+ validators, err := staking.WriteValidators(ctx, app.stakingKeeper)
+ return servertypes.ExportedApp{
+ AppState: appState,
+ Validators: validators,
+ Height: height,
+ ConsensusParams: app.BaseApp.GetConsensusParams(ctx),
+ }, err
+}
+
+// prepare for fresh start at zero height
+// NOTE zero height genesis is a temporary feature which will be deprecated
+// in favour of export at a block height
+func (app *Gravity) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string) {
+ applyWhiteList := false
+
+ //Check if there is a whitelist
+ if len(jailWhiteList) > 0 {
+ applyWhiteList = true
+ }
+
+ whiteListMap := make(map[string]bool)
+
+ for _, addr := range jailWhiteList {
+ _, err := sdk.ValAddressFromBech32(addr)
+ if err != nil {
+ log.Fatal(err)
+ }
+ whiteListMap[addr] = true
+ }
+
+ /* Just to be safe, assert the invariants on current state. */
+ app.crisisKeeper.AssertInvariants(ctx)
+
+ /* Handle fee distribution state. */
+
+ // withdraw all validator commission
+ app.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
+ _, err := app.distrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
+ if err != nil {
+ log.Fatal(err)
+ }
+ return false
+ })
+
+ // withdraw all delegator rewards
+ dels := app.stakingKeeper.GetAllDelegations(ctx)
+ for _, delegation := range dels {
+ valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
+ if err != nil {
+ panic(err)
+ }
+
+ delAddr, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
+ if err != nil {
+ panic(err)
+ }
+
+ if _, err = app.distrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr); err != nil {
+ log.Fatal(err)
+ }
+ }
+
+ // clear validator slash events
+ app.distrKeeper.DeleteAllValidatorSlashEvents(ctx)
+
+ // clear validator historical rewards
+ app.distrKeeper.DeleteAllValidatorHistoricalRewards(ctx)
+
+ // set context height to zero
+ height := ctx.BlockHeight()
+ ctx = ctx.WithBlockHeight(0)
+
+ // reinitialize all validators
+ app.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
+ // donate any unwithdrawn outstanding reward fraction tokens to the community pool
+ scraps := app.distrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator())
+ feePool := app.distrKeeper.GetFeePool(ctx)
+ feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
+ app.distrKeeper.SetFeePool(ctx, feePool)
+
+ app.distrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator())
+ return false
+ })
+
+ // reinitialize all delegations
+ for _, del := range dels {
+ valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
+ if err != nil {
+ panic(err)
+ }
+ delAddr, err := sdk.AccAddressFromBech32(del.DelegatorAddress)
+ if err != nil {
+ panic(err)
+ }
+ app.distrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr)
+ app.distrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr)
+ }
+
+ // reset context height
+ ctx = ctx.WithBlockHeight(height)
+
+ /* Handle staking state. */
+
+ // iterate through redelegations, reset creation height
+ app.stakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) {
+ for i := range red.Entries {
+ red.Entries[i].CreationHeight = 0
+ }
+ app.stakingKeeper.SetRedelegation(ctx, red)
+ return false
+ })
+
+ // iterate through unbonding delegations, reset creation height
+ app.stakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) {
+ for i := range ubd.Entries {
+ ubd.Entries[i].CreationHeight = 0
+ }
+ app.stakingKeeper.SetUnbondingDelegation(ctx, ubd)
+ return false
+ })
+
+ // Iterate through validators by power descending, reset bond heights, and
+ // update bond intra-tx counters.
+ store := ctx.KVStore(app.keys[stakingtypes.StoreKey])
+ iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
+ counter := int16(0)
+
+ for ; iter.Valid(); iter.Next() {
+ addr := sdk.ValAddress(iter.Key()[1:])
+ validator, found := app.stakingKeeper.GetValidator(ctx, addr)
+ if !found {
+ panic("expected validator, not found")
+ }
+
+ validator.UnbondingHeight = 0
+ if applyWhiteList && !whiteListMap[addr.String()] {
+ validator.Jailed = true
+ }
+
+ app.stakingKeeper.SetValidator(ctx, validator)
+ counter++
+ }
+
+ iter.Close()
+
+ _, err := app.stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ /* Handle slashing state. */
+
+ // reset start height on signing infos
+ app.slashingKeeper.IterateValidatorSigningInfos(
+ ctx,
+ func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) {
+ info.StartHeight = 0
+ app.slashingKeeper.SetValidatorSigningInfo(ctx, addr, info)
+ return false
+ },
+ )
+}
diff --git a/module/app/genesis.go b/module/app/genesis.go
new file mode 100644
index 0000000..340cd80
--- /dev/null
+++ b/module/app/genesis.go
@@ -0,0 +1,20 @@
+package app
+
+import (
+ "encoding/json"
+)
+
+// The genesis state of the blockchain is represented here as a map of raw json
+// messages key'd by a identifier string.
+// The identifier is used to determine which module genesis information belongs
+// to so it may be appropriately routed during init chain.
+// Within this application default genesis information is retrieved from
+// the ModuleBasicManager which populates json from each BasicModule
+// object provided to it during init.
+type GenesisState map[string]json.RawMessage
+
+// NewDefaultGenesisState generates the default state for the application.
+func NewDefaultGenesisState() GenesisState {
+ encCfg := MakeEncodingConfig()
+ return ModuleBasics.DefaultGenesis(encCfg.Marshaler)
+}
diff --git a/module/app/params/doc.go b/module/app/params/doc.go
new file mode 100644
index 0000000..1c72134
--- /dev/null
+++ b/module/app/params/doc.go
@@ -0,0 +1,19 @@
+/*
+Package params defines the simulation parameters in the simapp.
+
+It contains the default weights used for each transaction used on the module's
+simulation. These weights define the chance for a transaction to be simulated at
+any gived operation.
+
+You can repace the default values for the weights by providing a params.json
+file with the weights defined for each of the transaction operations:
+
+ {
+ "op_weight_msg_send": 60,
+ "op_weight_msg_delegate": 100,
+ }
+
+In the example above, the `MsgSend` has 60% chance to be simulated, while the
+`MsgDelegate` will always be simulated.
+*/
+package params
diff --git a/module/app/params/encoding.go b/module/app/params/encoding.go
new file mode 100644
index 0000000..3d634ab
--- /dev/null
+++ b/module/app/params/encoding.go
@@ -0,0 +1,16 @@
+package params
+
+import (
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/codec"
+ "github.com/cosmos/cosmos-sdk/codec/types"
+)
+
+// EncodingConfig specifies the concrete encoding types to use for a given app.
+// This is provided for compatibility between protobuf and amino implementations.
+type EncodingConfig struct {
+ InterfaceRegistry types.InterfaceRegistry
+ Marshaler codec.Codec
+ TxConfig client.TxConfig
+ Amino *codec.LegacyAmino
+}
diff --git a/module/app/params/params.go b/module/app/params/params.go
new file mode 100644
index 0000000..b6aa5fb
--- /dev/null
+++ b/module/app/params/params.go
@@ -0,0 +1,7 @@
+package params
+
+// Simulation parameter constants
+const (
+ StakePerAccount = "stake_per_account"
+ InitiallyBondedValidators = "initially_bonded_validators"
+)
diff --git a/module/app/params/proto.go b/module/app/params/proto.go
new file mode 100644
index 0000000..84ff35a
--- /dev/null
+++ b/module/app/params/proto.go
@@ -0,0 +1,22 @@
+package params
+
+import (
+ "github.com/cosmos/cosmos-sdk/codec"
+ "github.com/cosmos/cosmos-sdk/codec/types"
+ "github.com/cosmos/cosmos-sdk/x/auth/tx"
+)
+
+// MakeEncodingConfig creates an EncodingConfig for an amino based test configuration.
+func MakeEncodingConfig() EncodingConfig {
+ amino := codec.NewLegacyAmino()
+ interfaceRegistry := types.NewInterfaceRegistry()
+ marshaler := codec.NewProtoCodec(interfaceRegistry)
+ txCfg := tx.NewTxConfig(marshaler, tx.DefaultSignModes)
+
+ return EncodingConfig{
+ InterfaceRegistry: interfaceRegistry,
+ Marshaler: marshaler,
+ TxConfig: txCfg,
+ Amino: amino,
+ }
+}
diff --git a/module/app/params/weights.go b/module/app/params/weights.go
new file mode 100644
index 0000000..0ba377b
--- /dev/null
+++ b/module/app/params/weights.go
@@ -0,0 +1,23 @@
+package params
+
+// Default simulation operation weights for messages and gov proposals
+const (
+ DefaultWeightMsgSend int = 100
+ DefaultWeightMsgMultiSend int = 10
+ DefaultWeightMsgSetWithdrawAddress int = 50
+ DefaultWeightMsgWithdrawDelegationReward int = 50
+ DefaultWeightMsgWithdrawValidatorCommission int = 50
+ DefaultWeightMsgFundCommunityPool int = 50
+ DefaultWeightMsgDeposit int = 100
+ DefaultWeightMsgVote int = 67
+ DefaultWeightMsgUnjail int = 100
+ DefaultWeightMsgCreateValidator int = 100
+ DefaultWeightMsgEditValidator int = 5
+ DefaultWeightMsgDelegate int = 100
+ DefaultWeightMsgUndelegate int = 100
+ DefaultWeightMsgBeginRedelegate int = 100
+
+ DefaultWeightCommunitySpendProposal int = 5
+ DefaultWeightTextProposal int = 5
+ DefaultWeightParamChangeProposal int = 5
+)
diff --git a/module/app/sim_test.go b/module/app/sim_test.go
new file mode 100644
index 0000000..df6d214
--- /dev/null
+++ b/module/app/sim_test.go
@@ -0,0 +1,335 @@
+package app
+
+import (
+ "encoding/json"
+ "fmt"
+ "math/rand"
+ "os"
+ "testing"
+
+ "github.com/cosmos/cosmos-sdk/baseapp"
+ "github.com/cosmos/cosmos-sdk/simapp"
+ "github.com/cosmos/cosmos-sdk/simapp/helpers"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
+ authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
+ banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
+ capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
+ distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
+ evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
+ govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
+ minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
+ paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
+ "github.com/cosmos/cosmos-sdk/x/simulation"
+ slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+ ibctransfertypes "github.com/cosmos/ibc-go/modules/apps/transfer/types"
+ ibchost "github.com/cosmos/ibc-go/modules/core/24-host"
+ "github.com/stretchr/testify/require"
+ abci "github.com/tendermint/tendermint/abci/types"
+ "github.com/tendermint/tendermint/libs/log"
+ tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
+ dbm "github.com/tendermint/tm-db"
+)
+
+func init() {
+ simapp.GetSimulatorFlags()
+}
+
+type StoreKeysPrefixes struct {
+ A sdk.StoreKey
+ B sdk.StoreKey
+ Prefixes [][]byte
+}
+
+// fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of
+// an IAVLStore for faster simulation speed.
+func fauxMerkleModeOpt(bapp *baseapp.BaseApp) {
+ bapp.SetFauxMerkleMode()
+}
+
+func TestFullAppSimulation(t *testing.T) {
+ config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
+ if skip {
+ t.Skip("skipping application simulation")
+ }
+ require.NoError(t, err, "simulation setup failed")
+
+ defer func() {
+ db.Close()
+ require.NoError(t, os.RemoveAll(dir))
+ }()
+
+ app := NewGravityApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt)
+ require.Equal(t, appName, app.Name())
+
+ // run randomized simulation
+ _, simParams, simErr := simulation.SimulateFromSeed(
+ t,
+ os.Stdout,
+ app.BaseApp,
+ AppStateFn(app.AppCodec(), app.SimulationManager()),
+ simtypes.RandomAccounts,
+ SimulationOperations(*app, app.AppCodec(), config),
+ app.ModuleAccountAddrs(),
+ config,
+ app.AppCodec(),
+ )
+
+ // export state and simParams before the simulation error is checked
+ err = CheckExportSimulation(*app, config, simParams)
+ require.NoError(t, err)
+ require.NoError(t, simErr)
+
+ if config.Commit {
+ PrintStats(db)
+ }
+}
+
+func TestAppImportExport(t *testing.T) {
+ config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation")
+ if skip {
+ t.Skip("skipping application import/export simulation")
+ }
+ require.NoError(t, err, "simulation setup failed")
+
+ defer func() {
+ db.Close()
+ require.NoError(t, os.RemoveAll(dir))
+ }()
+
+ app := NewGravityApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt)
+ require.Equal(t, appName, app.Name())
+
+ // Run randomized simulation
+ _, simParams, simErr := simulation.SimulateFromSeed(
+ t,
+ os.Stdout,
+ app.BaseApp,
+ AppStateFn(app.AppCodec(), app.SimulationManager()),
+ simtypes.RandomAccounts,
+ SimulationOperations(*app, app.AppCodec(), config),
+ app.ModuleAccountAddrs(),
+ config,
+ app.AppCodec(),
+ )
+
+ // export state and simParams before the simulation error is checked
+ err = CheckExportSimulation(*app, config, simParams)
+ require.NoError(t, err)
+ require.NoError(t, simErr)
+
+ if config.Commit {
+ PrintStats(db)
+ }
+
+ fmt.Printf("exporting genesis...\n")
+
+ appState, err := app.ExportAppStateAndValidators(false, []string{})
+ require.NoError(t, err)
+
+ fmt.Printf("importing genesis...\n")
+
+ _, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2")
+ require.NoError(t, err, "simulation setup failed")
+
+ defer func() {
+ newDB.Close()
+ require.NoError(t, os.RemoveAll(newDir))
+ }()
+
+ newApp := NewGravityApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt)
+ require.Equal(t, appName, newApp.Name())
+
+ var genesisState GenesisState
+ err = json.Unmarshal(appState.AppState, &genesisState)
+ require.NoError(t, err)
+
+ ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
+ ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
+ newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState)
+
+ fmt.Printf("comparing stores...\n")
+
+ storeKeysPrefixes := []StoreKeysPrefixes{
+ {app.keys[authtypes.StoreKey], newApp.keys[authtypes.StoreKey], [][]byte{}},
+ {app.keys[stakingtypes.StoreKey], newApp.keys[stakingtypes.StoreKey],
+ [][]byte{
+ stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey,
+ stakingtypes.HistoricalInfoKey,
+ }}, // ordering may change but it doesn't matter
+ {app.keys[slashingtypes.StoreKey], newApp.keys[slashingtypes.StoreKey], [][]byte{}},
+ {app.keys[minttypes.StoreKey], newApp.keys[minttypes.StoreKey], [][]byte{}},
+ {app.keys[distrtypes.StoreKey], newApp.keys[distrtypes.StoreKey], [][]byte{}},
+ {app.keys[banktypes.StoreKey], newApp.keys[banktypes.StoreKey], [][]byte{banktypes.BalancesPrefix}},
+ {app.keys[paramtypes.StoreKey], newApp.keys[paramtypes.StoreKey], [][]byte{}},
+ {app.keys[govtypes.StoreKey], newApp.keys[govtypes.StoreKey], [][]byte{}},
+ {app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}},
+ {app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}},
+ {app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}},
+ {app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}},
+ // TODO: Add gravity module once simulation code is write
+ }
+
+ for _, skp := range storeKeysPrefixes {
+ storeA := ctxA.KVStore(skp.A)
+ storeB := ctxB.KVStore(skp.B)
+
+ failedKVAs, failedKVBs := sdk.DiffKVStores(storeA, storeB, skp.Prefixes)
+ require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare")
+
+ fmt.Printf("compared %d key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B)
+ require.Equal(t, len(failedKVAs), 0, GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs))
+ }
+}
+
+func TestAppSimulationAfterImport(t *testing.T) {
+ config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
+ if skip {
+ t.Skip("skipping application simulation after import")
+ }
+ require.NoError(t, err, "simulation setup failed")
+
+ defer func() {
+ db.Close()
+ require.NoError(t, os.RemoveAll(dir))
+ }()
+
+ app := NewGravityApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt)
+ require.Equal(t, appName, app.Name())
+
+ // Run randomized simulation
+ stopEarly, simParams, simErr := simulation.SimulateFromSeed(
+ t,
+ os.Stdout,
+ app.BaseApp,
+ AppStateFn(app.AppCodec(), app.SimulationManager()),
+ simtypes.RandomAccounts,
+ SimulationOperations(*app, app.AppCodec(), config),
+ app.ModuleAccountAddrs(),
+ config,
+ app.AppCodec(),
+ )
+
+ // export state and simParams before the simulation error is checked
+ err = CheckExportSimulation(*app, config, simParams)
+ require.NoError(t, err)
+ require.NoError(t, simErr)
+
+ if config.Commit {
+ PrintStats(db)
+ }
+
+ if stopEarly {
+ fmt.Println("can't export or import a zero-validator genesis, exiting test...")
+ return
+ }
+
+ fmt.Printf("exporting genesis...\n")
+
+ appState, err := app.ExportAppStateAndValidators(true, []string{})
+ require.NoError(t, err)
+
+ fmt.Printf("importing genesis...\n")
+
+ _, newDB, newDir, _, _, err := SetupSimulation("leveldb-app-sim-2", "Simulation-2")
+ require.NoError(t, err, "simulation setup failed")
+
+ defer func() {
+ newDB.Close()
+ require.NoError(t, os.RemoveAll(newDir))
+ }()
+
+ newApp := NewGravityApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt)
+ require.Equal(t, appName, newApp.Name())
+
+ newApp.InitChain(abci.RequestInitChain{
+ AppStateBytes: appState.AppState,
+ })
+
+ _, _, err = simulation.SimulateFromSeed(
+ t,
+ os.Stdout,
+ newApp.BaseApp,
+ AppStateFn(app.AppCodec(), app.SimulationManager()),
+ simtypes.RandomAccounts,
+ SimulationOperations(*newApp, newApp.AppCodec(), config),
+ newApp.ModuleAccountAddrs(),
+ config,
+ app.AppCodec(),
+ )
+ require.NoError(t, err)
+}
+
+func TestAppStateDeterminism(t *testing.T) {
+ if !FlagEnabledValue {
+ t.Skip("skipping application simulation")
+ }
+
+ config := NewConfigFromFlags()
+ config.InitialBlockHeight = 1
+ config.ExportParamsPath = ""
+ config.OnOperation = false
+ config.AllInvariants = false
+ config.ChainID = helpers.SimAppChainID
+
+ numSeeds := 3
+ numTimesToRunPerSeed := 5
+ appHashList := make([]json.RawMessage, numTimesToRunPerSeed)
+
+ for i := 0; i < numSeeds; i++ {
+ config.Seed = rand.Int63()
+
+ for j := 0; j < numTimesToRunPerSeed; j++ {
+ var logger log.Logger
+ if FlagVerboseValue {
+ logger = log.TestingLogger()
+ } else {
+ logger = log.NewNopLogger()
+ }
+
+ db := dbm.NewMemDB()
+ app := NewGravityApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt)
+
+ fmt.Printf(
+ "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n",
+ config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
+ )
+
+ _, _, err := simulation.SimulateFromSeed(
+ t,
+ os.Stdout,
+ app.BaseApp,
+ AppStateFn(app.AppCodec(), app.SimulationManager()),
+ simtypes.RandomAccounts,
+ SimulationOperations(*app, app.AppCodec(), config),
+ app.ModuleAccountAddrs(),
+ config,
+ app.AppCodec(),
+ )
+ require.NoError(t, err)
+
+ if config.Commit {
+ PrintStats(db)
+ }
+
+ appHash := app.LastCommitID().Hash
+ appHashList[j] = appHash
+
+ if j != 0 {
+ require.Equal(
+ t, string(appHashList[0]), string(appHashList[j]),
+ "non-determinism in seed %d: %d/%d, attempt: %d/%d\n", config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
+ )
+ }
+ }
+ }
+}
+
+// EmptyAppOptions is a stub implementing AppOptions
+type EmptyAppOptions struct{}
+
+// Get implements AppOptions
+func (ao EmptyAppOptions) Get(o string) interface{} {
+ return nil
+}
diff --git a/module/app/state.go b/module/app/state.go
new file mode 100644
index 0000000..3c9fc4e
--- /dev/null
+++ b/module/app/state.go
@@ -0,0 +1,181 @@
+package app
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "math/rand"
+ "time"
+
+ "github.com/cosmos/cosmos-sdk/codec"
+ "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
+ simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
+ tmjson "github.com/tendermint/tendermint/libs/json"
+ tmtypes "github.com/tendermint/tendermint/types"
+
+ "github.com/cosmos/cosmos-sdk/types/module"
+ simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
+ authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
+)
+
+// TODO: audit this code when we hook up simulations
+
+// AppStateFn returns the initial application state using a genesis or the simulation parameters.
+// It panics if the user provides files for both of them.
+// If a file is not given for the genesis or the sim params, it creates a randomized one.
+func AppStateFn(cdc codec.JSONCodec, simManager *module.SimulationManager) simtypes.AppStateFn {
+ return func(r *rand.Rand, accs []simtypes.Account, config simtypes.Config,
+ ) (appState json.RawMessage, simAccs []simtypes.Account, chainID string, genesisTimestamp time.Time) {
+
+ if FlagGenesisTimeValue == 0 {
+ genesisTimestamp = simtypes.RandTimestamp(r)
+ } else {
+ genesisTimestamp = time.Unix(FlagGenesisTimeValue, 0)
+ }
+
+ chainID = config.ChainID
+ switch {
+ case config.ParamsFile != "" && config.GenesisFile != "":
+ panic("cannot provide both a genesis file and a params file")
+
+ case config.GenesisFile != "":
+ // override the default chain-id from simapp to set it later to the config
+ genesisDoc, accounts := StateFromGenesisFileFn(r, cdc, config.GenesisFile)
+
+ if FlagGenesisTimeValue == 0 {
+ // use genesis timestamp if no custom timestamp is provided (i.e no random timestamp)
+ genesisTimestamp = genesisDoc.GenesisTime
+ }
+
+ appState = genesisDoc.AppState
+ chainID = genesisDoc.ChainID
+ simAccs = accounts
+
+ case config.ParamsFile != "":
+ appParams := make(simtypes.AppParams)
+ bz, err := ioutil.ReadFile(config.ParamsFile)
+ if err != nil {
+ panic(err)
+ }
+
+ err = json.Unmarshal(bz, &appParams)
+ if err != nil {
+ panic(err)
+ }
+ appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams)
+
+ default:
+ appParams := make(simtypes.AppParams)
+ appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams)
+ }
+
+ return appState, simAccs, chainID, genesisTimestamp
+ }
+}
+
+// AppStateRandomizedFn creates calls each module's GenesisState generator function
+// and creates the simulation params
+func AppStateRandomizedFn(
+ simManager *module.SimulationManager, r *rand.Rand, cdc codec.JSONCodec,
+ accs []simtypes.Account, genesisTimestamp time.Time, appParams simtypes.AppParams,
+) (json.RawMessage, []simtypes.Account) {
+ numAccs := int64(len(accs))
+ genesisState := NewDefaultGenesisState()
+
+ // generate a random amount of initial stake coins and a random initial
+ // number of bonded accounts
+ var initialStake, numInitiallyBonded int64
+ appParams.GetOrGenerate(
+ cdc, simappparams.StakePerAccount, &initialStake, r,
+ func(r *rand.Rand) { initialStake = r.Int63n(1e12) },
+ )
+ appParams.GetOrGenerate(
+ cdc, simappparams.InitiallyBondedValidators, &numInitiallyBonded, r,
+ func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(300)) },
+ )
+
+ if numInitiallyBonded > numAccs {
+ numInitiallyBonded = numAccs
+ }
+
+ fmt.Printf(
+ `Selected randomly generated parameters for simulated genesis:
+{
+ stake_per_account: "%d",
+ initially_bonded_validators: "%d"
+}
+`, initialStake, numInitiallyBonded,
+ )
+
+ simState := &module.SimulationState{
+ AppParams: appParams,
+ Cdc: cdc,
+ Rand: r,
+ GenState: genesisState,
+ Accounts: accs,
+ InitialStake: initialStake,
+ NumBonded: numInitiallyBonded,
+ GenTimestamp: genesisTimestamp,
+ }
+
+ simManager.GenerateGenesisStates(simState)
+
+ appState, err := json.Marshal(genesisState)
+ if err != nil {
+ panic(err)
+ }
+
+ return appState, accs
+}
+
+// StateFromGenesisFileFn util function to generate the genesis AppState
+// from a genesis.json file.
+func StateFromGenesisFileFn(r io.Reader, cdc codec.JSONCodec, genesisFile string) (tmtypes.GenesisDoc, []simtypes.Account) {
+ bytes, err := ioutil.ReadFile(genesisFile)
+ if err != nil {
+ panic(err)
+ }
+
+ var genesis tmtypes.GenesisDoc
+ // NOTE: Tendermint uses a custom JSON decoder for GenesisDoc
+ err = tmjson.Unmarshal(bytes, &genesis)
+ if err != nil {
+ panic(err)
+ }
+
+ var appState GenesisState
+ err = json.Unmarshal(genesis.AppState, &appState)
+ if err != nil {
+ panic(err)
+ }
+
+ var authGenesis authtypes.GenesisState
+ if appState[authtypes.ModuleName] != nil {
+ cdc.MustUnmarshalJSON(appState[authtypes.ModuleName], &authGenesis)
+ }
+
+ newAccs := make([]simtypes.Account, len(authGenesis.Accounts))
+ for i, acc := range authGenesis.Accounts {
+ // Pick a random private key, since we don't know the actual key
+ // This should be fine as it's only used for mock Tendermint validators
+ // and these keys are never actually used to sign by mock Tendermint.
+ privkeySeed := make([]byte, 15)
+ if _, err := r.Read(privkeySeed); err != nil {
+ panic(err)
+ }
+
+ privKey := secp256k1.GenPrivKeyFromSecret(privkeySeed)
+
+ a, ok := acc.GetCachedValue().(authtypes.AccountI)
+ if !ok {
+ panic("expected account")
+ }
+
+ // create simulator accounts
+ simAcc := simtypes.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: a.GetAddress()}
+ newAccs[i] = simAcc
+ }
+
+ return genesis, newAccs
+}
diff --git a/module/app/utils.go b/module/app/utils.go
new file mode 100644
index 0000000..9f9883c
--- /dev/null
+++ b/module/app/utils.go
@@ -0,0 +1,131 @@
+package app
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+
+ "github.com/tendermint/tendermint/libs/log"
+ dbm "github.com/tendermint/tm-db"
+
+ "github.com/cosmos/cosmos-sdk/codec"
+ "github.com/cosmos/cosmos-sdk/simapp/helpers"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/cosmos/cosmos-sdk/types/kv"
+ "github.com/cosmos/cosmos-sdk/types/module"
+ simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
+)
+
+// SetupSimulation creates the config, db (levelDB), temporary directory and logger for
+// the simulation tests. If `FlagEnabledValue` is false it skips the current test.
+// Returns error on an invalid db intantiation or temp dir creation.
+func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, log.Logger, bool, error) {
+ if !FlagEnabledValue {
+ return simtypes.Config{}, nil, "", nil, true, nil
+ }
+
+ config := NewConfigFromFlags()
+ config.ChainID = helpers.SimAppChainID
+
+ var logger log.Logger
+ if FlagVerboseValue {
+ logger = log.TestingLogger()
+ } else {
+ logger = log.NewNopLogger()
+ }
+
+ dir, err := ioutil.TempDir("", dirPrefix)
+ if err != nil {
+ return simtypes.Config{}, nil, "", nil, false, err
+ }
+
+ db, err := sdk.NewLevelDB(dbName, dir)
+ if err != nil {
+ return simtypes.Config{}, nil, "", nil, false, err
+ }
+
+ return config, db, dir, logger, false, nil
+}
+
+// SimulationOperations retrieves the simulation params from the provided file path
+// and returns all the modules weighted operations
+func SimulationOperations(app Gravity, cdc codec.JSONCodec, config simtypes.Config) []simtypes.WeightedOperation {
+ simState := module.SimulationState{
+ AppParams: make(simtypes.AppParams),
+ Cdc: cdc,
+ }
+
+ if config.ParamsFile != "" {
+ bz, err := ioutil.ReadFile(config.ParamsFile)
+ if err != nil {
+ panic(err)
+ }
+
+ err = json.Unmarshal(bz, &simState.AppParams)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ simState.ParamChanges = app.SimulationManager().GenerateParamChanges(config.Seed)
+ simState.Contents = app.SimulationManager().GetProposalContents(simState)
+ return app.SimulationManager().WeightedOperations(simState)
+}
+
+// CheckExportSimulation exports the app state and simulation parameters to JSON
+// if the export paths are defined.
+func CheckExportSimulation(
+ app Gravity, config simtypes.Config, params simtypes.Params,
+) error {
+ if config.ExportStatePath != "" {
+ fmt.Println("exporting app state...")
+ exported, err := app.ExportAppStateAndValidators(false, nil)
+ if err != nil {
+ return err
+ }
+
+ if err := ioutil.WriteFile(config.ExportStatePath, []byte(exported.AppState), 0600); err != nil {
+ return err
+ }
+ }
+
+ if config.ExportParamsPath != "" {
+ fmt.Println("exporting simulation params...")
+ paramsBz, err := json.MarshalIndent(params, "", " ")
+ if err != nil {
+ return err
+ }
+
+ if err := ioutil.WriteFile(config.ExportParamsPath, paramsBz, 0600); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// PrintStats prints the corresponding statistics from the app DB.
+func PrintStats(db dbm.DB) {
+ fmt.Println("\nLevelDB Stats")
+ fmt.Println(db.Stats()["leveldb.stats"])
+ fmt.Println("LevelDB cached block size", db.Stats()["leveldb.cachedblock"])
+}
+
+// GetSimulationLog unmarshals the KVPair's Value to the corresponding type based on the
+// each's module store key and the prefix bytes of the KVPair's key.
+func GetSimulationLog(storeName string, sdr sdk.StoreDecoderRegistry, kvAs, kvBs []kv.Pair) (log string) {
+ for i := 0; i < len(kvAs); i++ {
+ if len(kvAs[i].Value) == 0 && len(kvBs[i].Value) == 0 {
+ // skip if the value doesn't have any bytes
+ continue
+ }
+
+ decoder, ok := sdr[storeName]
+ if ok {
+ log += decoder(kvAs[i], kvBs[i])
+ } else {
+ log += fmt.Sprintf("store A %X => %X\nstore B %X => %X\n", kvAs[i].Key, kvAs[i].Value, kvBs[i].Key, kvBs[i].Value)
+ }
+ }
+
+ return log
+}
diff --git a/module/buf.yaml b/module/buf.yaml
new file mode 100644
index 0000000..000dbef
--- /dev/null
+++ b/module/buf.yaml
@@ -0,0 +1,40 @@
+version: v1beta1
+
+build:
+ roots:
+ - proto
+ - third_party/proto
+ excludes:
+ - third_party/proto/google/protobuf
+lint:
+ use:
+ - DEFAULT
+ - COMMENTS
+ - FILE_LOWER_SNAKE_CASE
+ except:
+ - UNARY_RPC
+ - COMMENT_FIELD
+ - COMMENT_ENUM
+ - COMMENT_ENUM_VALUE
+ - COMMENT_RPC
+ - COMMENT_MESSAGE
+ - SERVICE_SUFFIX
+ - PACKAGE_VERSION_SUFFIX
+ - RPC_REQUEST_STANDARD_NAME
+ - RPC_RESPONSE_STANDARD_NAME
+ - RPC_REQUEST_RESPONSE_UNIQUE
+ ignore:
+ - tendermint
+ - gogoproto
+ - cosmos_proto
+ - google
+breaking:
+ use:
+ - FILE
+ except:
+ - FIELD_NO_DELETE
+ ignore:
+ - tendermint
+ - gogoproto
+ - cosmos_proto
+ - google
diff --git a/module/ci.Dockerfile b/module/ci.Dockerfile
new file mode 100644
index 0000000..4dd56b8
--- /dev/null
+++ b/module/ci.Dockerfile
@@ -0,0 +1,10 @@
+FROM ubuntu:latest
+
+# Install ca-certificates
+RUN apt get install ca-certificates
+
+EXPOSE 26656 26657 1317 9090
+
+COPY build/gravity /usr/bin/gravity
+
+CMD ["gravity", "start"]
\ No newline at end of file
diff --git a/module/cmd/gravity/cmd/eth_keys.go b/module/cmd/gravity/cmd/eth_keys.go
new file mode 100644
index 0000000..0543fc1
--- /dev/null
+++ b/module/cmd/gravity/cmd/eth_keys.go
@@ -0,0 +1,130 @@
+package cmd
+
+import (
+ "crypto/ecdsa"
+ "encoding/json"
+ "errors"
+ "fmt"
+
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ "github.com/cosmos/cosmos-sdk/client/keys"
+ "github.com/ethereum/go-ethereum/accounts/keystore"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/spf13/cobra"
+ "github.com/tendermint/tendermint/libs/cli"
+)
+
+const flagPassphrase = "passphrase"
+
+// Commands registers a sub-tree of commands to interact with
+// local private key storage.
+func Commands(defaultNodeHome string) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "eth_keys",
+ Short: "Manage your application's ethereum keys",
+ Long: `Keyring management commands. Generated by the official Ethereum go library.
+
+The keyring supports the following backends:
+ test Stores keys insecurely to disk. It does not prompt for a password to be unlocked
+ and it should be use only for testing purposes.
+`,
+ }
+
+ cmd.AddCommand(
+ AddKeyCommand(),
+ )
+
+ cmd.PersistentFlags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
+ cmd.PersistentFlags().String(flags.FlagKeyringDir, "", "The client Keyring directory; if omitted, the default 'home' directory will be used")
+ cmd.PersistentFlags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
+ cmd.PersistentFlags().String(cli.OutputFlag, "text", "Output format (text|json)")
+
+ return cmd
+}
+
+// AddKeyCommand defines a keys command to generate a key
+func AddKeyCommand() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "add",
+ Short: "Add an encrypted private ethereum key",
+ Long: `Derive a new private key and encrypt to disk.
+`,
+ RunE: runAddCmd,
+ }
+
+ cmd.Flags().String(flagPassphrase, "default", "Password used for ethereum key generation")
+ cmd.Flags().Bool(flags.FlagDryRun, false, "Perform action, but don't add key to local keystore")
+
+ cmd.SetOut(cmd.OutOrStdout())
+ cmd.SetErr(cmd.ErrOrStderr())
+
+ return cmd
+}
+
+type EthereumKeyOutput struct {
+ PublicKey string `json:"public_key"`
+ PrivateKey string `json:"private_key"`
+ Address string `json:"address"`
+}
+
+func runAddCmd(cmd *cobra.Command, args []string) error {
+ privateKey, err := crypto.GenerateKey()
+ if err != nil {
+ return err
+ }
+ privateKeyBytes := crypto.FromECDSA(privateKey)
+
+ publicKey := privateKey.Public()
+ publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
+ if !ok {
+ return errors.New("error casting public key to ECDSA")
+ }
+ publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
+
+ keyOutput := EthereumKeyOutput{
+ PrivateKey: hexutil.Encode(privateKeyBytes),
+ PublicKey: hexutil.Encode(publicKeyBytes),
+ Address: crypto.PubkeyToAddress(*publicKeyECDSA).Hex(),
+ }
+
+ if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); !dryRun {
+ clientCtx, err := client.GetClientQueryContext(cmd)
+ if err != nil {
+ return err
+ }
+ ks := keystore.NewKeyStore(clientCtx.KeyringDir, keystore.StandardScryptN, keystore.StandardScryptP)
+ passphrase, err := cmd.Flags().GetString(flagPassphrase)
+ if err != nil {
+ return err
+ }
+ if _, err := ks.ImportECDSA(privateKey, passphrase); err != nil {
+ return err
+ }
+ }
+
+ return printCreate(cmd, keyOutput)
+}
+
+func printCreate(cmd *cobra.Command, keyOutput EthereumKeyOutput) error {
+ output, _ := cmd.Flags().GetString(cli.OutputFlag)
+
+ switch output {
+ case keys.OutputFormatText:
+ cmd.PrintErrln()
+ cmd.Printf("private: %s \npublic: %s \naddress: %s\n", keyOutput.PrivateKey, keyOutput.PublicKey, keyOutput.Address)
+
+ case keys.OutputFormatJSON:
+ outputBytes, err := json.Marshal(keyOutput)
+ if err != nil {
+ return err
+ }
+ cmd.Println(string(outputBytes))
+
+ default:
+ return fmt.Errorf("invalid output format %s", output)
+ }
+
+ return nil
+}
diff --git a/module/cmd/gravity/cmd/genaccounts.go b/module/cmd/gravity/cmd/genaccounts.go
new file mode 100644
index 0000000..6b23dc9
--- /dev/null
+++ b/module/cmd/gravity/cmd/genaccounts.go
@@ -0,0 +1,180 @@
+package cmd
+
+import (
+ "bufio"
+ "encoding/json"
+ "errors"
+ "fmt"
+
+ "github.com/spf13/cobra"
+
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ "github.com/cosmos/cosmos-sdk/codec"
+ "github.com/cosmos/cosmos-sdk/crypto/keyring"
+ "github.com/cosmos/cosmos-sdk/server"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
+ authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
+ banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
+ "github.com/cosmos/cosmos-sdk/x/genutil"
+ genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
+)
+
+const (
+ flagVestingStart = "vesting-start-time"
+ flagVestingEnd = "vesting-end-time"
+ flagVestingAmt = "vesting-amount"
+)
+
+// AddGenesisAccountCmd returns add-genesis-account cobra Command.
+func AddGenesisAccountCmd(defaultNodeHome string) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]",
+ Short: "Add a genesis account to genesis.json",
+ Long: `Add a genesis account to genesis.json. The provided account must specify
+the account address or key name and a list of initial coins. If a key name is given,
+the address will be looked up in the local Keybase. The list of initial tokens must
+contain valid denominations. Accounts may optionally be supplied with vesting parameters.
+`,
+ Args: cobra.ExactArgs(2),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx := client.GetClientContextFromCmd(cmd)
+ depCdc := clientCtx.Codec
+ cdc := depCdc.(codec.Codec)
+
+ serverCtx := server.GetServerContextFromCmd(cmd)
+ config := serverCtx.Config
+
+ config.SetRoot(clientCtx.HomeDir)
+
+ addr, err := sdk.AccAddressFromBech32(args[0])
+ if err != nil {
+ inBuf := bufio.NewReader(cmd.InOrStdin())
+ keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
+
+ // attempt to lookup address from Keybase if no address was provided
+ kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf)
+ if err != nil {
+ return err
+ }
+
+ info, err := kb.Key(args[0])
+ if err != nil {
+ return fmt.Errorf("failed to get address from Keybase: %w", err)
+ }
+
+ addr = info.GetAddress()
+ }
+
+ coins, err := sdk.ParseCoinsNormalized(args[1])
+ if err != nil {
+ return fmt.Errorf("failed to parse coins: %w", err)
+ }
+
+ vestingStart, _ := cmd.Flags().GetInt64(flagVestingStart)
+ vestingEnd, _ := cmd.Flags().GetInt64(flagVestingEnd)
+ vestingAmtStr, _ := cmd.Flags().GetString(flagVestingAmt)
+
+ vestingAmt, err := sdk.ParseCoinsNormalized(vestingAmtStr)
+ if err != nil {
+ return fmt.Errorf("failed to parse vesting amount: %w", err)
+ }
+
+ // create concrete account type based on input parameters
+ var genAccount authtypes.GenesisAccount
+
+ balances := banktypes.Balance{Address: addr.String(), Coins: coins.Sort()}
+ baseAccount := authtypes.NewBaseAccount(addr, nil, 0, 0)
+
+ if !vestingAmt.IsZero() {
+ baseVestingAccount := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd)
+
+ if (balances.Coins.IsZero() && !baseVestingAccount.OriginalVesting.IsZero()) ||
+ baseVestingAccount.OriginalVesting.IsAnyGT(balances.Coins) {
+ return errors.New("vesting amount cannot be greater than total amount")
+ }
+
+ switch {
+ case vestingStart != 0 && vestingEnd != 0:
+ genAccount = authvesting.NewContinuousVestingAccountRaw(baseVestingAccount, vestingStart)
+
+ case vestingEnd != 0:
+ genAccount = authvesting.NewDelayedVestingAccountRaw(baseVestingAccount)
+
+ default:
+ return errors.New("invalid vesting parameters; must supply start and end time or end time")
+ }
+ } else {
+ genAccount = baseAccount
+ }
+
+ if err := genAccount.Validate(); err != nil {
+ return fmt.Errorf("failed to validate new genesis account: %w", err)
+ }
+
+ genFile := config.GenesisFile()
+ appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile)
+ if err != nil {
+ return fmt.Errorf("failed to unmarshal genesis state: %w", err)
+ }
+
+ authGenState := authtypes.GetGenesisStateFromAppState(cdc, appState)
+
+ accs, err := authtypes.UnpackAccounts(authGenState.Accounts)
+ if err != nil {
+ return fmt.Errorf("failed to get accounts from any: %w", err)
+ }
+
+ if accs.Contains(addr) {
+ return fmt.Errorf("cannot add account at existing address %s", addr)
+ }
+
+ // Add the new account to the set of genesis accounts and sanitize the
+ // accounts afterwards.
+ accs = append(accs, genAccount)
+ accs = authtypes.SanitizeGenesisAccounts(accs)
+
+ genAccs, err := authtypes.PackAccounts(accs)
+ if err != nil {
+ return fmt.Errorf("failed to convert accounts into any's: %w", err)
+ }
+ authGenState.Accounts = genAccs
+
+ authGenStateBz, err := cdc.MarshalJSON(&authGenState)
+ if err != nil {
+ return fmt.Errorf("failed to marshal auth genesis state: %w", err)
+ }
+
+ appState[authtypes.ModuleName] = authGenStateBz
+
+ bankGenState := banktypes.GetGenesisStateFromAppState(depCdc, appState)
+ bankGenState.Balances = append(bankGenState.Balances, balances)
+ bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances)
+
+ bankGenStateBz, err := cdc.MarshalJSON(bankGenState)
+ if err != nil {
+ return fmt.Errorf("failed to marshal bank genesis state: %w", err)
+ }
+
+ appState[banktypes.ModuleName] = bankGenStateBz
+
+ appStateJSON, err := json.Marshal(appState)
+ if err != nil {
+ return fmt.Errorf("failed to marshal application genesis state: %w", err)
+ }
+
+ genDoc.AppState = appStateJSON
+ return genutil.ExportGenesisFile(genDoc, genFile)
+ },
+ }
+
+ cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
+ cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
+ cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts")
+ cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
+ cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
+ flags.AddQueryFlagsToCmd(cmd)
+
+ return cmd
+}
diff --git a/module/cmd/gravity/cmd/genaccounts_test.go b/module/cmd/gravity/cmd/genaccounts_test.go
new file mode 100644
index 0000000..c11eab5
--- /dev/null
+++ b/module/cmd/gravity/cmd/genaccounts_test.go
@@ -0,0 +1,86 @@
+package cmd_test
+
+import (
+ "context"
+ "fmt"
+ "testing"
+
+ "github.com/spf13/viper"
+ "github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/libs/log"
+
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ "github.com/cosmos/cosmos-sdk/server"
+ "github.com/cosmos/cosmos-sdk/simapp"
+ simcmd "github.com/cosmos/cosmos-sdk/simapp/simd/cmd"
+ "github.com/cosmos/cosmos-sdk/testutil/testdata"
+ "github.com/cosmos/cosmos-sdk/types/module"
+ "github.com/cosmos/cosmos-sdk/x/genutil"
+ genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil"
+)
+
+var testMbm = module.NewBasicManager(genutil.AppModuleBasic{})
+
+func TestAddGenesisAccountCmd(t *testing.T) {
+ _, _, addr1 := testdata.KeyTestPubAddr()
+ tests := []struct {
+ name string
+ addr string
+ denom string
+ expectErr bool
+ }{
+ {
+ name: "invalid address",
+ addr: "",
+ denom: "1000atom",
+ expectErr: true,
+ },
+ {
+ name: "valid address",
+ addr: addr1.String(),
+ denom: "1000atom",
+ expectErr: false,
+ },
+ {
+ name: "multiple denoms",
+ addr: addr1.String(),
+ denom: "1000atom, 2000stake",
+ expectErr: false,
+ },
+ }
+
+ for _, tc := range tests {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+ home := t.TempDir()
+ logger := log.NewNopLogger()
+ cfg, err := genutiltest.CreateDefaultTendermintConfig(home)
+ require.NoError(t, err)
+
+ appCodec := simapp.MakeTestEncodingConfig().Marshaler
+ err = genutiltest.ExecInitCmd(testMbm, home, appCodec)
+ require.NoError(t, err)
+
+ serverCtx := server.NewContext(viper.New(), cfg, logger)
+ clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home)
+
+ ctx := context.Background()
+ ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
+ ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
+
+ cmd := simcmd.AddGenesisAccountCmd(home)
+ cmd.SetArgs([]string{
+ tc.addr,
+ tc.denom,
+ fmt.Sprintf("--%s=home", flags.FlagHome),
+ })
+
+ if tc.expectErr {
+ require.Error(t, cmd.ExecuteContext(ctx))
+ } else {
+ require.NoError(t, cmd.ExecuteContext(ctx))
+ }
+ })
+ }
+}
diff --git a/module/cmd/gravity/cmd/gentx.go b/module/cmd/gravity/cmd/gentx.go
new file mode 100644
index 0000000..3d61694
--- /dev/null
+++ b/module/cmd/gravity/cmd/gentx.go
@@ -0,0 +1,535 @@
+package cmd
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "runtime"
+ "sort"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+ cfg "github.com/tendermint/tendermint/config"
+ tmos "github.com/tendermint/tendermint/libs/os"
+ tmtypes "github.com/tendermint/tendermint/types"
+
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ "github.com/cosmos/cosmos-sdk/client/tx"
+ "github.com/cosmos/cosmos-sdk/codec"
+ "github.com/cosmos/cosmos-sdk/crypto/keyring"
+ "github.com/cosmos/cosmos-sdk/server"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/cosmos/cosmos-sdk/types/module"
+ "github.com/cosmos/cosmos-sdk/version"
+ authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
+ bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported"
+ "github.com/cosmos/cosmos-sdk/x/genutil"
+ "github.com/cosmos/cosmos-sdk/x/genutil/types"
+ "github.com/cosmos/cosmos-sdk/x/staking/client/cli"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+ gravitytypes "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+// GenTxCmd builds the application's gentx command.
+func GenTxCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfig, genBalIterator types.GenesisBalancesIterator, defaultNodeHome string) *cobra.Command {
+ ipDefault, _ := server.ExternalIP()
+ fsCreateValidator, defaultsDesc := cli.CreateValidatorMsgFlagSet(ipDefault)
+
+ cmd := &cobra.Command{
+ Use: "gentx [key_name] [amount] [eth-address] [orchestrator-address] [eth-sig]",
+ Short: "Generate a genesis tx carrying a self delegation, oracle key delegation and orchestrator key delegation",
+ Args: cobra.ExactArgs(5),
+ Long: fmt.Sprintf(`Generate a genesis transaction that creates a validator with a self-delegation, oracle key
+delegation and orchestrator key delegation that is signed by the key in the Keyring referenced by a given name. A node
+ID and Bech32 consensus pubkey may optionally be provided. If they are omitted, they will be retrieved from the
+priv_validator.json file. The following default parameters are included:
+ %s
+
+Example:
+$ %s gentx my-key-name 1000000stake 0x033030FEeBd93E3178487c35A9c8cA80874353C9 cosmos1ahx7f8wyertuus9r20284ej0asrs085case3kn 0x12...AF --home=/path/to/home/dir --keyring-backend=os --chain-id=test-chain-1 \
+ --moniker="myvalidator" \
+ --commission-max-change-rate=0.01 \
+ --commission-max-rate=1.0 \
+ --commission-rate=0.07 \
+ --details="..." \
+ --security-contact="..." \
+ --website="..."
+`, defaultsDesc, version.AppName,
+ ),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ serverCtx := server.GetServerContextFromCmd(cmd)
+ clientCtx, err := client.GetClientQueryContext(cmd)
+ if err != nil {
+ return err
+ }
+ cdc := clientCtx.Codec
+
+ config := serverCtx.Config
+ config.SetRoot(clientCtx.HomeDir)
+
+ nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(serverCtx.Config)
+ if err != nil {
+ return errors.Wrap(err, "failed to initialize node validator files")
+ }
+
+ // read --nodeID, if empty take it from priv_validator.json
+ if nodeIDString, _ := cmd.Flags().GetString(cli.FlagNodeID); nodeIDString != "" {
+ nodeID = nodeIDString
+ }
+
+ // read --pubkey, if empty take it from priv_validator.json
+ if pkStr, _ := cmd.Flags().GetString(cli.FlagPubKey); pkStr != "" {
+ if err := clientCtx.Codec.UnmarshalInterfaceJSON([]byte(pkStr), &valPubKey); err != nil {
+ return errors.Wrap(err, "failed to unmarshal validator public key")
+ }
+ }
+
+ genDoc, err := tmtypes.GenesisDocFromFile(config.GenesisFile())
+ if err != nil {
+ return errors.Wrapf(err, "failed to read genesis doc file %s", config.GenesisFile())
+ }
+
+ var genesisState map[string]json.RawMessage
+ if err = json.Unmarshal(genDoc.AppState, &genesisState); err != nil {
+ return errors.Wrap(err, "failed to unmarshal genesis state")
+ }
+
+ if err = mbm.ValidateGenesis(cdc, txEncCfg, genesisState); err != nil {
+ return errors.Wrap(err, "failed to validate genesis state")
+ }
+
+ inBuf := bufio.NewReader(cmd.InOrStdin())
+
+ name := args[0]
+ key, err := clientCtx.Keyring.Key(name)
+ if err != nil {
+ return errors.Wrapf(err, "failed to fetch '%s' from the keyring", name)
+ }
+
+ ethAddress := args[2]
+
+ if !common.IsHexAddress(ethAddress) {
+ return errors.Wrapf(gravitytypes.ErrInvalid, "invalid ethereum address")
+ }
+
+ orchAddress, err := sdk.AccAddressFromBech32(args[3])
+ if err != nil {
+ return errors.Wrapf(err, "failed to parse orchAddress(%s)", args[3])
+ }
+
+ moniker := config.Moniker
+ if m, _ := cmd.Flags().GetString(cli.FlagMoniker); m != "" {
+ moniker = m
+ }
+
+ // set flags for creating a gentx
+ createValCfg, err := cli.PrepareConfigForTxCreateValidator(cmd.Flags(), moniker, nodeID, genDoc.ChainID, valPubKey)
+ if err != nil {
+ return errors.Wrap(err, "error creating configuration to create validator msg")
+ }
+
+ amount := args[1]
+ coins, err := sdk.ParseCoinsNormalized(amount)
+ if err != nil {
+ return errors.Wrap(err, "failed to parse coins")
+ }
+
+ // validate validator account in genesis
+ if err = genutil.ValidateAccountInGenesis(genesisState, genBalIterator, key.GetAddress(), coins, cdc); err != nil {
+ return errors.Wrap(err, "failed to validate validator account in genesis")
+ }
+
+ // validate orchestrator account in genesis and warn if not found
+ if err = genutil.ValidateAccountInGenesis(genesisState, genBalIterator, orchAddress, coins, cdc); err != nil {
+ cmd.PrintErrf("orchestrator address not found in genesis file: %s\n", orchAddress)
+ return nil
+ }
+
+ txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags())
+ if err != nil {
+ return errors.Wrap(err, "error creating tx builder")
+ }
+
+ clientCtx = clientCtx.WithInput(inBuf).WithFromAddress(key.GetAddress())
+
+ // The following line comes from a discrepancy between the `gentx`
+ // and `create-validator` commands:
+ // - `gentx` expects amount as an arg,
+ // - `create-validator` expects amount as a required flag.
+ // ref: https://github.com/cosmos/cosmos-sdk/issues/8251
+ // Since gentx doesn't set the amount flag (which `create-validator`
+ // reads from), we copy the amount arg into the valCfg directly.
+ //
+ // Ideally, the `create-validator` command should take a validator
+ // config file instead of so many flags.
+ // ref: https://github.com/cosmos/cosmos-sdk/issues/8177
+ createValCfg.Amount = amount
+
+ // create a 'create-validator' message
+ txBldr, msg, err := cli.BuildCreateValidatorMsg(clientCtx, createValCfg, txFactory, true)
+ if err != nil {
+ return errors.Wrap(err, "failed to build create-validator message")
+ }
+
+ ethSig, err := hexutil.Decode(args[4])
+ if err != nil {
+ return err
+ }
+
+ delegateGravityMsg := &gravitytypes.MsgDelegateKeys{
+ ValidatorAddress: sdk.ValAddress(key.GetAddress()).String(),
+ OrchestratorAddress: orchAddress.String(),
+ EthereumAddress: ethAddress,
+ EthSignature: ethSig,
+ }
+
+ msgs := []sdk.Msg{msg, delegateGravityMsg}
+
+ if key.GetType() == keyring.TypeOffline || key.GetType() == keyring.TypeMulti {
+ cmd.PrintErrln("Offline key passed in. Use `tx sign` command to sign.")
+ return authclient.PrintUnsignedStdTx(txBldr, clientCtx, msgs)
+ }
+
+ // write the unsigned transaction to the buffer
+ w := bytes.NewBuffer([]byte{})
+ clientCtx = clientCtx.WithOutput(w)
+
+ if err = authclient.PrintUnsignedStdTx(txBldr, clientCtx, msgs); err != nil {
+ return errors.Wrap(err, "failed to print unsigned std tx")
+ }
+
+ // read the transaction
+ stdTx, err := readUnsignedGenTxFile(clientCtx, w)
+ if err != nil {
+ return errors.Wrap(err, "failed to read unsigned gen tx file")
+ }
+
+ // sign the transaction and write it to the output file
+ txBuilder, err := clientCtx.TxConfig.WrapTxBuilder(stdTx)
+ if err != nil {
+ return fmt.Errorf("error creating tx builder: %w", err)
+ }
+
+ err = authclient.SignTx(txFactory, clientCtx, name, txBuilder, true, true)
+ if err != nil {
+ return errors.Wrap(err, "failed to sign std tx")
+ }
+
+ outputDocument, _ := cmd.Flags().GetString(flags.FlagOutputDocument)
+ if outputDocument == "" {
+ outputDocument, err = makeOutputFilepath(config.RootDir, nodeID)
+ if err != nil {
+ return errors.Wrap(err, "failed to create output file path")
+ }
+ }
+
+ if err := writeSignedGenTx(clientCtx, outputDocument, stdTx); err != nil {
+ return errors.Wrap(err, "failed to write signed gen tx")
+ }
+
+ cmd.PrintErrf("Genesis transaction written to %q\n", outputDocument)
+ return nil
+ },
+ }
+
+ cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
+ cmd.Flags().String(flags.FlagOutputDocument, "", "Write the genesis transaction JSON document to the given file instead of the default location")
+ cmd.Flags().String(flags.FlagChainID, "", "The network chain ID")
+ cmd.Flags().AddFlagSet(fsCreateValidator)
+ flags.AddTxFlagsToCmd(cmd)
+
+ return cmd
+}
+
+func makeOutputFilepath(rootDir, nodeID string) (string, error) {
+ writePath := filepath.Join(rootDir, "config", "gentx")
+ if err := tmos.EnsureDir(writePath, 0700); err != nil {
+ return "", err
+ }
+
+ return filepath.Join(writePath, fmt.Sprintf("gentx-%v.json", nodeID)), nil
+}
+
+func readUnsignedGenTxFile(clientCtx client.Context, r io.Reader) (sdk.Tx, error) {
+ bz, err := ioutil.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+
+ aTx, err := clientCtx.TxConfig.TxJSONDecoder()(bz)
+ if err != nil {
+ return nil, err
+ }
+
+ return aTx, err
+}
+
+func writeSignedGenTx(clientCtx client.Context, outputDocument string, tx sdk.Tx) error {
+ outputFile, err := os.OpenFile(outputDocument, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
+ if err != nil {
+ return err
+ }
+ defer outputFile.Close()
+
+ json, err := clientCtx.TxConfig.TxJSONEncoder()(tx)
+ if err != nil {
+ return err
+ }
+
+ _, err = fmt.Fprintf(outputFile, "%s\n", json)
+
+ return err
+}
+
+const flagGenTxDir = "gentx-dir"
+
+// CollectGenTxsCmd - return the cobra command to collect genesis transactions
+func CollectGenTxsCmd(genBalIterator types.GenesisBalancesIterator, defaultNodeHome string) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "collect-gentxs",
+ Short: "Collect genesis txs and output a genesis.json file",
+ RunE: func(cmd *cobra.Command, _ []string) error {
+ serverCtx := server.GetServerContextFromCmd(cmd)
+ config := serverCtx.Config
+
+ clientCtx := client.GetClientContextFromCmd(cmd)
+ cdc := clientCtx.Codec
+
+ config.SetRoot(clientCtx.HomeDir)
+
+ nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(config)
+ if err != nil {
+ return errors.Wrap(err, "failed to initialize node validator files")
+ }
+
+ genDoc, err := tmtypes.GenesisDocFromFile(config.GenesisFile())
+ if err != nil {
+ return errors.Wrap(err, "failed to read genesis doc from file")
+ }
+
+ genTxDir, _ := cmd.Flags().GetString(flagGenTxDir)
+ genTxsDir := genTxDir
+ if genTxsDir == "" {
+ genTxsDir = filepath.Join(config.RootDir, "config", "gentx")
+ }
+
+ toPrint := newPrintInfo(config.Moniker, genDoc.ChainID, nodeID, genTxsDir, json.RawMessage(""))
+ initCfg := types.NewInitConfig(genDoc.ChainID, genTxsDir, nodeID, valPubKey)
+
+ appMessage, err := GenAppStateFromConfig(cdc,
+ clientCtx.TxConfig,
+ config, initCfg, *genDoc, genBalIterator)
+ if err != nil {
+ return errors.Wrap(err, "failed to get genesis app state from config")
+ }
+
+ toPrint.AppMessage = appMessage
+
+ return displayInfo(toPrint)
+ },
+ }
+
+ cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
+ cmd.Flags().String(flagGenTxDir, "", "override default \"gentx\" directory from which collect and execute genesis transactions; default [--home]/config/gentx/")
+
+ return cmd
+}
+
+func displayInfo(info printInfo) error {
+ out, err := json.MarshalIndent(info, "", " ")
+ if err != nil {
+ return err
+ }
+
+ _, err = fmt.Fprintf(os.Stderr, "%s\n", string(sdk.MustSortJSON(out)))
+
+ return err
+}
+
+type printInfo struct {
+ Moniker string `json:"moniker" yaml:"moniker"`
+ ChainID string `json:"chain_id" yaml:"chain_id"`
+ NodeID string `json:"node_id" yaml:"node_id"`
+ GenTxsDir string `json:"gentxs_dir" yaml:"gentxs_dir"`
+ AppMessage json.RawMessage `json:"app_message" yaml:"app_message"`
+}
+
+func newPrintInfo(moniker, chainID, nodeID, genTxsDir string, appMessage json.RawMessage) printInfo {
+ return printInfo{
+ Moniker: moniker,
+ ChainID: chainID,
+ NodeID: nodeID,
+ GenTxsDir: genTxsDir,
+ AppMessage: appMessage,
+ }
+}
+
+// GenAppStateFromConfig gets the genesis app state from the config
+func GenAppStateFromConfig(cdc codec.JSONCodec, txEncodingConfig client.TxEncodingConfig,
+ config *cfg.Config, initCfg types.InitConfig, genDoc tmtypes.GenesisDoc, genBalIterator types.GenesisBalancesIterator,
+) (appState json.RawMessage, err error) {
+
+ // process genesis transactions, else create default genesis.json
+ appGenTxs, persistentPeers, err := CollectTxs(
+ cdc, txEncodingConfig.TxJSONDecoder(), config.Moniker, initCfg.GenTxsDir, genDoc, genBalIterator,
+ )
+ if err != nil {
+ return appState, err
+ }
+
+ config.P2P.PersistentPeers = persistentPeers
+ cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
+
+ // if there are no gen txs to be processed, return the default empty state
+ if len(appGenTxs) == 0 {
+ return appState, errors.New("there must be at least one genesis tx")
+ }
+
+ // create the app state
+ appGenesisState, err := types.GenesisStateFromGenDoc(genDoc)
+ if err != nil {
+ return appState, err
+ }
+
+ appGenesisState, err = genutil.SetGenTxsInAppGenesisState(cdc, txEncodingConfig.TxJSONEncoder(), appGenesisState, appGenTxs)
+ if err != nil {
+ return appState, err
+ }
+
+ appState, err = json.MarshalIndent(appGenesisState, "", " ")
+ if err != nil {
+ return appState, err
+ }
+
+ genDoc.AppState = appState
+ err = genutil.ExportGenesisFile(&genDoc, config.GenesisFile())
+
+ return appState, err
+}
+
+// CollectTxs processes and validates application's genesis Txs and returns
+// the list of appGenTxs, and persistent peers required to generate genesis.json.
+func CollectTxs(cdc codec.JSONCodec, txJSONDecoder sdk.TxDecoder, moniker, genTxsDir string,
+ genDoc tmtypes.GenesisDoc, genBalIterator types.GenesisBalancesIterator,
+) (appGenTxs []sdk.Tx, persistentPeers string, err error) {
+ // prepare a map of all balances in genesis state to then validate
+ // against the validators addresses
+ var appState map[string]json.RawMessage
+ if err := json.Unmarshal(genDoc.AppState, &appState); err != nil {
+ return appGenTxs, persistentPeers, err
+ }
+
+ var fos []os.FileInfo
+ fos, err = ioutil.ReadDir(genTxsDir)
+ if err != nil {
+ return appGenTxs, persistentPeers, err
+ }
+
+ balancesMap := make(map[string]bankexported.GenesisBalance)
+
+ genBalIterator.IterateGenesisBalances(
+ cdc, appState,
+ func(balance bankexported.GenesisBalance) (stop bool) {
+ balancesMap[balance.GetAddress().String()] = balance
+ return false
+ },
+ )
+
+ // addresses and IPs (and port) validator server info
+ var addressesIPs []string
+
+ for _, fo := range fos {
+ if fo.IsDir() {
+ continue
+ }
+ if !strings.HasSuffix(fo.Name(), ".json") {
+ continue
+ }
+
+ // get the genTx
+ jsonRawTx, err := ioutil.ReadFile(filepath.Join(genTxsDir, fo.Name()))
+ if err != nil {
+ return appGenTxs, persistentPeers, err
+ }
+
+ var genTx sdk.Tx
+ if genTx, err = txJSONDecoder(jsonRawTx); err != nil {
+ return appGenTxs, persistentPeers, err
+ }
+
+ appGenTxs = append(appGenTxs, genTx)
+
+ // the memo flag is used to store
+ // the ip and node-id, for example this may be:
+ // "528fd3df22b31f4969b05652bfe8f0fe921321d5@192.168.2.37:26656"
+
+ memoTx, ok := genTx.(sdk.TxWithMemo)
+ if !ok {
+ return appGenTxs, persistentPeers, fmt.Errorf("expected TxWithMemo, got %T", genTx)
+ }
+ nodeAddrIP := memoTx.GetMemo()
+ if len(nodeAddrIP) == 0 {
+ return appGenTxs, persistentPeers, fmt.Errorf("failed to find node's address and IP in %s", fo.Name())
+ }
+
+ // genesis transactions must be single-message
+ msgs := genTx.GetMsgs()
+
+ // TODO abstract out staking message validation back to staking
+ msg := msgs[0].(*stakingtypes.MsgCreateValidator)
+
+ // validate delegator and validator addresses and funds against the accounts in the state
+ delAddr := msg.DelegatorAddress
+ valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
+ if err != nil {
+ return appGenTxs, persistentPeers, err
+ }
+
+ delBal, delOk := balancesMap[delAddr]
+ if !delOk {
+ _, file, no, ok := runtime.Caller(1)
+ if ok {
+ fmt.Printf("CollectTxs-1, called from %s#%d\n", file, no)
+ }
+
+ return appGenTxs, persistentPeers, fmt.Errorf("account %s balance not in genesis state: %+v", delAddr, balancesMap)
+ }
+
+ _, valOk := balancesMap[sdk.AccAddress(valAddr).String()]
+ if !valOk {
+ _, file, no, ok := runtime.Caller(1)
+ if ok {
+ fmt.Printf("CollectTxs-2, called from %s#%d - %s\n", file, no, sdk.AccAddress(msg.ValidatorAddress).String())
+ }
+ return appGenTxs, persistentPeers, fmt.Errorf("account %s balance not in genesis state: %+v", valAddr, balancesMap)
+ }
+
+ if delBal.GetCoins().AmountOf(msg.Value.Denom).LT(msg.Value.Amount) {
+ return appGenTxs, persistentPeers, fmt.Errorf(
+ "insufficient fund for delegation %v: %v < %v",
+ delBal.GetAddress().String(), delBal.GetCoins().AmountOf(msg.Value.Denom), msg.Value.Amount,
+ )
+ }
+
+ // TODO: validate msgdelegatekeys
+
+ // exclude itself from persistent peers
+ if msg.Description.Moniker != moniker {
+ addressesIPs = append(addressesIPs, nodeAddrIP)
+ }
+ }
+
+ sort.Strings(addressesIPs)
+ persistentPeers = strings.Join(addressesIPs, ",")
+
+ return appGenTxs, persistentPeers, nil
+}
diff --git a/module/cmd/gravity/cmd/root.go b/module/cmd/gravity/cmd/root.go
new file mode 100644
index 0000000..f4856aa
--- /dev/null
+++ b/module/cmd/gravity/cmd/root.go
@@ -0,0 +1,243 @@
+package cmd
+
+import (
+ "context"
+ "io"
+ "os"
+ "path/filepath"
+
+ "github.com/cosmos/cosmos-sdk/baseapp"
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/client/debug"
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ "github.com/cosmos/cosmos-sdk/client/keys"
+ "github.com/cosmos/cosmos-sdk/client/rpc"
+ "github.com/cosmos/cosmos-sdk/server"
+ servertypes "github.com/cosmos/cosmos-sdk/server/types"
+ "github.com/cosmos/cosmos-sdk/snapshots"
+ "github.com/cosmos/cosmos-sdk/store"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
+ "github.com/cosmos/cosmos-sdk/x/auth/types"
+ vestingcli "github.com/cosmos/cosmos-sdk/x/auth/vesting/client/cli"
+ banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
+ "github.com/cosmos/cosmos-sdk/x/crisis"
+ genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
+ "github.com/spf13/cast"
+ "github.com/spf13/cobra"
+ tmcli "github.com/tendermint/tendermint/libs/cli"
+ "github.com/tendermint/tendermint/libs/log"
+ dbm "github.com/tendermint/tm-db"
+
+ "github.com/cosmos/gravity-bridge/module/app"
+ "github.com/cosmos/gravity-bridge/module/app/params"
+)
+
+// NewRootCmd creates a new root command for simd. It is called once in the
+// main function.
+func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
+ app.SetAddressConfig()
+
+ encodingConfig := app.MakeEncodingConfig()
+ initClientCtx := client.Context{}.
+ WithCodec(encodingConfig.Marshaler).
+ WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
+ WithTxConfig(encodingConfig.TxConfig).
+ WithLegacyAmino(encodingConfig.Amino).
+ WithInput(os.Stdin).
+ WithAccountRetriever(types.AccountRetriever{}).
+ WithBroadcastMode(flags.BroadcastBlock).
+ WithHomeDir(app.DefaultNodeHome)
+
+ rootCmd := &cobra.Command{
+ Use: "gravity",
+ Short: "Stargate Gravity App",
+ PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
+ if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil {
+ return err
+ }
+
+ return server.InterceptConfigsPreRunHandler(cmd, "", nil)
+ },
+ }
+
+ initRootCmd(rootCmd, encodingConfig)
+
+ return rootCmd, encodingConfig
+}
+
+// Execute executes the root command.
+func Execute(rootCmd *cobra.Command) error {
+ // Create and set a client.Context on the command's Context. During the pre-run
+ // of the root command, a default initialized client.Context is provided to
+ // seed child command execution with values such as AccountRetriver, Keyring,
+ // and a Tendermint RPC. This requires the use of a pointer reference when
+ // getting and setting the client.Context. Ideally, we utilize
+ // https://github.com/spf13/cobra/pull/1118.
+ srvCtx := server.NewDefaultContext()
+ ctx := context.Background()
+ ctx = context.WithValue(ctx, client.ClientContextKey, &client.Context{})
+ ctx = context.WithValue(ctx, server.ServerContextKey, srvCtx)
+
+ rootCmd.PersistentFlags().String("log_level", "info", "The logging level in the format of :,...")
+
+ executor := tmcli.PrepareBaseCmd(rootCmd, "", app.DefaultNodeHome)
+ return executor.ExecuteContext(ctx)
+}
+
+func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
+ rootCmd.AddCommand(
+ genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
+ CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
+ genutilcli.MigrateGenesisCmd(),
+ GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
+ genutilcli.ValidateGenesisCmd(app.ModuleBasics),
+ AddGenesisAccountCmd(app.DefaultNodeHome),
+ tmcli.NewCompletionCmd(rootCmd, true),
+ testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}),
+ debug.Cmd(),
+ )
+
+ a := appCreator{encodingConfig}
+ server.AddCommands(rootCmd, app.DefaultNodeHome, a.newApp, a.appExport, addModuleInitFlags)
+
+ // add keybase, auxiliary RPC, query, and tx child commands
+ rootCmd.AddCommand(
+ rpc.StatusCommand(),
+ queryCommand(),
+ txCommand(),
+ keys.Commands(app.DefaultNodeHome),
+ Commands(app.DefaultNodeHome),
+ )
+}
+
+func addModuleInitFlags(startCmd *cobra.Command) {
+ crisis.AddModuleInitFlags(startCmd)
+}
+
+func queryCommand() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "query",
+ Aliases: []string{"q"},
+ Short: "Querying subcommands",
+ DisableFlagParsing: true,
+ SuggestionsMinimumDistance: 2,
+ RunE: client.ValidateCmd,
+ }
+
+ cmd.AddCommand(
+ authcmd.GetAccountCmd(),
+ rpc.ValidatorCommand(),
+ rpc.BlockCommand(),
+ authcmd.QueryTxsByEventsCmd(),
+ authcmd.QueryTxCmd(),
+ )
+
+ app.ModuleBasics.AddQueryCommands(cmd)
+ cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID")
+
+ return cmd
+}
+
+func txCommand() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "tx",
+ Short: "Transactions subcommands",
+ DisableFlagParsing: true,
+ SuggestionsMinimumDistance: 2,
+ RunE: client.ValidateCmd,
+ }
+
+ cmd.AddCommand(
+ authcmd.GetSignCommand(),
+ authcmd.GetSignBatchCommand(),
+ authcmd.GetMultiSignCommand(),
+ authcmd.GetValidateSignaturesCommand(),
+ flags.LineBreak,
+ authcmd.GetBroadcastCommand(),
+ authcmd.GetEncodeCommand(),
+ authcmd.GetDecodeCommand(),
+ flags.LineBreak,
+ vestingcli.GetTxCmd(),
+ )
+
+ app.ModuleBasics.AddTxCommands(cmd)
+ cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID")
+
+ return cmd
+}
+
+type appCreator struct {
+ encCfg params.EncodingConfig
+}
+
+func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
+ var cache sdk.MultiStorePersistentCache
+
+ if cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) {
+ cache = store.NewCommitKVStoreCacheManager()
+ }
+
+ skipUpgradeHeights := make(map[int64]bool)
+ for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) {
+ skipUpgradeHeights[int64(h)] = true
+ }
+
+ pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts)
+ if err != nil {
+ panic(err)
+ }
+
+ snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots")
+ snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir)
+ if err != nil {
+ panic(err)
+ }
+ snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir)
+ if err != nil {
+ panic(err)
+ }
+
+ return app.NewGravityApp(
+ logger, db, traceStore, true, skipUpgradeHeights,
+ cast.ToString(appOpts.Get(flags.FlagHome)),
+ cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)),
+ a.encCfg,
+ appOpts,
+ baseapp.SetPruning(pruningOpts),
+ baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))),
+ baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))),
+ baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(server.FlagHaltTime))),
+ baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))),
+ baseapp.SetInterBlockCache(cache),
+ baseapp.SetTrace(cast.ToBool(appOpts.Get(server.FlagTrace))),
+ baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))),
+ baseapp.SetSnapshotStore(snapshotStore),
+ baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(server.FlagStateSyncSnapshotInterval))),
+ baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(server.FlagStateSyncSnapshotKeepRecent))),
+ )
+}
+
+func (a appCreator) appExport(
+ logger log.Logger,
+ db dbm.DB,
+ traceStore io.Writer,
+ height int64,
+ forZeroHeight bool,
+ jailAllowedAddrs []string,
+ appOpts servertypes.AppOptions,
+) (servertypes.ExportedApp, error) {
+
+ var gravity *app.Gravity
+ if height != -1 {
+ gravity = app.NewGravityApp(logger, db, traceStore, false, map[int64]bool{}, "", uint(1), a.encCfg, appOpts)
+
+ if err := gravity.LoadHeight(height); err != nil {
+ return servertypes.ExportedApp{}, err
+ }
+ } else {
+ gravity = app.NewGravityApp(logger, db, traceStore, true, map[int64]bool{}, "", uint(1), a.encCfg, appOpts)
+ }
+
+ return gravity.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs)
+}
diff --git a/module/cmd/gravity/cmd/root_test.go b/module/cmd/gravity/cmd/root_test.go
new file mode 100644
index 0000000..2cc050d
--- /dev/null
+++ b/module/cmd/gravity/cmd/root_test.go
@@ -0,0 +1,68 @@
+package cmd
+
+import (
+ "bytes"
+ "encoding/json"
+ "strings"
+ "testing"
+
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ "github.com/cosmos/cosmos-sdk/client/keys"
+ "github.com/cosmos/cosmos-sdk/crypto/hd"
+ "github.com/cosmos/cosmos-sdk/crypto/keyring"
+ "github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/libs/cli"
+)
+
+type KeyOutput struct {
+ Name string `json:"name"`
+ Type string `json:"type"`
+ Address string `json:"address"`
+ PubKey string `json:"pubkey"`
+}
+
+func TestKeyGen(t *testing.T) {
+ mnemonic := "weasel lunch attack blossom tone drum unfair worry risk level negative height sight nation inside task oyster client shiver aware neck mansion gun dune"
+
+ // generate key from binary
+ keyCmd := keys.AddKeyCommand()
+ keyCmd.Flags().String(cli.OutputFlag, "json", "output flag")
+ keyCmd.Flags().String(flags.FlagKeyringBackend, keyring.BackendTest, "Select keyring's backend (os|file|kwallet|pass|test|memory)")
+ keyCmd.SetArgs([]string{
+ "--dry-run=true",
+ "--output=json",
+ "--recover=true",
+ "orch",
+ })
+ keyCmd.SetIn(strings.NewReader(mnemonic + "\n"))
+
+ buf := bytes.NewBuffer(nil)
+ keyCmd.SetOut(buf)
+ keyCmd.SetErr(buf)
+
+ err := Execute(keyCmd)
+ require.NoError(t, err)
+
+ var key KeyOutput
+ output := buf.Bytes()
+ t.Log("outputs: ", string(output))
+ err = json.Unmarshal(output, &key)
+ require.NoError(t, err)
+
+ // generate a memory key directly
+ kb, err := keyring.New("testnet", keyring.BackendMemory, "", nil)
+ if err != nil {
+ return
+ }
+
+ keyringAlgos, _ := kb.SupportedAlgorithms()
+ algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos)
+ if err != nil {
+ return
+ }
+
+ account, err := kb.NewAccount("", mnemonic, "", "m/44'/118'/0'/0/0", algo)
+ require.NoError(t, err)
+
+ require.Equal(t, account.GetAddress().String(), key.Address)
+}
diff --git a/module/cmd/gravity/cmd/testnet.go b/module/cmd/gravity/cmd/testnet.go
new file mode 100644
index 0000000..6a3df64
--- /dev/null
+++ b/module/cmd/gravity/cmd/testnet.go
@@ -0,0 +1,397 @@
+package cmd
+
+// DONTCOVER
+
+import (
+ "bufio"
+ "encoding/json"
+ "fmt"
+ "net"
+ "os"
+ "path/filepath"
+
+ crypto "github.com/cosmos/cosmos-sdk/crypto/types"
+ "github.com/spf13/cobra"
+ tmconfig "github.com/tendermint/tendermint/config"
+ tmos "github.com/tendermint/tendermint/libs/os"
+ tmrand "github.com/tendermint/tendermint/libs/rand"
+ "github.com/tendermint/tendermint/types"
+ tmtime "github.com/tendermint/tendermint/types/time"
+
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ "github.com/cosmos/cosmos-sdk/client/tx"
+ "github.com/cosmos/cosmos-sdk/crypto/hd"
+ "github.com/cosmos/cosmos-sdk/crypto/keyring"
+ "github.com/cosmos/cosmos-sdk/server"
+ srvconfig "github.com/cosmos/cosmos-sdk/server/config"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/cosmos/cosmos-sdk/types/module"
+ authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
+ banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
+ "github.com/cosmos/cosmos-sdk/x/genutil"
+ genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+)
+
+var (
+ flagNodeDirPrefix = "node-dir-prefix"
+ flagNumValidators = "v"
+ flagOutputDir = "output-dir"
+ flagNodeDaemonHome = "node-daemon-home"
+ flagStartingIPAddress = "starting-ip-address"
+)
+
+// get cmd to initialize all files for tendermint testnet and application
+func testnetCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "testnet",
+ Short: "Initialize files for a simapp testnet",
+ Long: `testnet will create "v" number of directories and populate each with
+necessary files (private validator, genesis, config, etc.).
+
+Note, strict routability for addresses is turned off in the config file.
+
+Example:
+ simd testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2
+ `,
+ RunE: func(cmd *cobra.Command, _ []string) error {
+ clientCtx := client.GetClientContextFromCmd(cmd)
+
+ serverCtx := server.GetServerContextFromCmd(cmd)
+ config := serverCtx.Config
+
+ outputDir, _ := cmd.Flags().GetString(flagOutputDir)
+ keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
+ chainID, _ := cmd.Flags().GetString(flags.FlagChainID)
+ minGasPrices, _ := cmd.Flags().GetString(server.FlagMinGasPrices)
+ nodeDirPrefix, _ := cmd.Flags().GetString(flagNodeDirPrefix)
+ nodeDaemonHome, _ := cmd.Flags().GetString(flagNodeDaemonHome)
+ startingIPAddress, _ := cmd.Flags().GetString(flagStartingIPAddress)
+ numValidators, _ := cmd.Flags().GetInt(flagNumValidators)
+ algo, _ := cmd.Flags().GetString(flags.FlagKeyAlgorithm)
+
+ return InitTestnet(
+ clientCtx, cmd, config, mbm, genBalIterator, outputDir, chainID, minGasPrices,
+ nodeDirPrefix, nodeDaemonHome, startingIPAddress, keyringBackend, algo, numValidators,
+ )
+ },
+ }
+
+ cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with")
+ cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", "Directory to store initialization data for the testnet")
+ cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)")
+ cmd.Flags().String(flagNodeDaemonHome, "simd", "Home directory of the node's daemon configuration")
+ cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
+ cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
+ cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)")
+ cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
+ cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for")
+
+ return cmd
+}
+
+const nodeDirPerm = 0755
+
+// InitTestnet initializes the testnet
+func InitTestnet(
+ clientCtx client.Context,
+ cmd *cobra.Command,
+ nodeConfig *tmconfig.Config,
+ mbm module.BasicManager,
+ genBalIterator banktypes.GenesisBalancesIterator,
+ outputDir,
+ chainID,
+ minGasPrices,
+ nodeDirPrefix,
+ nodeDaemonHome,
+ startingIPAddress,
+ keyringBackend,
+ algoStr string,
+ numValidators int,
+) error {
+
+ if chainID == "" {
+ chainID = "chain-" + tmrand.NewRand().Str(6)
+ }
+
+ nodeIDs := make([]string, numValidators)
+ valPubKeys := make([]crypto.PubKey, numValidators)
+
+ simappConfig := srvconfig.DefaultConfig()
+ simappConfig.MinGasPrices = minGasPrices
+ simappConfig.API.Enable = true
+ simappConfig.Telemetry.Enabled = true
+ simappConfig.Telemetry.PrometheusRetentionTime = 60
+ simappConfig.Telemetry.EnableHostnameLabel = false
+ simappConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", chainID}}
+
+ var (
+ genAccounts []authtypes.GenesisAccount
+ genBalances []banktypes.Balance
+ genFiles []string
+ )
+
+ inBuf := bufio.NewReader(cmd.InOrStdin())
+ // generate private keys, node IDs, and initial transactions
+ for i := 0; i < numValidators; i++ {
+ nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
+ nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)
+ gentxsDir := filepath.Join(outputDir, "gentxs")
+
+ nodeConfig.SetRoot(nodeDir)
+ nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657"
+
+ if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil {
+ _ = os.RemoveAll(outputDir)
+ return err
+ }
+
+ nodeConfig.Moniker = nodeDirName
+
+ ip, err := getIP(i, startingIPAddress)
+ if err != nil {
+ _ = os.RemoveAll(outputDir)
+ return err
+ }
+
+ nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig)
+ if err != nil {
+ _ = os.RemoveAll(outputDir)
+ return err
+ }
+
+ memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
+ genFiles = append(genFiles, nodeConfig.GenesisFile())
+
+ kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, nodeDir, inBuf)
+ if err != nil {
+ return err
+ }
+
+ keyringAlgos, _ := kb.SupportedAlgorithms()
+ algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos)
+ if err != nil {
+ return err
+ }
+
+ addr, secret, err := server.GenerateSaveCoinKey(kb, nodeDirName, true, algo)
+ if err != nil {
+ _ = os.RemoveAll(outputDir)
+ return err
+ }
+
+ info := map[string]string{"secret": secret}
+
+ cliPrint, err := json.Marshal(info)
+ if err != nil {
+ return err
+ }
+
+ // save private key seed words
+ if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil {
+ return err
+ }
+
+ accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction)
+ accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction)
+ coins := sdk.Coins{
+ sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), accTokens),
+ sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens),
+ }
+
+ genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()})
+ genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))
+
+ valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction)
+ createValMsg, err := stakingtypes.NewMsgCreateValidator(
+ sdk.ValAddress(addr),
+ valPubKeys[i],
+ sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
+ stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
+ stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()),
+ sdk.OneInt(),
+ )
+ if err != nil {
+ return err
+ }
+
+ txBuilder := clientCtx.TxConfig.NewTxBuilder()
+ if err = txBuilder.SetMsgs(createValMsg); err != nil {
+ return err
+ }
+
+ txBuilder.SetMemo(memo)
+
+ txFactory := tx.Factory{}
+ txFactory = txFactory.
+ WithChainID(chainID).
+ WithMemo(memo).
+ WithKeybase(kb).
+ WithTxConfig(clientCtx.TxConfig)
+
+ if err = tx.Sign(txFactory, nodeDirName, txBuilder, true); err != nil {
+ return err
+ }
+
+ txBz, err := clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
+ if err != nil {
+ return err
+ }
+
+ if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil {
+ return err
+ }
+
+ srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), simappConfig)
+ }
+
+ if err := initGenFiles(clientCtx, mbm, chainID, genAccounts, genBalances, genFiles, numValidators); err != nil {
+ return err
+ }
+
+ err := collectGenFiles(
+ clientCtx, nodeConfig, chainID, nodeIDs, valPubKeys, numValidators,
+ outputDir, nodeDirPrefix, nodeDaemonHome, genBalIterator,
+ )
+ if err != nil {
+ return err
+ }
+
+ cmd.PrintErrf("Successfully initialized %d node directories\n", numValidators)
+ return nil
+}
+
+func initGenFiles(
+ clientCtx client.Context, mbm module.BasicManager, chainID string,
+ genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance,
+ genFiles []string, numValidators int,
+) error {
+
+ appGenState := mbm.DefaultGenesis(clientCtx.Codec)
+
+ // set the accounts in the genesis state
+ var authGenState authtypes.GenesisState
+ clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState)
+
+ accounts, err := authtypes.PackAccounts(genAccounts)
+ if err != nil {
+ return err
+ }
+
+ authGenState.Accounts = accounts
+ appGenState[authtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&authGenState)
+
+ // set the balances in the genesis state
+ var bankGenState banktypes.GenesisState
+ clientCtx.Codec.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState)
+
+ bankGenState.Balances = genBalances
+ appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState)
+
+ appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ")
+ if err != nil {
+ return err
+ }
+
+ genDoc := types.GenesisDoc{
+ ChainID: chainID,
+ AppState: appGenStateJSON,
+ Validators: nil,
+ }
+
+ // generate empty genesis files for each validator and save
+ for i := 0; i < numValidators; i++ {
+ if err := genDoc.SaveAs(genFiles[i]); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func collectGenFiles(
+ clientCtx client.Context, nodeConfig *tmconfig.Config, chainID string,
+ nodeIDs []string, valPubKeys []crypto.PubKey, numValidators int,
+ outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator,
+) error {
+
+ var appState json.RawMessage
+ genTime := tmtime.Now()
+
+ for i := 0; i < numValidators; i++ {
+ nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
+ nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)
+ gentxsDir := filepath.Join(outputDir, "gentxs")
+ nodeConfig.Moniker = nodeDirName
+
+ nodeConfig.SetRoot(nodeDir)
+
+ nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
+ initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey)
+
+ genDoc, err := types.GenesisDocFromFile(nodeConfig.GenesisFile())
+ if err != nil {
+ return err
+ }
+
+ nodeAppState, err := genutil.GenAppStateFromConfig(clientCtx.Codec, clientCtx.TxConfig, nodeConfig, initCfg, *genDoc, genBalIterator)
+ if err != nil {
+ return err
+ }
+
+ if appState == nil {
+ // set the canonical application state (they should not differ)
+ appState = nodeAppState
+ }
+
+ genFile := nodeConfig.GenesisFile()
+
+ // overwrite each validator's genesis file to have a canonical genesis time
+ if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func getIP(i int, startingIPAddr string) (ip string, err error) {
+ if len(startingIPAddr) == 0 {
+ ip, err = server.ExternalIP()
+ if err != nil {
+ return "", err
+ }
+ return ip, nil
+ }
+ return calculateIP(startingIPAddr, i)
+}
+
+func calculateIP(ip string, i int) (string, error) {
+ ipv4 := net.ParseIP(ip).To4()
+ if ipv4 == nil {
+ return "", fmt.Errorf("%v: non ipv4 address", ip)
+ }
+
+ for j := 0; j < i; j++ {
+ ipv4[3]++
+ }
+
+ return ipv4.String(), nil
+}
+
+func writeFile(name string, dir string, contents []byte) error {
+ writePath := filepath.Join(dir)
+ file := filepath.Join(writePath, name)
+
+ err := tmos.EnsureDir(writePath, 0755)
+ if err != nil {
+ return err
+ }
+
+ err = tmos.WriteFile(file, contents, 0644)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/module/cmd/gravity/main.go b/module/cmd/gravity/main.go
new file mode 100644
index 0000000..75c611f
--- /dev/null
+++ b/module/cmd/gravity/main.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+ "os"
+
+ "github.com/cosmos/cosmos-sdk/server"
+ "github.com/cosmos/gravity-bridge/module/cmd/gravity/cmd"
+)
+
+func main() {
+ rootCmd, _ := cmd.NewRootCmd()
+ if err := cmd.Execute(rootCmd); err != nil {
+ switch e := err.(type) {
+ case server.ErrorCode:
+ os.Exit(e.Code)
+ default:
+ os.Exit(1)
+ }
+ }
+}
diff --git a/module/contrib/local/01-bootstrap_attestation.sh b/module/contrib/local/01-bootstrap_attestation.sh
new file mode 100755
index 0000000..b94605e
--- /dev/null
+++ b/module/contrib/local/01-bootstrap_attestation.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+set -eu
+
+echo "## Add ETH key"
+gravitycli tx gravity update-eth-addr 0xb8662f35f9de8720424e82b232e8c98d15399490adae9ca993f5ef1dc4883690 --from validator --chain-id=testing -b block -y
+
+echo "## Submit observation"
+nonce=$(date +%s) # use unix timestamp as fake nonce
+# chain id: 1
+# bridge contract address: 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf
+# erc20 token contract address: 0x7c2c195cd6d34b8f845992d380aadb2730bb9c6f
+# erc20 symbol: ALX
+# amount: 100
+# gravitycli tx gravity observed bootstrap [eth chain id] [eth contract address] [nonce] [allowed_validators] [validator_powers] [gravity_id] [start_threshold]
+gravitycli tx gravity observed bootstrap 1 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf "$nonce" "0xc783df8a850f42e7f7e57013759c285caa701eb6" "10" my-gravity-id 0 --from validator --chain-id=testing -b block -y
+
+echo "## View attestation status"
+gravitycli q gravity attestation bridge_bootstrap "$nonce" -o json | jq
+
+echo "## Query last observed state"
+gravitycli q gravity observed nonces -o json | jq
diff --git a/module/contrib/local/02-fake_deposit_attestation.sh b/module/contrib/local/02-fake_deposit_attestation.sh
new file mode 100755
index 0000000..12ee3c7
--- /dev/null
+++ b/module/contrib/local/02-fake_deposit_attestation.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+set -eu
+
+echo "## Add ETH key"
+gravitycli tx gravity update-eth-addr 0xb8662f35f9de8720424e82b232e8c98d15399490adae9ca993f5ef1dc4883690 --from validator --chain-id=testing -b block -y
+
+echo "## Submit observation"
+nonce=$(date +%s) # use unix timestamp as fake nonce
+# chain id: 1
+# bridge contract address: 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf
+# erc20 token contract address: 0x7c2c195cd6d34b8f845992d380aadb2730bb9c6f
+# erc20 symbol: ALX
+# amount: 100
+# gravitycli tx gravity observed deposit [eth chain id] [eth contract address] [nonce] [cosmos receiver] [amount] [eth erc20 symbol] [eth erc20 contract addr] [eth sender address] [flags]
+gravitycli tx gravity observed deposit 1 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf "$nonce" $(gravitycli keys show validator -a) 1000 ALX 0xc783df8a850f42e7f7e57013759c285caa701eb6 0x7c2c195cd6d34b8f845992d380aadb2730bb9c6f --from validator --chain-id=testing -b block -y
+
+echo "## Query balance"
+gravitycli q account $(gravitycli keys show validator -a)
+echo "## Query last observed state"
+gravitycli q gravity observed nonces -o json
\ No newline at end of file
diff --git a/module/contrib/local/03-fake_withdraw_attestation.sh b/module/contrib/local/03-fake_withdraw_attestation.sh
new file mode 100755
index 0000000..cd732e6
--- /dev/null
+++ b/module/contrib/local/03-fake_withdraw_attestation.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+set -eux
+
+echo "--> Needs to run after deposit\n"
+echo "## Add ETH key"
+gravitycli tx gravity update-eth-addr 0xb8662f35f9de8720424e82b232e8c98d15399490adae9ca993f5ef1dc4883690 --from validator --chain-id=testing -b block -y
+
+echo "## Add ETH withdraw to pool"
+gravitycli tx gravity withdraw validator 0xc783df8a850f42e7f7e57013759c285caa701eb6 1gravityf01b315c8e 0gravityf01b315c8e --from validator --chain-id=testing -b block -y
+
+echo "## Request a batch for outgoing TX"
+gravitycli tx gravity build-batch gravityf01b315c8e --from validator --chain-id=testing -b block -y
+
+echo "## Query pending request nonce"
+nonce=$(gravitycli q gravity pending-batch-request $(gravitycli keys show validator -a) -o json | jq -r ".value.nonce")
+
+echo "## Approve pending request"
+gravitycli tx gravity approved batch-confirm "$nonce" 0xb8662f35f9de8720424e82b232e8c98d15399490adae9ca993f5ef1dc4883690 --from validator --chain-id=testing -b block -y
+
+echo "## Submit observation"
+# chain id: 1
+# bridge contract address: 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf
+gravitycli tx gravity observed withdrawal 1 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf "$nonce" --from validator --chain-id=testing -b block -y
+
+echo "## Query balance"
+gravitycli q account $(gravitycli keys show validator -a)
+echo "## Query last observed state"
+gravitycli q gravity observed nonces -o json
\ No newline at end of file
diff --git a/module/contrib/local/04-fake_multisig_attestation.sh b/module/contrib/local/04-fake_multisig_attestation.sh
new file mode 100755
index 0000000..8a12964
--- /dev/null
+++ b/module/contrib/local/04-fake_multisig_attestation.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+set -eu
+
+echo "## Add ETH key"
+gravitycli tx gravity update-eth-addr 0xb8662f35f9de8720424e82b232e8c98d15399490adae9ca993f5ef1dc4883690 --from validator --chain-id=testing -b block -y
+echo "## Request valset update"
+gravitycli tx gravity valset-request --from validator --chain-id=testing -b block -y
+echo "## Query pending request nonce"
+nonce=$(gravitycli q gravity pending-valset-request $(gravitycli keys show validator -a) -o json | jq -r ".value.nonce")
+
+echo "## Approve pending request"
+gravitycli tx gravity approved valset-confirm "$nonce" 0xb8662f35f9de8720424e82b232e8c98d15399490adae9ca993f5ef1dc4883690 --from validator --chain-id=testing -b block -y
+
+echo "## View attestations"
+gravitycli q gravity attestation orchestrator_signed_multisig_update $nonce -o json | jq
+
+echo "## Submit observation"
+# chain id: 1
+# bridge contract address: 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf
+#gravitycli tx gravity observed multisig-update 1 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf "$nonce" --from validator --chain-id=testing -b block -y
+echo "## Query last observed state"
+gravitycli q gravity observed nonces -o json
\ No newline at end of file
diff --git a/module/contrib/local/README.md b/module/contrib/local/README.md
new file mode 100644
index 0000000..4ff2242
--- /dev/null
+++ b/module/contrib/local/README.md
@@ -0,0 +1,2 @@
+# Local development
+Collection of bash scripts to help with manual tests. Not for production.
\ No newline at end of file
diff --git a/module/contrib/local/protocgen.sh b/module/contrib/local/protocgen.sh
new file mode 100755
index 0000000..a67d6db
--- /dev/null
+++ b/module/contrib/local/protocgen.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+set -eo pipefail
+
+proto_dirs=$(find ./proto -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq)
+for dir in $proto_dirs; do
+ buf protoc \
+ -I "proto" \
+ -I "third_party/proto" \
+ --gocosmos_out=plugins=interfacetype+grpc,\
+Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types:. \
+ $(find "${dir}" -maxdepth 1 -name '*.proto')
+
+ # # command to generate gRPC gateway (*.pb.gw.go in respective modules) files
+ # buf protoc \
+ # -I "proto" \
+ # -I "third_party/proto" \
+ # --grpc-gateway_out=logtostderr=true:. \
+ # $(find "${dir}" -maxdepth 1 -name '*.proto')
+
+done
+
+# move proto files to the right places
+cp -r github.com/cosmos/gravity-bridge/module/* ./
+rm -rf github.com
diff --git a/module/contrib/local/setup_node.sh b/module/contrib/local/setup_node.sh
new file mode 100755
index 0000000..b1bb73e
--- /dev/null
+++ b/module/contrib/local/setup_node.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+set -eu
+
+gravityd init --chain-id=testing local
+gravityd add-genesis-account validator 1000000000stake
+gravityd gentx --name validator --amount 1000000000stake
+gravityd collect-gentxs
diff --git a/module/contrib/local/start_node.sh b/module/contrib/local/start_node.sh
new file mode 100755
index 0000000..14b0037
--- /dev/null
+++ b/module/contrib/local/start_node.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -eu
+
+gravityd start --rpc.laddr tcp://0.0.0.0:26657 --trace --log_level="main:info,state:debug,*:error"
\ No newline at end of file
diff --git a/module/go.mod b/module/go.mod
new file mode 100644
index 0000000..067ba29
--- /dev/null
+++ b/module/go.mod
@@ -0,0 +1,30 @@
+module github.com/cosmos/gravity-bridge/module
+
+go 1.15
+
+require (
+ github.com/cosmos/cosmos-sdk v0.43.0
+ github.com/cosmos/ibc-go v1.0.1
+ github.com/ethereum/go-ethereum v1.9.25
+ github.com/gogo/protobuf v1.3.3
+ github.com/gorilla/mux v1.8.0
+ github.com/grpc-ecosystem/grpc-gateway v1.16.0
+ github.com/pkg/errors v0.9.1
+ github.com/rakyll/statik v0.1.7
+ github.com/regen-network/cosmos-proto v0.3.1
+ github.com/spf13/cast v1.3.1
+ github.com/spf13/cobra v1.1.3
+ github.com/spf13/viper v1.8.0
+ github.com/stretchr/testify v1.7.0
+ github.com/tendermint/tendermint v0.34.12
+ github.com/tendermint/tm-db v0.6.4
+ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c
+ google.golang.org/grpc v1.38.0
+ google.golang.org/protobuf v1.26.0
+)
+
+replace google.golang.org/grpc => google.golang.org/grpc v1.33.2
+
+replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
+
+replace github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76
diff --git a/module/go.sum b/module/go.sum
new file mode 100644
index 0000000..264f886
--- /dev/null
+++ b/module/go.sum
@@ -0,0 +1,1254 @@
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
+cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
+cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
+cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
+cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
+cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
+cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
+cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+filippo.io/edwards25519 v1.0.0-beta.2 h1:/BZRNzm8N4K4eWfK28dL4yescorxtO7YG1yun8fy+pI=
+filippo.io/edwards25519 v1.0.0-beta.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o=
+github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
+github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
+github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4=
+github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
+github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
+github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
+github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
+github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
+github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
+github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
+github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
+github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
+github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
+github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
+github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
+github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
+github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI=
+github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
+github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM=
+github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
+github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
+github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 h1:rtI0fD4oG/8eVokGVPYJEW1F88p1ZNgXiEIs9thEE4A=
+github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-metrics v0.3.9 h1:O2sNqxBdvq8Eq5xmzljcYzAORli6RWCvEym4cJf9m18=
+github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
+github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
+github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
+github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
+github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0=
+github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
+github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
+github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94=
+github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo=
+github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
+github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
+github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
+github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
+github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
+github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
+github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ=
+github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o=
+github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
+github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
+github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
+github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
+github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
+github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
+github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
+github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
+github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
+github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
+github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
+github.com/coinbase/rosetta-sdk-go v0.6.10 h1:rgHD/nHjxLh0lMEdfGDqpTtlvtSBwULqrrZ2qPdNaCM=
+github.com/coinbase/rosetta-sdk-go v0.6.10/go.mod h1:J/JFMsfcePrjJZkwQFLh+hJErkAmdm9Iyy3D5Y0LfXo=
+github.com/confio/ics23/go v0.0.0-20200817220745-f173e6211efb/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg=
+github.com/confio/ics23/go v0.6.3/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg=
+github.com/confio/ics23/go v0.6.6 h1:pkOy18YxxJ/r0XFDCnrl4Bjv6h4LkBSpLS6F38mrKL8=
+github.com/confio/ics23/go v0.6.6/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/cosmos/cosmos-sdk v0.43.0 h1:l2GXJMDVtJyHb35pDUCw+uyr6eZtBo8vt+7PSsq+Fjo=
+github.com/cosmos/cosmos-sdk v0.43.0/go.mod h1:ctcrTEAhei9s8O3KSNvL0dxe+fVQGp07QyRb/7H9JYE=
+github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
+github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
+github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
+github.com/cosmos/iavl v0.15.0-rc3.0.20201009144442-230e9bdf52cd/go.mod h1:3xOIaNNX19p0QrX0VqWa6voPRoJRGGYtny+DH8NEPvE=
+github.com/cosmos/iavl v0.15.0-rc5/go.mod h1:WqoPL9yPTQ85QBMT45OOUzPxG/U/JcJoN7uMjgxke/I=
+github.com/cosmos/iavl v0.15.3/go.mod h1:OLjQiAQ4fGD2KDZooyJG9yz+p2ao2IAYSbke8mVvSA4=
+github.com/cosmos/iavl v0.16.0 h1:ICIOB8xysirTX27GmVAaoeSpeozzgSu9d49w36xkVJA=
+github.com/cosmos/iavl v0.16.0/go.mod h1:2A8O/Jz9YwtjqXMO0CjnnbTYEEaovE8jWcwrakH3PoE=
+github.com/cosmos/ibc-go v1.0.1 h1:3g2e4lghZea6Yrvj5PBViZrHdcEbG6iq7eulq3vsmxk=
+github.com/cosmos/ibc-go v1.0.1/go.mod h1:pfLnoW9yUdjSMw3rD0baIsqLBauVAlGFQ1zQ3HGK6J0=
+github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 h1:DdzS1m6o/pCqeZ8VOAit/gyATedRgjvkVI+UCrLpyuU=
+github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76/go.mod h1:0mkLWIoZuQ7uBoospo5Q9zIpqq6rYCPJDSUdeCJvPM8=
+github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4=
+github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
+github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI=
+github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI=
+github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
+github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU=
+github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
+github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0=
+github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
+github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
+github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
+github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
+github.com/dgraph-io/badger/v2 v2.2007.1/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE=
+github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k=
+github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE=
+github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
+github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI=
+github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
+github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
+github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
+github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
+github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b h1:HBah4D48ypg3J7Np4N+HY/ZR76fx3HEUGxDU6Uk39oQ=
+github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM=
+github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/enigmampc/btcutil v1.0.3-0.20200723161021-e2fb6adb2a25 h1:2vLKys4RBU4pn2T/hjXMbvwTr1Cvy5THHrQkbeY9HRk=
+github.com/enigmampc/btcutil v1.0.3-0.20200723161021-e2fb6adb2a25/go.mod h1:hTr8+TLQmkUkgcuh3mcr5fjrT9c64ZzsBCdCEC6UppY=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/ethereum/go-ethereum v1.9.25 h1:mMiw/zOOtCLdGLWfcekua0qPrJTe7FVIiHJ4IKNTfR0=
+github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM=
+github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
+github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
+github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
+github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
+github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=
+github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
+github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
+github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
+github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
+github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
+github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
+github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
+github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=
+github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
+github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
+github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
+github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
+github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
+github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
+github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
+github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
+github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
+github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
+github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
+github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=
+github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0=
+github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
+github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
+github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3 h1:ur2rms48b3Ep1dxh7aUV2FZEQ8jEVO2F6ILKx8ofkAg=
+github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64=
+github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us=
+github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
+github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-middleware v1.2.1/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
+github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
+github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
+github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.14.7/go.mod h1:oYZKL012gGh6LMyg/xA7Q2yq6j8bu0wa+9w14EEthWU=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=
+github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
+github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
+github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is=
+github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
+github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc=
+github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o=
+github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
+github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
+github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
+github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 h1:uUjLpLt6bVvZ72SQc/B4dXcPBw4Vgd7soowdRl52qEM=
+github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87/go.mod h1:XGsKKeXxeRr95aEOgipvluMPlgjr7dGlk9ZTWOjcUcg=
+github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
+github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
+github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/improbable-eng/grpc-web v0.14.0 h1:GdoK+cXABdB+1keuqsV1drSFO2XLYIxqt/4Rj8SWGBk=
+github.com/improbable-eng/grpc-web v0.14.0/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs=
+github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
+github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
+github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU=
+github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jhump/protoreflect v1.8.2 h1:k2xE7wcUomeqwY0LDCYA16y4WWfyTcMx5mKhk0d4ua0=
+github.com/jhump/protoreflect v1.8.2/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=
+github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
+github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
+github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
+github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
+github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM=
+github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
+github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA=
+github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
+github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
+github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
+github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
+github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
+github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4=
+github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
+github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
+github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
+github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0=
+github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
+github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0=
+github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
+github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs=
+github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
+github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
+github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
+github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
+github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
+github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
+github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso=
+github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
+github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
+github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
+github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ=
+github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E=
+github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
+github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI=
+github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
+github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
+github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E=
+github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
+github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
+github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
+github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
+github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
+github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
+github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
+github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
+github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
+github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
+github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
+github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
+github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
+github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM=
+github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
+github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
+github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
+github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
+github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
+github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
+github.com/prometheus/common v0.29.0 h1:3jqPBvKT4OHAbje2Ql7KeaaSicDBCxMYwEJU1zRJceE=
+github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
+github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
+github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
+github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg=
+github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM=
+github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4=
+github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI=
+github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
+github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
+github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
+github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
+github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/zerolog v1.23.0 h1:UskrK+saS9P9Y789yNNulYKdARjPZuS35B8gJF2x60g=
+github.com/rs/zerolog v1.23.0/go.mod h1:6c7hFfxPOy7TacJc4Fcdi24/J0NKYGzjG8FWRI916Qo=
+github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
+github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10=
+github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa h1:0U2s5loxrTy6/VgfVoLuVLFJcURKLH49ie0zSch7gh4=
+github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
+github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
+github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
+github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
+github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
+github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
+github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
+github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/spf13/viper v1.8.0 h1:QRwDgoG8xX+kp69di68D+YYTCWfYEckbZRfUlEIAal0=
+github.com/spf13/viper v1.8.0/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
+github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
+github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
+github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU=
+github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk=
+github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
+github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok=
+github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
+github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s=
+github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U=
+github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI=
+github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk=
+github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E=
+github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
+github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4=
+github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX6mjJTgbLHTwi17VDVg=
+github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ=
+github.com/tendermint/tendermint v0.34.10/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0=
+github.com/tendermint/tendermint v0.34.11/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0=
+github.com/tendermint/tendermint v0.34.12 h1:m+kUYNhONedhJfHmHG8lqsdZvbR5t6vmhaok1yXjpKg=
+github.com/tendermint/tendermint v0.34.12/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0=
+github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI=
+github.com/tendermint/tm-db v0.6.3/go.mod h1:lfA1dL9/Y/Y8wwyPp2NMLyn5P5Ptr/gvDFNWtrCWSf8=
+github.com/tendermint/tm-db v0.6.4 h1:3N2jlnYQkXNQclQwd/eKV/NzlqPlfK21cpRRIx80XXQ=
+github.com/tendermint/tm-db v0.6.4/go.mod h1:dptYhIpJ2M5kUuenLr+Yyf3zQOv1SgBZcl8/BmWlMBw=
+github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI=
+github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
+github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
+github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
+github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
+github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/vmihailenco/msgpack/v5 v5.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI=
+github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
+github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
+github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
+go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
+go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
+go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
+go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
+go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
+golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=
+golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
+google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
+google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
+google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
+google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
+gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
+gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
+gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
+gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
+nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
diff --git a/module/proto/gravity/v1/genesis.proto b/module/proto/gravity/v1/genesis.proto
new file mode 100644
index 0000000..5d2dc5f
--- /dev/null
+++ b/module/proto/gravity/v1/genesis.proto
@@ -0,0 +1,124 @@
+syntax = "proto3";
+package gravity.v1;
+
+import "gogoproto/gogo.proto";
+import "gravity/v1/gravity.proto";
+import "gravity/v1/msgs.proto";
+import "google/protobuf/any.proto";
+
+option go_package = "github.com/cosmos/gravity-bridge/module/x/gravity/types";
+
+// Params represent the Gravity genesis and store parameters
+// gravity_id:
+// a random 32 byte value to prevent signature reuse, for example if the
+// cosmos validators decided to use the same Ethereum keys for another chain
+// also running Gravity we would not want it to be possible to play a deposit
+// from chain A back on chain B's Gravity. This value IS USED ON ETHEREUM so
+// it must be set in your genesis.json before launch and not changed after
+// deploying Gravity
+//
+// contract_hash:
+// the code hash of a known good version of the Gravity contract
+// solidity code. This can be used to verify the correct version
+// of the contract has been deployed. This is a reference value for
+// goernance action only it is never read by any Gravity code
+//
+// bridge_ethereum_address:
+// is address of the bridge contract on the Ethereum side, this is a
+// reference value for governance only and is not actually used by any
+// Gravity code
+//
+// bridge_chain_id:
+// the unique identifier of the Ethereum chain, this is a reference value
+// only and is not actually used by any Gravity code
+//
+// These reference values may be used by future Gravity client implemetnations
+// to allow for saftey features or convenience features like the Gravity address
+// in your relayer. A relayer would require a configured Gravity address if
+// governance had not set the address on the chain it was relaying for.
+//
+// signed_signer_set_txs_window
+// signed_batches_window
+// signed_ethereum_signatures_window
+//
+// These values represent the time in blocks that a validator has to submit
+// a signature for a batch or valset, or to submit a ethereum_signature for a
+// particular attestation nonce. In the case of attestations this clock starts
+// when the attestation is created, but only allows for slashing once the event
+// has passed
+//
+// target_eth_tx_timeout:
+//
+// This is the 'target' value for when ethereum transactions time out, this is a target
+// because Ethereum is a probabilistic chain and you can't say for sure what the
+// block frequency is ahead of time.
+//
+// average_block_time
+// average_ethereum_block_time
+//
+// These values are the average Cosmos block time and Ethereum block time
+// respectively and they are used to compute what the target batch timeout is. It
+// is important that governance updates these in case of any major, prolonged
+// change in the time it takes to produce a block
+//
+// slash_fraction_signer_set_tx
+// slash_fraction_batch
+// slash_fraction_ethereum_signature
+// slash_fraction_conflicting_ethereum_signature
+//
+// The slashing fractions for the various gravity related slashing conditions.
+// The first three refer to not submitting a particular message, the third for
+// submitting a different ethereum_signature for the same Ethereum event
+message Params {
+ option (gogoproto.stringer) = false;
+
+ string gravity_id = 1;
+ string contract_source_hash = 2;
+ string bridge_ethereum_address = 4;
+ uint64 bridge_chain_id = 5;
+ uint64 signed_signer_set_txs_window = 6;
+ uint64 signed_batches_window = 7;
+ uint64 ethereum_signatures_window = 8;
+ uint64 target_eth_tx_timeout = 10;
+ uint64 average_block_time = 11;
+ uint64 average_ethereum_block_time = 12;
+ // TODO: slash fraction for contract call txs too
+ bytes slash_fraction_signer_set_tx = 13 [
+ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
+ (gogoproto.nullable) = false
+ ];
+ bytes slash_fraction_batch = 14 [
+ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
+ (gogoproto.nullable) = false
+ ];
+ bytes slash_fraction_ethereum_signature = 15 [
+ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
+ (gogoproto.nullable) = false
+ ];
+ bytes slash_fraction_conflicting_ethereum_signature = 16 [
+ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
+ (gogoproto.nullable) = false
+ ];
+ uint64 unbond_slashing_signer_set_txs_window = 17;
+}
+
+// GenesisState struct
+// TODO: this need to be audited and potentially simplified using the new
+// interfaces
+message GenesisState {
+ Params params = 1;
+ uint64 last_observed_event_nonce = 2;
+ repeated google.protobuf.Any outgoing_txs = 3;
+ repeated google.protobuf.Any confirmations = 4;
+ repeated EthereumEventVoteRecord ethereum_event_vote_records = 9;
+ repeated MsgDelegateKeys delegate_keys = 10;
+ repeated ERC20ToDenom erc20_to_denoms = 11;
+ repeated SendToEthereum unbatched_send_to_ethereum_txs = 12;
+}
+
+// This records the relationship between an ERC20 token and the denom
+// of the corresponding Cosmos originated asset
+message ERC20ToDenom {
+ string erc20 = 1;
+ string denom = 2;
+}
diff --git a/module/proto/gravity/v1/gravity.proto b/module/proto/gravity/v1/gravity.proto
new file mode 100644
index 0000000..7b21a87
--- /dev/null
+++ b/module/proto/gravity/v1/gravity.proto
@@ -0,0 +1,91 @@
+syntax = "proto3";
+package gravity.v1;
+
+import "cosmos_proto/cosmos.proto";
+import "google/protobuf/timestamp.proto";
+import "gogoproto/gogo.proto";
+import "cosmos/base/v1beta1/coin.proto";
+import "google/protobuf/any.proto";
+
+option go_package = "github.com/cosmos/gravity-bridge/module/x/gravity/types";
+
+// EthereumEventVoteRecord is an event that is pending of confirmation by 2/3 of
+// the signer set. The event is then attested and executed in the state machine
+// once the required threshold is met.
+message EthereumEventVoteRecord {
+ google.protobuf.Any event = 1
+ [ (cosmos_proto.accepts_interface) = "EthereumEvent" ];
+ repeated string votes = 2;
+ bool accepted = 3;
+}
+
+// LatestEthereumBlockHeight defines the latest observed ethereum block height
+// and the corresponding timestamp value in nanoseconds.
+message LatestEthereumBlockHeight {
+ uint64 ethereum_height = 1;
+ uint64 cosmos_height = 2;
+}
+
+// EthereumSigner represents a cosmos validator with its corresponding bridge
+// operator ethereum address and its staking consensus power.
+message EthereumSigner {
+ uint64 power = 1;
+ string ethereum_address = 2;
+}
+
+// SignerSetTx is the Ethereum Bridge multisig set that relays
+// transactions the two chains. The staking validators keep ethereum keys which
+// are used to check signatures on Ethereum in order to get significant gas
+// savings.
+message SignerSetTx {
+ uint64 nonce = 1;
+ uint64 height = 2;
+ repeated EthereumSigner signers = 3
+ [ (gogoproto.castrepeated) = "EthereumSigners" ];
+}
+
+// BatchTx represents a batch of transactions going from Cosmos to Ethereum.
+// Batch txs are are identified by a unique hash and the token contract that is
+// shared by all the SendToEthereum
+message BatchTx {
+ uint64 batch_nonce = 1;
+ uint64 timeout = 2;
+ repeated SendToEthereum transactions = 3;
+ string token_contract = 4;
+ uint64 height = 5;
+}
+
+// SendToEthereum represents an individual SendToEthereum from Cosmos to
+// Ethereum
+message SendToEthereum {
+ uint64 id = 1;
+ string sender = 2;
+ string ethereum_recipient = 3;
+ ERC20Token erc20_token = 4 [ (gogoproto.nullable) = false ];
+ ERC20Token erc20_fee = 5 [ (gogoproto.nullable) = false ];
+}
+
+// ContractCallTx represents an individual arbitrary logic call transaction
+// from Cosmos to Ethereum.
+message ContractCallTx {
+ uint64 invalidation_nonce = 1;
+ bytes invalidation_scope = 2
+ [ (gogoproto.casttype) =
+ "github.com/tendermint/tendermint/libs/bytes.HexBytes" ];
+ string address = 3;
+ bytes payload = 4;
+ uint64 timeout = 5;
+ repeated ERC20Token tokens = 6 [ (gogoproto.nullable) = false ];
+ repeated ERC20Token fees = 7 [ (gogoproto.nullable) = false ];
+ uint64 height = 8;
+}
+
+message ERC20Token {
+ string contract = 1;
+ string amount = 2 [
+ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
+ (gogoproto.nullable) = false
+ ];
+}
+
+message IDSet { repeated uint64 ids = 1; }
diff --git a/module/proto/gravity/v1/msgs.proto b/module/proto/gravity/v1/msgs.proto
new file mode 100644
index 0000000..ebb97d2
--- /dev/null
+++ b/module/proto/gravity/v1/msgs.proto
@@ -0,0 +1,206 @@
+syntax = "proto3";
+package gravity.v1;
+
+import "cosmos/base/v1beta1/coin.proto";
+import "cosmos_proto/cosmos.proto";
+import "gravity/v1/gravity.proto";
+import "gogoproto/gogo.proto";
+import "google/api/annotations.proto";
+import "google/protobuf/any.proto";
+
+option go_package = "github.com/cosmos/gravity-bridge/module/x/gravity/types";
+
+// Msg defines the state transitions possible within gravity
+service Msg {
+ rpc SendToEthereum(MsgSendToEthereum) returns (MsgSendToEthereumResponse) {
+ // option (google.api.http).post = "/gravity/v1/send_to_ethereum";
+ }
+ rpc CancelSendToEthereum(MsgCancelSendToEthereum)
+ returns (MsgCancelSendToEthereumResponse) {
+ // option (google.api.http).post = "/gravity/v1/send_to_ethereum/cancel";
+ }
+ rpc RequestBatchTx(MsgRequestBatchTx) returns (MsgRequestBatchTxResponse) {
+ // option (google.api.http).post = "/gravity/v1/batchtx/request";
+ }
+ rpc SubmitEthereumTxConfirmation(MsgSubmitEthereumTxConfirmation)
+ returns (MsgSubmitEthereumTxConfirmationResponse) {
+ // option (google.api.http).post = "/gravity/v1/ethereum_signature";
+ }
+ rpc SubmitEthereumEvent(MsgSubmitEthereumEvent)
+ returns (MsgSubmitEthereumEventResponse) {
+ // option (google.api.http).post = "/gravity/v1/ethereum_event";
+ }
+ rpc SetDelegateKeys(MsgDelegateKeys) returns (MsgDelegateKeysResponse) {
+ // option (google.api.http).post = "/gravity/v1/delegate_keys";
+ }
+}
+
+// MsgSendToEthereum submits a SendToEthereum attempt to bridge an asset over to
+// Ethereum. The SendToEthereum will be stored and then included in a batch and
+// then submitted to Ethereum.
+message MsgSendToEthereum {
+ string sender = 1;
+ string ethereum_recipient = 2;
+ cosmos.base.v1beta1.Coin amount = 3 [ (gogoproto.nullable) = false ];
+ cosmos.base.v1beta1.Coin bridge_fee = 4 [ (gogoproto.nullable) = false ];
+}
+
+// MsgSendToEthereumResponse returns the SendToEthereum transaction ID which
+// will be included in the batch tx.
+message MsgSendToEthereumResponse { uint64 id = 1; }
+
+// MsgCancelSendToEthereum allows the sender to cancel its own outgoing
+// SendToEthereum tx and recieve a refund of the tokens and bridge fees. This tx
+// will only succeed if the SendToEthereum tx hasn't been batched to be
+// processed and relayed to Ethereum.
+message MsgCancelSendToEthereum {
+ uint64 id = 1;
+ string sender = 2;
+}
+
+message MsgCancelSendToEthereumResponse {}
+
+// MsgRequestBatchTx requests a batch of transactions with a given coin
+// denomination to send across the bridge to Ethereum.
+message MsgRequestBatchTx {
+ string denom = 1;
+ string signer = 2;
+}
+
+message MsgRequestBatchTxResponse {}
+
+// MsgSubmitEthereumTxConfirmation submits an ethereum signature for a given
+// validator
+message MsgSubmitEthereumTxConfirmation {
+ option (gogoproto.goproto_getters) = false;
+
+ // TODO: can we make this take an array?
+ google.protobuf.Any confirmation = 1
+ [ (cosmos_proto.accepts_interface) = "EthereumTxConfirmation" ];
+ string signer = 2;
+}
+
+// ContractCallTxConfirmation is a signature on behalf of a validator for a
+// ContractCallTx.
+message ContractCallTxConfirmation {
+ bytes invalidation_scope = 1;
+ uint64 invalidation_nonce = 2;
+ string ethereum_signer = 3;
+ bytes signature = 4;
+}
+
+// BatchTxConfirmation is a signature on behalf of a validator for a BatchTx.
+message BatchTxConfirmation {
+ string token_contract = 1;
+ uint64 batch_nonce = 2;
+ string ethereum_signer = 3;
+ bytes signature = 4;
+}
+
+// SignerSetTxConfirmation is a signature on behalf of a validator for a
+// SignerSetTx
+message SignerSetTxConfirmation {
+ uint64 signer_set_nonce = 1;
+ string ethereum_signer = 2;
+ bytes signature = 3;
+}
+
+message MsgSubmitEthereumTxConfirmationResponse {}
+
+// MsgSubmitEthereumEvent
+message MsgSubmitEthereumEvent {
+ option (gogoproto.goproto_getters) = false;
+
+ google.protobuf.Any event = 1
+ [ (cosmos_proto.accepts_interface) = "EthereumEvent" ];
+ string signer = 2;
+}
+
+
+message MsgSubmitEthereumEventResponse {}
+
+// MsgDelegateKey allows validators to delegate their voting responsibilities
+// to a given orchestrator address. This key is then used as an optional
+// authentication method for attesting events from Ethereum.
+message MsgDelegateKeys {
+ string validator_address = 1;
+ string orchestrator_address = 2;
+ string ethereum_address = 3;
+ bytes eth_signature = 4;
+}
+
+message MsgDelegateKeysResponse {}
+
+// DelegateKeysSignMsg defines the message structure an operator is expected to
+// sign when submitting a MsgDelegateKeys message. The resulting signature should
+// populate the eth_signature field.
+message DelegateKeysSignMsg {
+ string validator_address = 1;
+ uint64 nonce = 2;
+}
+
+////////////
+// Events //
+////////////
+
+// SendToCosmosEvent is submitted when the SendToCosmosEvent is emitted by they
+// gravity contract. ERC20 representation coins are minted to the cosmosreceiver
+// address.
+message SendToCosmosEvent {
+ option (gogoproto.equal) = true;
+
+ uint64 event_nonce = 1;
+ string token_contract = 2;
+ string amount = 3 [
+ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
+ (gogoproto.nullable) = false
+ ];
+ string ethereum_sender = 4;
+ string cosmos_receiver = 5;
+ uint64 ethereum_height = 6;
+}
+
+// BatchExecutedEvent claims that a batch of BatchTxExecutedal operations on the
+// bridge contract was executed successfully on ETH
+message BatchExecutedEvent {
+ string token_contract = 1;
+ uint64 event_nonce = 2;
+ uint64 ethereum_height = 3;
+ uint64 batch_nonce = 4;
+}
+
+// ContractCallExecutedEvent describes a contract call that has been
+// successfully executed on Ethereum.
+
+// NOTE: bytes.HexBytes is supposed to "help" with json encoding/decoding
+// investigate?
+message ContractCallExecutedEvent {
+ uint64 event_nonce = 1;
+ bytes invalidation_scope = 2
+ [ (gogoproto.casttype) =
+ "github.com/tendermint/tendermint/libs/bytes.HexBytes" ];
+ uint64 invalidation_nonce = 3;
+ uint64 ethereum_height = 4;
+}
+
+// ERC20DeployedEvent is submitted when an ERC20 contract
+// for a Cosmos SDK coin has been deployed on Ethereum.
+message ERC20DeployedEvent {
+ uint64 event_nonce = 1;
+ string cosmos_denom = 2;
+ string token_contract = 3;
+ string erc20_name = 4;
+ string erc20_symbol = 5;
+ uint64 erc20_decimals = 6;
+ uint64 ethereum_height = 7;
+}
+
+// This informs the Cosmos module that a validator
+// set has been updated.
+message SignerSetTxExecutedEvent {
+ uint64 event_nonce = 1;
+ uint64 signer_set_tx_nonce = 2;
+ uint64 ethereum_height = 3;
+ repeated EthereumSigner members = 4;
+}
+
diff --git a/module/proto/gravity/v1/query.proto b/module/proto/gravity/v1/query.proto
new file mode 100644
index 0000000..455f27c
--- /dev/null
+++ b/module/proto/gravity/v1/query.proto
@@ -0,0 +1,320 @@
+syntax = "proto3";
+package gravity.v1;
+
+import "cosmos/base/query/v1beta1/pagination.proto";
+import "cosmos/base/v1beta1/coin.proto";
+import "gogoproto/gogo.proto";
+import "google/api/annotations.proto";
+import "gravity/v1/genesis.proto";
+import "gravity/v1/gravity.proto";
+import "gravity/v1/msgs.proto";
+
+option go_package = "github.com/cosmos/gravity-bridge/module/x/gravity/types";
+
+// Query defines the gRPC querier service
+service Query {
+
+ // Module parameters query
+ rpc Params(ParamsRequest) returns (ParamsResponse) {
+ // option (google.api.http).get = "/gravity/v1/params";
+ }
+
+ // get info on individual outgoing data
+ rpc SignerSetTx(SignerSetTxRequest) returns (SignerSetTxResponse) {
+ // option (google.api.http).get = "/gravity/v1/signer_set";
+ }
+ rpc LatestSignerSetTx(LatestSignerSetTxRequest)
+ returns (SignerSetTxResponse) {
+ // option (google.api.http).get = "/gravity/v1/signer_set/latest";
+ }
+ rpc BatchTx(BatchTxRequest) returns (BatchTxResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/batch_txs/{token_contract}/{nonce}";
+ }
+ rpc ContractCallTx(ContractCallTxRequest) returns (ContractCallTxResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/contract_call_txs/{invalidation_id}/{invalidation_nonce}";
+ }
+
+ // get collections of outgoing traffic from the bridge
+ rpc SignerSetTxs(SignerSetTxsRequest) returns (SignerSetTxsResponse) {
+ // option (google.api.http).get = "/gravity/v1/signer_sets";
+ }
+ rpc BatchTxs(BatchTxsRequest) returns (BatchTxsResponse) {
+ // option (google.api.http).get = "/gravity/v1/batch/batch_txs";
+ }
+ rpc ContractCallTxs(ContractCallTxsRequest)
+ returns (ContractCallTxsResponse) {
+ // option (google.api.http).get = "/gravity/v1/batch/contract_call_txs";
+ }
+
+ // ethereum signature queries so validators can construct valid etherum
+ // transactions
+
+ // TODO: can/should we group these into one endpoint?
+ rpc SignerSetTxConfirmations(SignerSetTxConfirmationsRequest)
+ returns (SignerSetTxConfirmationsResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/signer_sets/ethereum_signatures";
+ }
+ rpc BatchTxConfirmations(BatchTxConfirmationsRequest)
+ returns (BatchTxConfirmationsResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/batch_txs/ethereum_signatures";
+ }
+ rpc ContractCallTxConfirmations(ContractCallTxConfirmationsRequest)
+ returns (ContractCallTxConfirmationsResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/logic_calls/ethereum_signatures";
+ }
+
+ // ^^^^^^^^^^^^ seem okay for now ^^^^^^
+
+ // pending ethereum signature queries for orchestrators to figure out which
+ // signatures they are missing
+ // TODO: can/should we group this into one endpoint?
+ rpc UnsignedSignerSetTxs(UnsignedSignerSetTxsRequest)
+ returns (UnsignedSignerSetTxsResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/SignerSetTxs/{address}/pending";
+ }
+ rpc UnsignedBatchTxs(UnsignedBatchTxsRequest)
+ returns (UnsignedBatchTxsResponse) {
+ // option (google.api.http).get = "/gravity/v1/batches/{address}/pending";
+ }
+ rpc UnsignedContractCallTxs(UnsignedContractCallTxsRequest)
+ returns (UnsignedContractCallTxsResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/ContractCallTxs/{address}/pending";
+ }
+
+ rpc LastSubmittedEthereumEvent(LastSubmittedEthereumEventRequest)
+ returns (LastSubmittedEthereumEventResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/oracle/event_nonce/{address}";
+ }
+
+ // Queries the fees for all pending batches, results are returned in sdk.Coin
+ // (fee_amount_int)(contract_address) style
+ rpc BatchTxFees(BatchTxFeesRequest) returns (BatchTxFeesResponse) {
+ // option (google.api.http).get = "/gravity/v1/batches/fees";
+ }
+
+ // Query for info about denoms tracked by gravity
+ rpc ERC20ToDenom(ERC20ToDenomRequest) returns (ERC20ToDenomResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/cosmos_originated/erc20_to_denom";
+ }
+
+ // DenomToERC20Params implements a query that allows ERC-20 parameter information
+ // to be retrieved by a Cosmos base denomination.
+ rpc DenomToERC20Params(DenomToERC20ParamsRequest) returns (DenomToERC20ParamsResponse) {}
+
+ // Query for info about denoms tracked by gravity
+ rpc DenomToERC20(DenomToERC20Request) returns (DenomToERC20Response) {
+ // option (google.api.http).get =
+ // "/gravity/v1/cosmos_originated/denom_to_erc20";
+ }
+ // Query for batch send to ethereums
+ rpc BatchedSendToEthereums(BatchedSendToEthereumsRequest)
+ returns (BatchedSendToEthereumsResponse) {
+ // option (google.api.http).get = "/gravity/v1/query_batched_send_to_eth";
+ }
+ // Query for unbatched send to ethereums
+ rpc UnbatchedSendToEthereums(UnbatchedSendToEthereumsRequest)
+ returns (UnbatchedSendToEthereumsResponse) {
+ // option (google.api.http).get = "/gravity/v1/query_unbatched_send_to_eth";
+ }
+
+ // delegate keys
+ rpc DelegateKeysByValidator(DelegateKeysByValidatorRequest)
+ returns (DelegateKeysByValidatorResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/delegate_keys/validator/{validator}";
+ }
+ rpc DelegateKeysByEthereumSigner(DelegateKeysByEthereumSignerRequest)
+ returns (DelegateKeysByEthereumSignerResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/delegate_keys/ethereum/{ethereum_signer}";
+ }
+ rpc DelegateKeysByOrchestrator(DelegateKeysByOrchestratorRequest)
+ returns (DelegateKeysByOrchestratorResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/delegate_keys/orchestrator/{orchestrator}";
+ }
+
+ rpc DelegateKeys(DelegateKeysRequest) returns (DelegateKeysResponse) {
+ // option (google.api.http).get =
+ // "/gravity/v1/delegate_keys";
+ }
+}
+
+// rpc Params
+message ParamsRequest {}
+message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; }
+
+// rpc SignerSetTx
+message SignerSetTxRequest { uint64 signer_set_nonce = 1; }
+message LatestSignerSetTxRequest {}
+message SignerSetTxResponse { SignerSetTx signer_set = 1; }
+
+// rpc BatchTx
+message BatchTxRequest {
+ string token_contract = 1;
+ uint64 batch_nonce = 2;
+}
+message BatchTxResponse { BatchTx batch = 1; }
+
+// rpc ContractCallTx
+message ContractCallTxRequest {
+ bytes invalidation_scope = 1;
+ uint64 invalidation_nonce = 2;
+}
+message ContractCallTxResponse { ContractCallTx logic_call = 1; }
+
+// rpc SignerSetTxConfirmations
+message SignerSetTxConfirmationsRequest { uint64 signer_set_nonce = 1; }
+message SignerSetTxConfirmationsResponse {
+ repeated SignerSetTxConfirmation signatures = 1;
+}
+
+// rpc SignerSetTxs
+message SignerSetTxsRequest {
+ cosmos.base.query.v1beta1.PageRequest pagination = 1;
+}
+message SignerSetTxsResponse {
+ repeated SignerSetTx signer_sets = 1;
+ cosmos.base.query.v1beta1.PageResponse pagination = 2;
+}
+
+// rpc BatchTxs
+message BatchTxsRequest {
+ cosmos.base.query.v1beta1.PageRequest pagination = 1;
+}
+message BatchTxsResponse {
+ repeated BatchTx batches = 1;
+ cosmos.base.query.v1beta1.PageResponse pagination = 2;
+}
+
+// rpc ContractCallTxs
+message ContractCallTxsRequest {
+ cosmos.base.query.v1beta1.PageRequest pagination = 1;
+}
+message ContractCallTxsResponse {
+ repeated ContractCallTx calls = 1;
+ cosmos.base.query.v1beta1.PageResponse pagination = 2;
+}
+
+// NOTE(levi) pending queries: this is my address; what do I need to sign??
+// why orchestrator key? hot, signing thing all the time so validator key can be
+// safer
+
+// rpc UnsignedSignerSetTxs
+message UnsignedSignerSetTxsRequest {
+ // NOTE: this is an sdk.AccAddress and can represent either the
+ // orchestartor address or the cooresponding validator address
+ string address = 1;
+}
+message UnsignedSignerSetTxsResponse { repeated SignerSetTx signer_sets = 1; }
+
+message UnsignedBatchTxsRequest {
+ // NOTE: this is an sdk.AccAddress and can represent either the
+ // orchestrator address or the cooresponding validator address
+ string address = 1;
+}
+message UnsignedBatchTxsResponse {
+ // Note these are returned with the signature empty
+ repeated BatchTx batches = 1;
+}
+
+// rpc UnsignedContractCallTxs
+message UnsignedContractCallTxsRequest { string address = 1; }
+message UnsignedContractCallTxsResponse { repeated ContractCallTx calls = 1; }
+
+message BatchTxFeesRequest {}
+message BatchTxFeesResponse {
+ repeated cosmos.base.v1beta1.Coin fees = 1 [
+ (gogoproto.nullable) = false,
+ (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
+ ];
+}
+
+message ContractCallTxConfirmationsRequest {
+ bytes invalidation_scope = 1;
+ uint64 invalidation_nonce = 2;
+}
+message ContractCallTxConfirmationsResponse {
+ repeated ContractCallTxConfirmation signatures = 1;
+}
+
+message BatchTxConfirmationsRequest {
+ uint64 batch_nonce = 1;
+ string token_contract = 2;
+}
+message BatchTxConfirmationsResponse {
+ repeated BatchTxConfirmation signatures = 1;
+}
+
+message LastSubmittedEthereumEventRequest { string address = 1; }
+message LastSubmittedEthereumEventResponse { uint64 event_nonce = 1; }
+
+message ERC20ToDenomRequest { string erc20 = 1; }
+message ERC20ToDenomResponse {
+ string denom = 1;
+ bool cosmos_originated = 2;
+}
+
+message DenomToERC20ParamsRequest { string denom = 1; }
+message DenomToERC20ParamsResponse {
+ string base_denom = 1;
+ string erc20_name = 2;
+ string erc20_symbol = 3;
+ uint64 erc20_decimals = 4;
+}
+
+message DenomToERC20Request { string denom = 1; }
+message DenomToERC20Response {
+ string erc20 = 1;
+ bool cosmos_originated = 2;
+}
+
+message DelegateKeysByValidatorRequest { string validator_address = 1; }
+message DelegateKeysByValidatorResponse {
+ string eth_address = 1;
+ string orchestrator_address = 2;
+}
+
+message DelegateKeysByEthereumSignerRequest { string ethereum_signer = 1; }
+message DelegateKeysByEthereumSignerResponse {
+ string validator_address = 1;
+ string orchestrator_address = 2;
+}
+
+message DelegateKeysByOrchestratorRequest { string orchestrator_address = 1; }
+message DelegateKeysByOrchestratorResponse {
+ string validator_address = 1;
+ string ethereum_signer = 2;
+}
+
+message DelegateKeysRequest {}
+message DelegateKeysResponse { repeated MsgDelegateKeys delegate_keys = 1; }
+
+// NOTE: if there is no sender address, return all
+message BatchedSendToEthereumsRequest {
+ string sender_address = 1;
+ // todo: figure out how to paginate given n Batches with m Send To Ethereums
+ // cosmos.base.query.v1beta1.PageRequest pagination = 2;
+}
+message BatchedSendToEthereumsResponse {
+ repeated SendToEthereum send_to_ethereums = 1;
+ // cosmos.base.query.v1beta1.PageResponse pagination = 2;
+}
+
+message UnbatchedSendToEthereumsRequest {
+ string sender_address = 1;
+ cosmos.base.query.v1beta1.PageRequest pagination = 2;
+}
+message UnbatchedSendToEthereumsResponse {
+ repeated SendToEthereum send_to_ethereums = 1;
+ cosmos.base.query.v1beta1.PageResponse pagination = 2;
+}
diff --git a/module/third_party/proto/cosmos/base/abci/v1beta1/abci.proto b/module/third_party/proto/cosmos/base/abci/v1beta1/abci.proto
new file mode 100644
index 0000000..72da2aa
--- /dev/null
+++ b/module/third_party/proto/cosmos/base/abci/v1beta1/abci.proto
@@ -0,0 +1,137 @@
+syntax = "proto3";
+package cosmos.base.abci.v1beta1;
+
+import "gogoproto/gogo.proto";
+import "tendermint/abci/types.proto";
+import "google/protobuf/any.proto";
+
+option go_package = "github.com/cosmos/cosmos-sdk/types";
+option (gogoproto.goproto_stringer_all) = false;
+
+// TxResponse defines a structure containing relevant tx data and metadata. The
+// tags are stringified and the log is JSON decoded.
+message TxResponse {
+ option (gogoproto.goproto_getters) = false;
+ // The block height
+ int64 height = 1;
+ // The transaction hash.
+ string txhash = 2 [(gogoproto.customname) = "TxHash"];
+ // Namespace for the Code
+ string codespace = 3;
+ // Response code.
+ uint32 code = 4;
+ // Result bytes, if any.
+ string data = 5;
+ // The output of the application's logger (raw string). May be
+ // non-deterministic.
+ string raw_log = 6;
+ // The output of the application's logger (typed). May be non-deterministic.
+ repeated ABCIMessageLog logs = 7 [(gogoproto.castrepeated) = "ABCIMessageLogs", (gogoproto.nullable) = false];
+ // Additional information. May be non-deterministic.
+ string info = 8;
+ // Amount of gas requested for transaction.
+ int64 gas_wanted = 9;
+ // Amount of gas consumed by transaction.
+ int64 gas_used = 10;
+ // The request transaction bytes.
+ google.protobuf.Any tx = 11;
+ // Time of the previous block. For heights > 1, it's the weighted median of
+ // the timestamps of the valid votes in the block.LastCommit. For height == 1,
+ // it's genesis time.
+ string timestamp = 12;
+}
+
+// ABCIMessageLog defines a structure containing an indexed tx ABCI message log.
+message ABCIMessageLog {
+ option (gogoproto.stringer) = true;
+
+ uint32 msg_index = 1;
+ string log = 2;
+
+ // Events contains a slice of Event objects that were emitted during some
+ // execution.
+ repeated StringEvent events = 3 [(gogoproto.castrepeated) = "StringEvents", (gogoproto.nullable) = false];
+}
+
+// StringEvent defines en Event object wrapper where all the attributes
+// contain key/value pairs that are strings instead of raw bytes.
+message StringEvent {
+ option (gogoproto.stringer) = true;
+
+ string type = 1;
+ repeated Attribute attributes = 2 [(gogoproto.nullable) = false];
+}
+
+// Attribute defines an attribute wrapper where the key and value are
+// strings instead of raw bytes.
+message Attribute {
+ string key = 1;
+ string value = 2;
+}
+
+// GasInfo defines tx execution gas context.
+message GasInfo {
+ // GasWanted is the maximum units of work we allow this tx to perform.
+ uint64 gas_wanted = 1 [(gogoproto.moretags) = "yaml:\"gas_wanted\""];
+
+ // GasUsed is the amount of gas actually consumed.
+ uint64 gas_used = 2 [(gogoproto.moretags) = "yaml:\"gas_used\""];
+}
+
+// Result is the union of ResponseFormat and ResponseCheckTx.
+message Result {
+ option (gogoproto.goproto_getters) = false;
+
+ // Data is any data returned from message or handler execution. It MUST be
+ // length prefixed in order to separate data from multiple message executions.
+ bytes data = 1;
+
+ // Log contains the log information from message or handler execution.
+ string log = 2;
+
+ // Events contains a slice of Event objects that were emitted during message
+ // or handler execution.
+ repeated tendermint.abci.Event events = 3 [(gogoproto.nullable) = false];
+}
+
+// SimulationResponse defines the response generated when a transaction is
+// successfully simulated.
+message SimulationResponse {
+ GasInfo gas_info = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
+ Result result = 2;
+}
+
+// MsgData defines the data returned in a Result object during message
+// execution.
+message MsgData {
+ option (gogoproto.stringer) = true;
+
+ string msg_type = 1;
+ bytes data = 2;
+}
+
+// TxMsgData defines a list of MsgData. A transaction will have a MsgData object
+// for each message.
+message TxMsgData {
+ option (gogoproto.stringer) = true;
+
+ repeated MsgData data = 1;
+}
+
+// SearchTxsResult defines a structure for querying txs pageable
+message SearchTxsResult {
+ option (gogoproto.stringer) = true;
+
+ // Count of all txs
+ uint64 total_count = 1 [(gogoproto.moretags) = "yaml:\"total_count\"", (gogoproto.jsontag) = "total_count"];
+ // Count of txs in current page
+ uint64 count = 2;
+ // Index of current page, start from 1
+ uint64 page_number = 3 [(gogoproto.moretags) = "yaml:\"page_number\"", (gogoproto.jsontag) = "page_number"];
+ // Count of total pages
+ uint64 page_total = 4 [(gogoproto.moretags) = "yaml:\"page_total\"", (gogoproto.jsontag) = "page_total"];
+ // Max count txs per page
+ uint64 limit = 5;
+ // List of txs in current page
+ repeated TxResponse txs = 6;
+}
diff --git a/module/third_party/proto/cosmos/base/query/v1beta1/pagination.proto b/module/third_party/proto/cosmos/base/query/v1beta1/pagination.proto
new file mode 100644
index 0000000..784c479
--- /dev/null
+++ b/module/third_party/proto/cosmos/base/query/v1beta1/pagination.proto
@@ -0,0 +1,53 @@
+syntax = "proto3";
+package cosmos.base.query.v1beta1;
+
+option go_package = "github.com/cosmos/cosmos-sdk/types/query";
+
+// PageRequest is to be embedded in gRPC request messages for efficient
+// pagination. Ex:
+//
+// message SomeRequest {
+// Foo some_parameter = 1;
+// PageRequest pagination = 2;
+// }
+message PageRequest {
+ // key is a value returned in PageResponse.next_key to begin
+ // querying the next page most efficiently. Only one of offset or key
+ // should be set.
+ bytes key = 1;
+
+ // offset is a numeric offset that can be used when key is unavailable.
+ // It is less efficient than using key. Only one of offset or key should
+ // be set.
+ uint64 offset = 2;
+
+ // limit is the total number of results to be returned in the result page.
+ // If left empty it will default to a value to be set by each app.
+ uint64 limit = 3;
+
+ // count_total is set to true to indicate that the result set should include
+ // a count of the total number of items available for pagination in UIs.
+ // count_total is only respected when offset is used. It is ignored when key
+ // is set.
+ bool count_total = 4;
+
+ // reverse is set to true if results are to be returned in the descending order.
+ bool reverse = 5;
+}
+
+// PageResponse is to be embedded in gRPC response messages where the
+// corresponding request message has used PageRequest.
+//
+// message SomeResponse {
+// repeated Bar results = 1;
+// PageResponse page = 2;
+// }
+message PageResponse {
+ // next_key is the key to be passed to PageRequest.key to
+ // query the next page most efficiently
+ bytes next_key = 1;
+
+ // total is total number of results available if PageRequest.count_total
+ // was set, its value is undefined otherwise
+ uint64 total = 2;
+}
diff --git a/module/third_party/proto/cosmos/base/v1beta1/coin.proto b/module/third_party/proto/cosmos/base/v1beta1/coin.proto
new file mode 100644
index 0000000..fab7528
--- /dev/null
+++ b/module/third_party/proto/cosmos/base/v1beta1/coin.proto
@@ -0,0 +1,40 @@
+syntax = "proto3";
+package cosmos.base.v1beta1;
+
+import "gogoproto/gogo.proto";
+
+option go_package = "github.com/cosmos/cosmos-sdk/types";
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) = false;
+
+// Coin defines a token with a denomination and an amount.
+//
+// NOTE: The amount field is an Int which implements the custom method
+// signatures required by gogoproto.
+message Coin {
+ option (gogoproto.equal) = true;
+
+ string denom = 1;
+ string amount = 2 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false];
+}
+
+// DecCoin defines a token with a denomination and a decimal amount.
+//
+// NOTE: The amount field is an Dec which implements the custom method
+// signatures required by gogoproto.
+message DecCoin {
+ option (gogoproto.equal) = true;
+
+ string denom = 1;
+ string amount = 2 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false];
+}
+
+// IntProto defines a Protobuf wrapper around an Int object.
+message IntProto {
+ string int = 1 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false];
+}
+
+// DecProto defines a Protobuf wrapper around a Dec object.
+message DecProto {
+ string dec = 1 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false];
+}
diff --git a/module/third_party/proto/cosmos_proto/cosmos.proto b/module/third_party/proto/cosmos_proto/cosmos.proto
new file mode 100644
index 0000000..167b170
--- /dev/null
+++ b/module/third_party/proto/cosmos_proto/cosmos.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+package cosmos_proto;
+
+import "google/protobuf/descriptor.proto";
+
+option go_package = "github.com/regen-network/cosmos-proto";
+
+extend google.protobuf.MessageOptions {
+ string interface_type = 93001;
+
+ string implements_interface = 93002;
+}
+
+extend google.protobuf.FieldOptions {
+ string accepts_interface = 93001;
+}
diff --git a/module/third_party/proto/gogoproto/gogo.proto b/module/third_party/proto/gogoproto/gogo.proto
new file mode 100644
index 0000000..49e78f9
--- /dev/null
+++ b/module/third_party/proto/gogoproto/gogo.proto
@@ -0,0 +1,145 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+package gogoproto;
+
+import "google/protobuf/descriptor.proto";
+
+option java_package = "com.google.protobuf";
+option java_outer_classname = "GoGoProtos";
+option go_package = "github.com/gogo/protobuf/gogoproto";
+
+extend google.protobuf.EnumOptions {
+ optional bool goproto_enum_prefix = 62001;
+ optional bool goproto_enum_stringer = 62021;
+ optional bool enum_stringer = 62022;
+ optional string enum_customname = 62023;
+ optional bool enumdecl = 62024;
+}
+
+extend google.protobuf.EnumValueOptions {
+ optional string enumvalue_customname = 66001;
+}
+
+extend google.protobuf.FileOptions {
+ optional bool goproto_getters_all = 63001;
+ optional bool goproto_enum_prefix_all = 63002;
+ optional bool goproto_stringer_all = 63003;
+ optional bool verbose_equal_all = 63004;
+ optional bool face_all = 63005;
+ optional bool gostring_all = 63006;
+ optional bool populate_all = 63007;
+ optional bool stringer_all = 63008;
+ optional bool onlyone_all = 63009;
+
+ optional bool equal_all = 63013;
+ optional bool description_all = 63014;
+ optional bool testgen_all = 63015;
+ optional bool benchgen_all = 63016;
+ optional bool marshaler_all = 63017;
+ optional bool unmarshaler_all = 63018;
+ optional bool stable_marshaler_all = 63019;
+
+ optional bool sizer_all = 63020;
+
+ optional bool goproto_enum_stringer_all = 63021;
+ optional bool enum_stringer_all = 63022;
+
+ optional bool unsafe_marshaler_all = 63023;
+ optional bool unsafe_unmarshaler_all = 63024;
+
+ optional bool goproto_extensions_map_all = 63025;
+ optional bool goproto_unrecognized_all = 63026;
+ optional bool gogoproto_import = 63027;
+ optional bool protosizer_all = 63028;
+ optional bool compare_all = 63029;
+ optional bool typedecl_all = 63030;
+ optional bool enumdecl_all = 63031;
+
+ optional bool goproto_registration = 63032;
+ optional bool messagename_all = 63033;
+
+ optional bool goproto_sizecache_all = 63034;
+ optional bool goproto_unkeyed_all = 63035;
+}
+
+extend google.protobuf.MessageOptions {
+ optional bool goproto_getters = 64001;
+ optional bool goproto_stringer = 64003;
+ optional bool verbose_equal = 64004;
+ optional bool face = 64005;
+ optional bool gostring = 64006;
+ optional bool populate = 64007;
+ optional bool stringer = 67008;
+ optional bool onlyone = 64009;
+
+ optional bool equal = 64013;
+ optional bool description = 64014;
+ optional bool testgen = 64015;
+ optional bool benchgen = 64016;
+ optional bool marshaler = 64017;
+ optional bool unmarshaler = 64018;
+ optional bool stable_marshaler = 64019;
+
+ optional bool sizer = 64020;
+
+ optional bool unsafe_marshaler = 64023;
+ optional bool unsafe_unmarshaler = 64024;
+
+ optional bool goproto_extensions_map = 64025;
+ optional bool goproto_unrecognized = 64026;
+
+ optional bool protosizer = 64028;
+ optional bool compare = 64029;
+
+ optional bool typedecl = 64030;
+
+ optional bool messagename = 64033;
+
+ optional bool goproto_sizecache = 64034;
+ optional bool goproto_unkeyed = 64035;
+}
+
+extend google.protobuf.FieldOptions {
+ optional bool nullable = 65001;
+ optional bool embed = 65002;
+ optional string customtype = 65003;
+ optional string customname = 65004;
+ optional string jsontag = 65005;
+ optional string moretags = 65006;
+ optional string casttype = 65007;
+ optional string castkey = 65008;
+ optional string castvalue = 65009;
+
+ optional bool stdtime = 65010;
+ optional bool stdduration = 65011;
+ optional bool wktpointer = 65012;
+
+ optional string castrepeated = 65013;
+}
diff --git a/module/third_party/proto/google/api/annotations.proto b/module/third_party/proto/google/api/annotations.proto
new file mode 100644
index 0000000..efdab3d
--- /dev/null
+++ b/module/third_party/proto/google/api/annotations.proto
@@ -0,0 +1,31 @@
+// Copyright 2015 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.api;
+
+import "google/api/http.proto";
+import "google/protobuf/descriptor.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
+option java_multiple_files = true;
+option java_outer_classname = "AnnotationsProto";
+option java_package = "com.google.api";
+option objc_class_prefix = "GAPI";
+
+extend google.protobuf.MethodOptions {
+ // See `HttpRule`.
+ HttpRule http = 72295728;
+}
diff --git a/module/third_party/proto/google/api/http.proto b/module/third_party/proto/google/api/http.proto
new file mode 100644
index 0000000..113fa93
--- /dev/null
+++ b/module/third_party/proto/google/api/http.proto
@@ -0,0 +1,375 @@
+// Copyright 2015 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.api;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
+option java_multiple_files = true;
+option java_outer_classname = "HttpProto";
+option java_package = "com.google.api";
+option objc_class_prefix = "GAPI";
+
+// Defines the HTTP configuration for an API service. It contains a list of
+// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
+// to one or more HTTP REST API methods.
+message Http {
+ // A list of HTTP configuration rules that apply to individual API methods.
+ //
+ // **NOTE:** All service configuration rules follow "last one wins" order.
+ repeated HttpRule rules = 1;
+
+ // When set to true, URL path parameters will be fully URI-decoded except in
+ // cases of single segment matches in reserved expansion, where "%2F" will be
+ // left encoded.
+ //
+ // The default behavior is to not decode RFC 6570 reserved characters in multi
+ // segment matches.
+ bool fully_decode_reserved_expansion = 2;
+}
+
+// # gRPC Transcoding
+//
+// gRPC Transcoding is a feature for mapping between a gRPC method and one or
+// more HTTP REST endpoints. It allows developers to build a single API service
+// that supports both gRPC APIs and REST APIs. Many systems, including [Google
+// APIs](https://github.com/googleapis/googleapis),
+// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC
+// Gateway](https://github.com/grpc-ecosystem/grpc-gateway),
+// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature
+// and use it for large scale production services.
+//
+// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies
+// how different portions of the gRPC request message are mapped to the URL
+// path, URL query parameters, and HTTP request body. It also controls how the
+// gRPC response message is mapped to the HTTP response body. `HttpRule` is
+// typically specified as an `google.api.http` annotation on the gRPC method.
+//
+// Each mapping specifies a URL path template and an HTTP method. The path
+// template may refer to one or more fields in the gRPC request message, as long
+// as each field is a non-repeated field with a primitive (non-message) type.
+// The path template controls how fields of the request message are mapped to
+// the URL path.
+//
+// Example:
+//
+// service Messaging {
+// rpc GetMessage(GetMessageRequest) returns (Message) {
+// option (google.api.http) = {
+// get: "/v1/{name=messages/*}"
+// };
+// }
+// }
+// message GetMessageRequest {
+// string name = 1; // Mapped to URL path.
+// }
+// message Message {
+// string text = 1; // The resource content.
+// }
+//
+// This enables an HTTP REST to gRPC mapping as below:
+//
+// HTTP | gRPC
+// -----|-----
+// `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")`
+//
+// Any fields in the request message which are not bound by the path template
+// automatically become HTTP query parameters if there is no HTTP request body.
+// For example:
+//
+// service Messaging {
+// rpc GetMessage(GetMessageRequest) returns (Message) {
+// option (google.api.http) = {
+// get:"/v1/messages/{message_id}"
+// };
+// }
+// }
+// message GetMessageRequest {
+// message SubMessage {
+// string subfield = 1;
+// }
+// string message_id = 1; // Mapped to URL path.
+// int64 revision = 2; // Mapped to URL query parameter `revision`.
+// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`.
+// }
+//
+// This enables a HTTP JSON to RPC mapping as below:
+//
+// HTTP | gRPC
+// -----|-----
+// `GET /v1/messages/123456?revision=2&sub.subfield=foo` |
+// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield:
+// "foo"))`
+//
+// Note that fields which are mapped to URL query parameters must have a
+// primitive type or a repeated primitive type or a non-repeated message type.
+// In the case of a repeated type, the parameter can be repeated in the URL
+// as `...?param=A¶m=B`. In the case of a message type, each field of the
+// message is mapped to a separate parameter, such as
+// `...?foo.a=A&foo.b=B&foo.c=C`.
+//
+// For HTTP methods that allow a request body, the `body` field
+// specifies the mapping. Consider a REST update method on the
+// message resource collection:
+//
+// service Messaging {
+// rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
+// option (google.api.http) = {
+// patch: "/v1/messages/{message_id}"
+// body: "message"
+// };
+// }
+// }
+// message UpdateMessageRequest {
+// string message_id = 1; // mapped to the URL
+// Message message = 2; // mapped to the body
+// }
+//
+// The following HTTP JSON to RPC mapping is enabled, where the
+// representation of the JSON in the request body is determined by
+// protos JSON encoding:
+//
+// HTTP | gRPC
+// -----|-----
+// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id:
+// "123456" message { text: "Hi!" })`
+//
+// The special name `*` can be used in the body mapping to define that
+// every field not bound by the path template should be mapped to the
+// request body. This enables the following alternative definition of
+// the update method:
+//
+// service Messaging {
+// rpc UpdateMessage(Message) returns (Message) {
+// option (google.api.http) = {
+// patch: "/v1/messages/{message_id}"
+// body: "*"
+// };
+// }
+// }
+// message Message {
+// string message_id = 1;
+// string text = 2;
+// }
+//
+//
+// The following HTTP JSON to RPC mapping is enabled:
+//
+// HTTP | gRPC
+// -----|-----
+// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id:
+// "123456" text: "Hi!")`
+//
+// Note that when using `*` in the body mapping, it is not possible to
+// have HTTP parameters, as all fields not bound by the path end in
+// the body. This makes this option more rarely used in practice when
+// defining REST APIs. The common usage of `*` is in custom methods
+// which don't use the URL at all for transferring data.
+//
+// It is possible to define multiple HTTP methods for one RPC by using
+// the `additional_bindings` option. Example:
+//
+// service Messaging {
+// rpc GetMessage(GetMessageRequest) returns (Message) {
+// option (google.api.http) = {
+// get: "/v1/messages/{message_id}"
+// additional_bindings {
+// get: "/v1/users/{user_id}/messages/{message_id}"
+// }
+// };
+// }
+// }
+// message GetMessageRequest {
+// string message_id = 1;
+// string user_id = 2;
+// }
+//
+// This enables the following two alternative HTTP JSON to RPC mappings:
+//
+// HTTP | gRPC
+// -----|-----
+// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")`
+// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id:
+// "123456")`
+//
+// ## Rules for HTTP mapping
+//
+// 1. Leaf request fields (recursive expansion nested messages in the request
+// message) are classified into three categories:
+// - Fields referred by the path template. They are passed via the URL path.
+// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP
+// request body.
+// - All other fields are passed via the URL query parameters, and the
+// parameter name is the field path in the request message. A repeated
+// field can be represented as multiple query parameters under the same
+// name.
+// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields
+// are passed via URL path and HTTP request body.
+// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all
+// fields are passed via URL path and URL query parameters.
+//
+// ### Path template syntax
+//
+// Template = "/" Segments [ Verb ] ;
+// Segments = Segment { "/" Segment } ;
+// Segment = "*" | "**" | LITERAL | Variable ;
+// Variable = "{" FieldPath [ "=" Segments ] "}" ;
+// FieldPath = IDENT { "." IDENT } ;
+// Verb = ":" LITERAL ;
+//
+// The syntax `*` matches a single URL path segment. The syntax `**` matches
+// zero or more URL path segments, which must be the last part of the URL path
+// except the `Verb`.
+//
+// The syntax `Variable` matches part of the URL path as specified by its
+// template. A variable template must not contain other variables. If a variable
+// matches a single path segment, its template may be omitted, e.g. `{var}`
+// is equivalent to `{var=*}`.
+//
+// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL`
+// contains any reserved character, such characters should be percent-encoded
+// before the matching.
+//
+// If a variable contains exactly one path segment, such as `"{var}"` or
+// `"{var=*}"`, when such a variable is expanded into a URL path on the client
+// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The
+// server side does the reverse decoding. Such variables show up in the
+// [Discovery
+// Document](https://developers.google.com/discovery/v1/reference/apis) as
+// `{var}`.
+//
+// If a variable contains multiple path segments, such as `"{var=foo/*}"`
+// or `"{var=**}"`, when such a variable is expanded into a URL path on the
+// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded.
+// The server side does the reverse decoding, except "%2F" and "%2f" are left
+// unchanged. Such variables show up in the
+// [Discovery
+// Document](https://developers.google.com/discovery/v1/reference/apis) as
+// `{+var}`.
+//
+// ## Using gRPC API Service Configuration
+//
+// gRPC API Service Configuration (service config) is a configuration language
+// for configuring a gRPC service to become a user-facing product. The
+// service config is simply the YAML representation of the `google.api.Service`
+// proto message.
+//
+// As an alternative to annotating your proto file, you can configure gRPC
+// transcoding in your service config YAML files. You do this by specifying a
+// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same
+// effect as the proto annotation. This can be particularly useful if you
+// have a proto that is reused in multiple services. Note that any transcoding
+// specified in the service config will override any matching transcoding
+// configuration in the proto.
+//
+// Example:
+//
+// http:
+// rules:
+// # Selects a gRPC method and applies HttpRule to it.
+// - selector: example.v1.Messaging.GetMessage
+// get: /v1/messages/{message_id}/{sub.subfield}
+//
+// ## Special notes
+//
+// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the
+// proto to JSON conversion must follow the [proto3
+// specification](https://developers.google.com/protocol-buffers/docs/proto3#json).
+//
+// While the single segment variable follows the semantics of
+// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String
+// Expansion, the multi segment variable **does not** follow RFC 6570 Section
+// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion
+// does not expand special characters like `?` and `#`, which would lead
+// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding
+// for multi segment variables.
+//
+// The path variables **must not** refer to any repeated or mapped field,
+// because client libraries are not capable of handling such variable expansion.
+//
+// The path variables **must not** capture the leading "/" character. The reason
+// is that the most common use case "{var}" does not capture the leading "/"
+// character. For consistency, all path variables must share the same behavior.
+//
+// Repeated message fields must not be mapped to URL query parameters, because
+// no client library can support such complicated mapping.
+//
+// If an API needs to use a JSON array for request or response body, it can map
+// the request or response body to a repeated field. However, some gRPC
+// Transcoding implementations may not support this feature.
+message HttpRule {
+ // Selects a method to which this rule applies.
+ //
+ // Refer to [selector][google.api.DocumentationRule.selector] for syntax details.
+ string selector = 1;
+
+ // Determines the URL pattern is matched by this rules. This pattern can be
+ // used with any of the {get|put|post|delete|patch} methods. A custom method
+ // can be defined using the 'custom' field.
+ oneof pattern {
+ // Maps to HTTP GET. Used for listing and getting information about
+ // resources.
+ string get = 2;
+
+ // Maps to HTTP PUT. Used for replacing a resource.
+ string put = 3;
+
+ // Maps to HTTP POST. Used for creating a resource or performing an action.
+ string post = 4;
+
+ // Maps to HTTP DELETE. Used for deleting a resource.
+ string delete = 5;
+
+ // Maps to HTTP PATCH. Used for updating a resource.
+ string patch = 6;
+
+ // The custom pattern is used for specifying an HTTP method that is not
+ // included in the `pattern` field, such as HEAD, or "*" to leave the
+ // HTTP method unspecified for this rule. The wild-card rule is useful
+ // for services that provide content to Web (HTML) clients.
+ CustomHttpPattern custom = 8;
+ }
+
+ // The name of the request field whose value is mapped to the HTTP request
+ // body, or `*` for mapping all request fields not captured by the path
+ // pattern to the HTTP body, or omitted for not having any HTTP request body.
+ //
+ // NOTE: the referred field must be present at the top-level of the request
+ // message type.
+ string body = 7;
+
+ // Optional. The name of the response field whose value is mapped to the HTTP
+ // response body. When omitted, the entire response message will be used
+ // as the HTTP response body.
+ //
+ // NOTE: The referred field must be present at the top-level of the response
+ // message type.
+ string response_body = 12;
+
+ // Additional HTTP bindings for the selector. Nested bindings must
+ // not contain an `additional_bindings` field themselves (that is,
+ // the nesting may only be one level deep).
+ repeated HttpRule additional_bindings = 11;
+}
+
+// A custom pattern is used for defining custom HTTP verb.
+message CustomHttpPattern {
+ // The name of this custom HTTP verb.
+ string kind = 1;
+
+ // The path matched by this custom verb.
+ string path = 2;
+}
diff --git a/module/third_party/proto/google/api/httpbody.proto b/module/third_party/proto/google/api/httpbody.proto
new file mode 100644
index 0000000..596ba35
--- /dev/null
+++ b/module/third_party/proto/google/api/httpbody.proto
@@ -0,0 +1,77 @@
+// Copyright 2015 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.api;
+
+import "google/protobuf/any.proto";
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody";
+option java_multiple_files = true;
+option java_outer_classname = "HttpBodyProto";
+option java_package = "com.google.api";
+option objc_class_prefix = "GAPI";
+
+// Message that represents an arbitrary HTTP body. It should only be used for
+// payload formats that can't be represented as JSON, such as raw binary or
+// an HTML page.
+//
+//
+// This message can be used both in streaming and non-streaming API methods in
+// the request as well as the response.
+//
+// It can be used as a top-level request field, which is convenient if one
+// wants to extract parameters from either the URL or HTTP template into the
+// request fields and also want access to the raw HTTP body.
+//
+// Example:
+//
+// message GetResourceRequest {
+// // A unique request id.
+// string request_id = 1;
+//
+// // The raw HTTP body is bound to this field.
+// google.api.HttpBody http_body = 2;
+// }
+//
+// service ResourceService {
+// rpc GetResource(GetResourceRequest) returns (google.api.HttpBody);
+// rpc UpdateResource(google.api.HttpBody) returns
+// (google.protobuf.Empty);
+// }
+//
+// Example with streaming methods:
+//
+// service CaldavService {
+// rpc GetCalendar(stream google.api.HttpBody)
+// returns (stream google.api.HttpBody);
+// rpc UpdateCalendar(stream google.api.HttpBody)
+// returns (stream google.api.HttpBody);
+// }
+//
+// Use of this type only changes how the request and response bodies are
+// handled, all other features will continue to work unchanged.
+message HttpBody {
+ // The HTTP Content-Type header value specifying the content type of the body.
+ string content_type = 1;
+
+ // The HTTP request/response body as raw binary.
+ bytes data = 2;
+
+ // Application specific response metadata. Must be set in the first response
+ // for streaming APIs.
+ repeated google.protobuf.Any extensions = 3;
+}
diff --git a/module/third_party/proto/google/protobuf/any.proto b/module/third_party/proto/google/protobuf/any.proto
new file mode 100644
index 0000000..6ed8a23
--- /dev/null
+++ b/module/third_party/proto/google/protobuf/any.proto
@@ -0,0 +1,158 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package google.protobuf;
+
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option go_package = "google.golang.org/protobuf/types/known/anypb";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "AnyProto";
+option java_multiple_files = true;
+option objc_class_prefix = "GPB";
+
+// `Any` contains an arbitrary serialized protocol buffer message along with a
+// URL that describes the type of the serialized message.
+//
+// Protobuf library provides support to pack/unpack Any values in the form
+// of utility functions or additional generated methods of the Any type.
+//
+// Example 1: Pack and unpack a message in C++.
+//
+// Foo foo = ...;
+// Any any;
+// any.PackFrom(foo);
+// ...
+// if (any.UnpackTo(&foo)) {
+// ...
+// }
+//
+// Example 2: Pack and unpack a message in Java.
+//
+// Foo foo = ...;
+// Any any = Any.pack(foo);
+// ...
+// if (any.is(Foo.class)) {
+// foo = any.unpack(Foo.class);
+// }
+//
+// Example 3: Pack and unpack a message in Python.
+//
+// foo = Foo(...)
+// any = Any()
+// any.Pack(foo)
+// ...
+// if any.Is(Foo.DESCRIPTOR):
+// any.Unpack(foo)
+// ...
+//
+// Example 4: Pack and unpack a message in Go
+//
+// foo := &pb.Foo{...}
+// any, err := anypb.New(foo)
+// if err != nil {
+// ...
+// }
+// ...
+// foo := &pb.Foo{}
+// if err := any.UnmarshalTo(foo); err != nil {
+// ...
+// }
+//
+// The pack methods provided by protobuf library will by default use
+// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+// methods only use the fully qualified type name after the last '/'
+// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+// name "y.z".
+//
+//
+// JSON
+// ====
+// The JSON representation of an `Any` value uses the regular
+// representation of the deserialized, embedded message, with an
+// additional field `@type` which contains the type URL. Example:
+//
+// package google.profile;
+// message Person {
+// string first_name = 1;
+// string last_name = 2;
+// }
+//
+// {
+// "@type": "type.googleapis.com/google.profile.Person",
+// "firstName": ,
+// "lastName":
+// }
+//
+// If the embedded message type is well-known and has a custom JSON
+// representation, that representation will be embedded adding a field
+// `value` which holds the custom JSON in addition to the `@type`
+// field. Example (for message [google.protobuf.Duration][]):
+//
+// {
+// "@type": "type.googleapis.com/google.protobuf.Duration",
+// "value": "1.212s"
+// }
+//
+message Any {
+ // A URL/resource name that uniquely identifies the type of the serialized
+ // protocol buffer message. This string must contain at least
+ // one "/" character. The last segment of the URL's path must represent
+ // the fully qualified name of the type (as in
+ // `path/google.protobuf.Duration`). The name should be in a canonical form
+ // (e.g., leading "." is not accepted).
+ //
+ // In practice, teams usually precompile into the binary all types that they
+ // expect it to use in the context of Any. However, for URLs which use the
+ // scheme `http`, `https`, or no scheme, one can optionally set up a type
+ // server that maps type URLs to message definitions as follows:
+ //
+ // * If no scheme is provided, `https` is assumed.
+ // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+ // value in binary format, or produce an error.
+ // * Applications are allowed to cache lookup results based on the
+ // URL, or have them precompiled into a binary to avoid any
+ // lookup. Therefore, binary compatibility needs to be preserved
+ // on changes to types. (Use versioned type names to manage
+ // breaking changes.)
+ //
+ // Note: this functionality is not currently available in the official
+ // protobuf release, and it is not used for type URLs beginning with
+ // type.googleapis.com.
+ //
+ // Schemes other than `http`, `https` (or the empty scheme) might be
+ // used with implementation specific semantics.
+ //
+ string type_url = 1;
+
+ // Must be a valid serialized protocol buffer of the above specified type.
+ bytes value = 2;
+}
diff --git a/module/third_party/proto/tendermint/abci/types.proto b/module/third_party/proto/tendermint/abci/types.proto
new file mode 100644
index 0000000..c08cca2
--- /dev/null
+++ b/module/third_party/proto/tendermint/abci/types.proto
@@ -0,0 +1,401 @@
+syntax = "proto3";
+package tendermint.abci;
+
+option go_package = "github.com/tendermint/tendermint/abci/types";
+
+// For more information on gogo.proto, see:
+// https://github.com/gogo/protobuf/blob/master/extensions.md
+import "tendermint/crypto/proof.proto";
+import "tendermint/types/types.proto";
+import "tendermint/crypto/keys.proto";
+import "tendermint/types/params.proto";
+import "google/protobuf/timestamp.proto";
+import "gogoproto/gogo.proto";
+
+// This file is copied from http://github.com/tendermint/abci
+// NOTE: When using custom types, mind the warnings.
+// https://github.com/gogo/protobuf/blob/master/custom_types.md#warnings-and-issues
+
+//----------------------------------------
+// Request types
+
+message Request {
+ oneof value {
+ RequestEcho echo = 1;
+ RequestFlush flush = 2;
+ RequestInfo info = 3;
+ RequestSetOption set_option = 4;
+ RequestInitChain init_chain = 5;
+ RequestQuery query = 6;
+ RequestBeginBlock begin_block = 7;
+ RequestCheckTx check_tx = 8;
+ RequestDeliverTx deliver_tx = 9;
+ RequestEndBlock end_block = 10;
+ RequestCommit commit = 11;
+ RequestListSnapshots list_snapshots = 12;
+ RequestOfferSnapshot offer_snapshot = 13;
+ RequestLoadSnapshotChunk load_snapshot_chunk = 14;
+ RequestApplySnapshotChunk apply_snapshot_chunk = 15;
+ }
+}
+
+message RequestEcho {
+ string message = 1;
+}
+
+message RequestFlush {}
+
+message RequestInfo {
+ string version = 1;
+ uint64 block_version = 2;
+ uint64 p2p_version = 3;
+}
+
+// nondeterministic
+message RequestSetOption {
+ string key = 1;
+ string value = 2;
+}
+
+message RequestInitChain {
+ google.protobuf.Timestamp time = 1
+ [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+ string chain_id = 2;
+ ConsensusParams consensus_params = 3;
+ repeated ValidatorUpdate validators = 4 [(gogoproto.nullable) = false];
+ bytes app_state_bytes = 5;
+ int64 initial_height = 6;
+}
+
+message RequestQuery {
+ bytes data = 1;
+ string path = 2;
+ int64 height = 3;
+ bool prove = 4;
+}
+
+message RequestBeginBlock {
+ bytes hash = 1;
+ tendermint.types.Header header = 2 [(gogoproto.nullable) = false];
+ LastCommitInfo last_commit_info = 3 [(gogoproto.nullable) = false];
+ repeated Evidence byzantine_validators = 4 [(gogoproto.nullable) = false];
+}
+
+enum CheckTxType {
+ NEW = 0 [(gogoproto.enumvalue_customname) = "New"];
+ RECHECK = 1 [(gogoproto.enumvalue_customname) = "Recheck"];
+}
+
+message RequestCheckTx {
+ bytes tx = 1;
+ CheckTxType type = 2;
+}
+
+message RequestDeliverTx {
+ bytes tx = 1;
+}
+
+message RequestEndBlock {
+ int64 height = 1;
+}
+
+message RequestCommit {}
+
+// lists available snapshots
+message RequestListSnapshots {
+}
+
+// offers a snapshot to the application
+message RequestOfferSnapshot {
+ Snapshot snapshot = 1; // snapshot offered by peers
+ bytes app_hash = 2; // light client-verified app hash for snapshot height
+}
+
+// loads a snapshot chunk
+message RequestLoadSnapshotChunk {
+ uint64 height = 1;
+ uint32 format = 2;
+ uint32 chunk = 3;
+}
+
+// Applies a snapshot chunk
+message RequestApplySnapshotChunk {
+ uint32 index = 1;
+ bytes chunk = 2;
+ string sender = 3;
+}
+
+//----------------------------------------
+// Response types
+
+message Response {
+ oneof value {
+ ResponseException exception = 1;
+ ResponseEcho echo = 2;
+ ResponseFlush flush = 3;
+ ResponseInfo info = 4;
+ ResponseSetOption set_option = 5;
+ ResponseInitChain init_chain = 6;
+ ResponseQuery query = 7;
+ ResponseBeginBlock begin_block = 8;
+ ResponseCheckTx check_tx = 9;
+ ResponseDeliverTx deliver_tx = 10;
+ ResponseEndBlock end_block = 11;
+ ResponseCommit commit = 12;
+ ResponseListSnapshots list_snapshots = 13;
+ ResponseOfferSnapshot offer_snapshot = 14;
+ ResponseLoadSnapshotChunk load_snapshot_chunk = 15;
+ ResponseApplySnapshotChunk apply_snapshot_chunk = 16;
+ }
+}
+
+// nondeterministic
+message ResponseException {
+ string error = 1;
+}
+
+message ResponseEcho {
+ string message = 1;
+}
+
+message ResponseFlush {}
+
+message ResponseInfo {
+ string data = 1;
+
+ string version = 2;
+ uint64 app_version = 3;
+
+ int64 last_block_height = 4;
+ bytes last_block_app_hash = 5;
+}
+
+// nondeterministic
+message ResponseSetOption {
+ uint32 code = 1;
+ // bytes data = 2;
+ string log = 3;
+ string info = 4;
+}
+
+message ResponseInitChain {
+ ConsensusParams consensus_params = 1;
+ repeated ValidatorUpdate validators = 2 [(gogoproto.nullable) = false];
+ bytes app_hash = 3;
+}
+
+message ResponseQuery {
+ uint32 code = 1;
+ // bytes data = 2; // use "value" instead.
+ string log = 3; // nondeterministic
+ string info = 4; // nondeterministic
+ int64 index = 5;
+ bytes key = 6;
+ bytes value = 7;
+ tendermint.crypto.ProofOps proof_ops = 8;
+ int64 height = 9;
+ string codespace = 10;
+}
+
+message ResponseBeginBlock {
+ repeated Event events = 1
+ [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"];
+}
+
+message ResponseCheckTx {
+ uint32 code = 1;
+ bytes data = 2;
+ string log = 3; // nondeterministic
+ string info = 4; // nondeterministic
+ int64 gas_wanted = 5 [json_name = "gas_wanted"];
+ int64 gas_used = 6 [json_name = "gas_used"];
+ repeated Event events = 7
+ [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"];
+ string codespace = 8;
+}
+
+message ResponseDeliverTx {
+ uint32 code = 1;
+ bytes data = 2;
+ string log = 3; // nondeterministic
+ string info = 4; // nondeterministic
+ int64 gas_wanted = 5 [json_name = "gas_wanted"];
+ int64 gas_used = 6 [json_name = "gas_used"];
+ repeated Event events = 7
+ [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"];
+ string codespace = 8;
+}
+
+message ResponseEndBlock {
+ repeated ValidatorUpdate validator_updates = 1
+ [(gogoproto.nullable) = false];
+ ConsensusParams consensus_param_updates = 2;
+ repeated Event events = 3
+ [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"];
+}
+
+message ResponseCommit {
+ // reserve 1
+ bytes data = 2;
+ int64 retain_height = 3;
+}
+
+message ResponseListSnapshots {
+ repeated Snapshot snapshots = 1;
+}
+
+message ResponseOfferSnapshot {
+ Result result = 1;
+
+ enum Result {
+ UNKNOWN = 0; // Unknown result, abort all snapshot restoration
+ ACCEPT = 1; // Snapshot accepted, apply chunks
+ ABORT = 2; // Abort all snapshot restoration
+ REJECT = 3; // Reject this specific snapshot, try others
+ REJECT_FORMAT = 4; // Reject all snapshots of this format, try others
+ REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others
+ }
+}
+
+message ResponseLoadSnapshotChunk {
+ bytes chunk = 1;
+}
+
+message ResponseApplySnapshotChunk {
+ Result result = 1;
+ repeated uint32 refetch_chunks = 2; // Chunks to refetch and reapply
+ repeated string reject_senders = 3; // Chunk senders to reject and ban
+
+ enum Result {
+ UNKNOWN = 0; // Unknown result, abort all snapshot restoration
+ ACCEPT = 1; // Chunk successfully accepted
+ ABORT = 2; // Abort all snapshot restoration
+ RETRY = 3; // Retry chunk (combine with refetch and reject)
+ RETRY_SNAPSHOT = 4; // Retry snapshot (combine with refetch and reject)
+ REJECT_SNAPSHOT = 5; // Reject this snapshot, try others
+ }
+}
+
+//----------------------------------------
+// Misc.
+
+// ConsensusParams contains all consensus-relevant parameters
+// that can be adjusted by the abci app
+message ConsensusParams {
+ BlockParams block = 1;
+ tendermint.types.EvidenceParams evidence = 2;
+ tendermint.types.ValidatorParams validator = 3;
+ tendermint.types.VersionParams version = 4;
+}
+
+// BlockParams contains limits on the block size.
+message BlockParams {
+ // Note: must be greater than 0
+ int64 max_bytes = 1;
+ // Note: must be greater or equal to -1
+ int64 max_gas = 2;
+}
+
+message LastCommitInfo {
+ int32 round = 1;
+ repeated VoteInfo votes = 2 [(gogoproto.nullable) = false];
+}
+
+// Event allows application developers to attach additional information to
+// ResponseBeginBlock, ResponseEndBlock, ResponseCheckTx and ResponseDeliverTx.
+// Later, transactions may be queried using these events.
+message Event {
+ string type = 1;
+ repeated EventAttribute attributes = 2 [
+ (gogoproto.nullable) = false,
+ (gogoproto.jsontag) = "attributes,omitempty"
+ ];
+}
+
+// EventAttribute is a single key-value pair, associated with an event.
+message EventAttribute {
+ bytes key = 1;
+ bytes value = 2;
+ bool index = 3; // nondeterministic
+}
+
+// TxResult contains results of executing the transaction.
+//
+// One usage is indexing transaction results.
+message TxResult {
+ int64 height = 1;
+ uint32 index = 2;
+ bytes tx = 3;
+ ResponseDeliverTx result = 4 [(gogoproto.nullable) = false];
+}
+
+//----------------------------------------
+// Blockchain Types
+
+// Validator
+message Validator {
+ bytes address = 1; // The first 20 bytes of SHA256(public key)
+ // PubKey pub_key = 2 [(gogoproto.nullable)=false];
+ int64 power = 3; // The voting power
+}
+
+// ValidatorUpdate
+message ValidatorUpdate {
+ tendermint.crypto.PublicKey pub_key = 1 [(gogoproto.nullable) = false];
+ int64 power = 2;
+}
+
+// VoteInfo
+message VoteInfo {
+ Validator validator = 1 [(gogoproto.nullable) = false];
+ bool signed_last_block = 2;
+}
+
+message Evidence {
+ string type = 1;
+ // The offending validator
+ Validator validator = 2 [(gogoproto.nullable) = false];
+ // The height when the offense occurred
+ int64 height = 3;
+ // The corresponding time where the offense occurred
+ google.protobuf.Timestamp time = 4 [
+ (gogoproto.nullable) = false,
+ (gogoproto.stdtime) = true
+ ];
+ // Total voting power of the validator set in case the ABCI application does
+ // not store historical validators.
+ // https://github.com/tendermint/tendermint/issues/4581
+ int64 total_voting_power = 5;
+}
+
+//----------------------------------------
+// State Sync Types
+
+message Snapshot {
+ uint64 height = 1; // The height at which the snapshot was taken
+ uint32 format = 2; // The application-specific snapshot format
+ uint32 chunks = 3; // Number of chunks in the snapshot
+ bytes hash = 4; // Arbitrary snapshot hash, equal only if identical
+ bytes metadata = 5; // Arbitrary application metadata
+}
+
+//----------------------------------------
+// Service Definition
+
+service ABCIApplication {
+ rpc Echo(RequestEcho) returns (ResponseEcho);
+ rpc Flush(RequestFlush) returns (ResponseFlush);
+ rpc Info(RequestInfo) returns (ResponseInfo);
+ rpc SetOption(RequestSetOption) returns (ResponseSetOption);
+ rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx);
+ rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx);
+ rpc Query(RequestQuery) returns (ResponseQuery);
+ rpc Commit(RequestCommit) returns (ResponseCommit);
+ rpc InitChain(RequestInitChain) returns (ResponseInitChain);
+ rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock);
+ rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock);
+ rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots);
+ rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot);
+ rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) returns (ResponseLoadSnapshotChunk);
+ rpc ApplySnapshotChunk(RequestApplySnapshotChunk) returns (ResponseApplySnapshotChunk);
+}
diff --git a/module/third_party/proto/tendermint/crypto/keys.proto b/module/third_party/proto/tendermint/crypto/keys.proto
new file mode 100644
index 0000000..e3a8ce9
--- /dev/null
+++ b/module/third_party/proto/tendermint/crypto/keys.proto
@@ -0,0 +1,24 @@
+syntax = "proto3";
+package tendermint.crypto;
+
+option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto";
+
+import "gogoproto/gogo.proto";
+
+// PublicKey defines the keys available for use with Tendermint Validators
+message PublicKey {
+ option (gogoproto.compare) = true;
+ option (gogoproto.equal) = true;
+
+ oneof sum {
+ bytes ed25519 = 1;
+ }
+}
+
+// PrivateKey defines the keys available for use with Tendermint Validators
+// WARNING PrivateKey is used for internal purposes only
+message PrivateKey {
+ oneof sum {
+ bytes ed25519 = 1;
+ }
+}
diff --git a/module/third_party/proto/tendermint/crypto/proof.proto b/module/third_party/proto/tendermint/crypto/proof.proto
new file mode 100644
index 0000000..975df76
--- /dev/null
+++ b/module/third_party/proto/tendermint/crypto/proof.proto
@@ -0,0 +1,41 @@
+syntax = "proto3";
+package tendermint.crypto;
+
+option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto";
+
+import "gogoproto/gogo.proto";
+
+message Proof {
+ int64 total = 1;
+ int64 index = 2;
+ bytes leaf_hash = 3;
+ repeated bytes aunts = 4;
+}
+
+message ValueOp {
+ // Encoded in ProofOp.Key.
+ bytes key = 1;
+
+ // To encode in ProofOp.Data
+ Proof proof = 2;
+}
+
+message DominoOp {
+ string key = 1;
+ string input = 2;
+ string output = 3;
+}
+
+// ProofOp defines an operation used for calculating Merkle root
+// The data could be arbitrary format, providing nessecary data
+// for example neighbouring node hash
+message ProofOp {
+ string type = 1;
+ bytes key = 2;
+ bytes data = 3;
+}
+
+// ProofOps is Merkle proof defined by the list of ProofOps
+message ProofOps {
+ repeated ProofOp ops = 1 [(gogoproto.nullable) = false];
+}
diff --git a/module/third_party/proto/tendermint/libs/bits/types.proto b/module/third_party/proto/tendermint/libs/bits/types.proto
new file mode 100644
index 0000000..3111d11
--- /dev/null
+++ b/module/third_party/proto/tendermint/libs/bits/types.proto
@@ -0,0 +1,9 @@
+syntax = "proto3";
+package tendermint.libs.bits;
+
+option go_package = "github.com/tendermint/tendermint/proto/tendermint/libs/bits";
+
+message BitArray {
+ int64 bits = 1;
+ repeated uint64 elems = 2;
+}
diff --git a/module/third_party/proto/tendermint/types/evidence.proto b/module/third_party/proto/tendermint/types/evidence.proto
new file mode 100644
index 0000000..c2bb74c
--- /dev/null
+++ b/module/third_party/proto/tendermint/types/evidence.proto
@@ -0,0 +1,68 @@
+syntax = "proto3";
+package tendermint.types;
+
+option go_package = "github.com/tendermint/tendermint/proto/tendermint/types";
+
+import "gogoproto/gogo.proto";
+import "google/protobuf/timestamp.proto";
+import "tendermint/types/types.proto";
+import "tendermint/crypto/keys.proto";
+
+// DuplicateVoteEvidence contains evidence a validator signed two conflicting
+// votes.
+message DuplicateVoteEvidence {
+ Vote vote_a = 1;
+ Vote vote_b = 2;
+
+ google.protobuf.Timestamp timestamp = 3
+ [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+}
+
+message PotentialAmnesiaEvidence {
+ Vote vote_a = 1;
+ Vote vote_b = 2;
+
+ int64 height_stamp = 3;
+ google.protobuf.Timestamp timestamp = 4
+ [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+}
+
+message AmnesiaEvidence {
+ PotentialAmnesiaEvidence potential_amnesia_evidence = 1;
+ ProofOfLockChange polc = 2;
+}
+
+message ConflictingHeadersEvidence {
+ SignedHeader h1 = 1;
+ SignedHeader h2 = 2;
+}
+
+message LunaticValidatorEvidence {
+ Header header = 1;
+ Vote vote = 2;
+ string invalid_header_field = 3;
+
+ google.protobuf.Timestamp timestamp = 4
+ [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+}
+
+message Evidence {
+ oneof sum {
+ DuplicateVoteEvidence duplicate_vote_evidence = 1;
+ ConflictingHeadersEvidence conflicting_headers_evidence = 2;
+ LunaticValidatorEvidence lunatic_validator_evidence = 3;
+ PotentialAmnesiaEvidence potential_amnesia_evidence = 4;
+ AmnesiaEvidence amnesia_evidence = 5;
+ }
+}
+
+// EvidenceData contains any evidence of malicious wrong-doing by validators
+message EvidenceData {
+ repeated Evidence evidence = 1 [(gogoproto.nullable) = false];
+ bytes hash = 2;
+}
+
+message ProofOfLockChange {
+ repeated Vote votes = 1;
+ tendermint.crypto.PublicKey pub_key = 2;
+}
diff --git a/module/third_party/proto/tendermint/types/params.proto b/module/third_party/proto/tendermint/types/params.proto
new file mode 100644
index 0000000..33ed4f7
--- /dev/null
+++ b/module/third_party/proto/tendermint/types/params.proto
@@ -0,0 +1,86 @@
+syntax = "proto3";
+package tendermint.types;
+
+option go_package = "github.com/tendermint/tendermint/proto/tendermint/types";
+
+import "gogoproto/gogo.proto";
+import "google/protobuf/duration.proto";
+
+option (gogoproto.equal_all) = true;
+
+// ConsensusParams contains consensus critical parameters that determine the
+// validity of blocks.
+message ConsensusParams {
+ BlockParams block = 1 [(gogoproto.nullable) = false];
+ EvidenceParams evidence = 2 [(gogoproto.nullable) = false];
+ ValidatorParams validator = 3 [(gogoproto.nullable) = false];
+ VersionParams version = 4 [(gogoproto.nullable) = false];
+}
+
+// BlockParams contains limits on the block size.
+message BlockParams {
+ // Max block size, in bytes.
+ // Note: must be greater than 0
+ int64 max_bytes = 1;
+ // Max gas per block.
+ // Note: must be greater or equal to -1
+ int64 max_gas = 2;
+ // Minimum time increment between consecutive blocks (in milliseconds) If the
+ // block header timestamp is ahead of the system clock, decrease this value.
+ //
+ // Not exposed to the application.
+ int64 time_iota_ms = 3;
+}
+
+// EvidenceParams determine how we handle evidence of malfeasance.
+message EvidenceParams {
+ // Max age of evidence, in blocks.
+ //
+ // The basic formula for calculating this is: MaxAgeDuration / {average block
+ // time}.
+ int64 max_age_num_blocks = 1;
+
+ // Max age of evidence, in time.
+ //
+ // It should correspond with an app's "unbonding period" or other similar
+ // mechanism for handling [Nothing-At-Stake
+ // attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed).
+ google.protobuf.Duration max_age_duration = 2
+ [(gogoproto.nullable) = false, (gogoproto.stdduration) = true];
+
+ // This sets the maximum number of evidence that can be committed in a single block.
+ // and should fall comfortably under the max block bytes when we consider the size of
+ // each evidence (See MaxEvidenceBytes). The maximum number is MaxEvidencePerBlock.
+ // Default is 50
+ uint32 max_num = 3;
+
+ // Proof trial period dictates the time given for nodes accused of amnesia evidence, incorrectly
+ // voting twice in two different rounds to respond with their respective proofs.
+ // Default is half the max age in blocks: 50,000
+ int64 proof_trial_period = 4;
+}
+
+// ValidatorParams restrict the public key types validators can use.
+// NOTE: uses ABCI pubkey naming, not Amino names.
+message ValidatorParams {
+ option (gogoproto.populate) = true;
+ option (gogoproto.equal) = true;
+
+ repeated string pub_key_types = 1;
+}
+
+// VersionParams contains the ABCI application version.
+message VersionParams {
+ option (gogoproto.populate) = true;
+ option (gogoproto.equal) = true;
+
+ uint64 app_version = 1;
+}
+
+// HashedParams is a subset of ConsensusParams.
+//
+// It is hashed into the Header.ConsensusHash.
+message HashedParams {
+ int64 block_max_bytes = 1;
+ int64 block_max_gas = 2;
+}
diff --git a/module/third_party/proto/tendermint/types/types.proto b/module/third_party/proto/tendermint/types/types.proto
new file mode 100644
index 0000000..7ba7de8
--- /dev/null
+++ b/module/third_party/proto/tendermint/types/types.proto
@@ -0,0 +1,156 @@
+syntax = "proto3";
+package tendermint.types;
+
+option go_package = "github.com/tendermint/tendermint/proto/tendermint/types";
+
+import "gogoproto/gogo.proto";
+import "google/protobuf/timestamp.proto";
+import "tendermint/libs/bits/types.proto";
+import "tendermint/crypto/proof.proto";
+import "tendermint/version/types.proto";
+
+// BlockIdFlag indicates which BlcokID the signature is for
+enum BlockIDFlag {
+ option (gogoproto.goproto_enum_stringer) = true;
+ option (gogoproto.goproto_enum_prefix) = false;
+
+ BLOCK_ID_FLAG_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"];
+ BLOCK_ID_FLAG_ABSENT = 1 [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"];
+ BLOCK_ID_FLAG_COMMIT = 2 [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"];
+ BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"];
+}
+
+// SignedMsgType is a type of signed message in the consensus.
+enum SignedMsgType {
+ option (gogoproto.goproto_enum_stringer) = true;
+ option (gogoproto.goproto_enum_prefix) = false;
+
+ SIGNED_MSG_TYPE_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "UnknownType"];
+ // Votes
+ SIGNED_MSG_TYPE_PREVOTE = 1 [(gogoproto.enumvalue_customname) = "PrevoteType"];
+ SIGNED_MSG_TYPE_PRECOMMIT = 2 [(gogoproto.enumvalue_customname) = "PrecommitType"];
+
+ // Proposals
+ SIGNED_MSG_TYPE_PROPOSAL = 32 [(gogoproto.enumvalue_customname) = "ProposalType"];
+}
+
+// PartsetHeader
+message PartSetHeader {
+ uint32 total = 1;
+ bytes hash = 2;
+}
+
+message Part {
+ uint32 index = 1;
+ bytes bytes = 2;
+ tendermint.crypto.Proof proof = 3 [(gogoproto.nullable) = false];
+}
+
+// BlockID
+message BlockID {
+ bytes hash = 1;
+ PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false];
+}
+
+// --------------------------------
+
+// Header defines the structure of a Tendermint block header.
+message Header {
+ // basic block info
+ tendermint.version.Consensus version = 1 [(gogoproto.nullable) = false];
+ string chain_id = 2 [(gogoproto.customname) = "ChainID"];
+ int64 height = 3;
+ google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+
+ // prev block info
+ BlockID last_block_id = 5 [(gogoproto.nullable) = false];
+
+ // hashes of block data
+ bytes last_commit_hash = 6; // commit from validators from the last block
+ bytes data_hash = 7; // transactions
+
+ // hashes from the app output from the prev block
+ bytes validators_hash = 8; // validators for the current block
+ bytes next_validators_hash = 9; // validators for the next block
+ bytes consensus_hash = 10; // consensus params for current block
+ bytes app_hash = 11; // state after txs from the previous block
+ bytes last_results_hash = 12; // root hash of all results from the txs from the previous block
+
+ // consensus info
+ bytes evidence_hash = 13; // evidence included in the block
+ bytes proposer_address = 14; // original proposer of the block
+}
+
+// Data contains the set of transactions included in the block
+message Data {
+ // Txs that will be applied by state @ block.Height+1.
+ // NOTE: not all txs here are valid. We're just agreeing on the order first.
+ // This means that block.AppHash does not include these txs.
+ repeated bytes txs = 1;
+ // Volatile
+ bytes hash = 2;
+}
+
+// Vote represents a prevote, precommit, or commit vote from validators for
+// consensus.
+message Vote {
+ SignedMsgType type = 1;
+ int64 height = 2;
+ int32 round = 3;
+ BlockID block_id = 4
+ [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; // zero if vote is nil.
+ google.protobuf.Timestamp timestamp = 5
+ [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+ bytes validator_address = 6;
+ int32 validator_index = 7;
+ bytes signature = 8;
+}
+
+// Commit contains the evidence that a block was committed by a set of validators.
+message Commit {
+ int64 height = 1;
+ int32 round = 2;
+ BlockID block_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"];
+ repeated CommitSig signatures = 4 [(gogoproto.nullable) = false];
+ bytes hash = 5;
+ tendermint.libs.bits.BitArray bit_array = 6;
+}
+
+// CommitSig is a part of the Vote included in a Commit.
+message CommitSig {
+ BlockIDFlag block_id_flag = 1;
+ bytes validator_address = 2;
+ google.protobuf.Timestamp timestamp = 3
+ [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+ bytes signature = 4;
+}
+
+message Proposal {
+ SignedMsgType type = 1;
+ int64 height = 2;
+ int32 round = 3;
+ int32 pol_round = 4;
+ BlockID block_id = 5 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false];
+ google.protobuf.Timestamp timestamp = 6
+ [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+ bytes signature = 7;
+}
+
+message SignedHeader {
+ Header header = 1;
+ Commit commit = 2;
+}
+
+message BlockMeta {
+ BlockID block_id = 1 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false];
+ int64 block_size = 2;
+ Header header = 3 [(gogoproto.nullable) = false];
+ int64 num_txs = 4;
+}
+
+// TxProof represents a Merkle proof of the presence of a transaction in the Merkle tree.
+message TxProof {
+ bytes root_hash = 1;
+ bytes data = 2;
+ tendermint.crypto.Proof proof = 3;
+}
diff --git a/module/third_party/proto/tendermint/version/types.proto b/module/third_party/proto/tendermint/version/types.proto
new file mode 100644
index 0000000..6061868
--- /dev/null
+++ b/module/third_party/proto/tendermint/version/types.proto
@@ -0,0 +1,24 @@
+syntax = "proto3";
+package tendermint.version;
+
+option go_package = "github.com/tendermint/tendermint/proto/tendermint/version";
+
+import "gogoproto/gogo.proto";
+
+// App includes the protocol and software version for the application.
+// This information is included in ResponseInfo. The App.Protocol can be
+// updated in ResponseEndBlock.
+message App {
+ uint64 protocol = 1;
+ string software = 2;
+}
+
+// Consensus captures the consensus rules for processing a block in the blockchain,
+// including all blockchain data structures and the rules of the application's
+// state transition machine.
+message Consensus {
+ option (gogoproto.equal) = true;
+
+ uint64 block = 1;
+ uint64 app = 2;
+}
diff --git a/module/x/.gitkeep b/module/x/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/module/x/gravity/abci.go b/module/x/gravity/abci.go
new file mode 100644
index 0000000..e1728b2
--- /dev/null
+++ b/module/x/gravity/abci.go
@@ -0,0 +1,288 @@
+package gravity
+
+import (
+ "sort"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/keeper"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+ "github.com/ethereum/go-ethereum/common"
+)
+
+// BeginBlocker is called at the beginning of every block
+// NOTE: begin blocker also emits events which are helpful for
+// clients listening to the chain and creating transactions
+// based on the events (i.e. orchestrators)
+func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
+ cleanupTimedOutBatchTxs(ctx, k)
+ cleanupTimedOutContractCallTxs(ctx, k)
+ createSignerSetTxs(ctx, k)
+ createBatchTxs(ctx, k)
+ pruneSignerSetTxs(ctx, k)
+}
+
+// EndBlocker is called at the end of every block
+func EndBlocker(ctx sdk.Context, k keeper.Keeper) {
+ outgoingTxSlashing(ctx, k)
+ eventVoteRecordTally(ctx, k)
+}
+
+func createBatchTxs(ctx sdk.Context, k keeper.Keeper) {
+ // TODO: this needs some more work, is super naieve
+ if ctx.BlockHeight()%10 == 0 {
+ cm := map[string]bool{}
+ k.IterateUnbatchedSendToEthereums(ctx, func(ste *types.SendToEthereum) bool {
+ cm[ste.Erc20Token.Contract] = true
+ return false
+ })
+
+ var contracts []string
+ for k := range cm {
+ contracts = append(contracts, k)
+ }
+
+ for _, c := range contracts {
+ // NOTE: this doesn't emit events which would be helpful for client processes
+ k.BuildBatchTx(ctx, common.HexToAddress(c), 100)
+ }
+ }
+}
+
+func createSignerSetTxs(ctx sdk.Context, k keeper.Keeper) {
+ // Auto signerset tx creation.
+ // 1. If there are no signer set requests, create a new one.
+ // 2. If there is at least one validator who started unbonding in current block. (we persist last unbonded block height in hooks.go)
+ // This will make sure the unbonding validator has to provide an ethereum signature to a new signer set tx
+ // that excludes him before he completely Unbonds. Otherwise he will be slashed
+ // 3. If power change between validators of Current signer set and latest signer set request is > 5%
+ latestSignerSetTx := k.GetLatestSignerSetTx(ctx)
+ if latestSignerSetTx == nil {
+ k.CreateSignerSetTx(ctx)
+ return
+ }
+
+ lastUnbondingHeight := k.GetLastUnbondingBlockHeight(ctx)
+ blockHeight := uint64(ctx.BlockHeight())
+ powerDiff := types.EthereumSigners(k.CurrentSignerSet(ctx)).PowerDiff(latestSignerSetTx.Signers)
+
+ shouldCreate := (lastUnbondingHeight == blockHeight) || (powerDiff > 0.05)
+ k.Logger(ctx).Info(
+ "considering signer set tx creation",
+ "blockHeight", blockHeight,
+ "lastUnbondingHeight", lastUnbondingHeight,
+ "latestSignerSetTx.Nonce", latestSignerSetTx.Nonce,
+ "powerDiff", powerDiff,
+ "shouldCreate", shouldCreate,
+ )
+
+ if shouldCreate {
+ k.CreateSignerSetTx(ctx)
+ }
+}
+
+func pruneSignerSetTxs(ctx sdk.Context, k keeper.Keeper) {
+ params := k.GetParams(ctx)
+ // Validator set pruning
+ // prune all validator sets with a nonce less than the
+ // last observed nonce, they can't be submitted any longer
+ //
+ // Only prune valsets after the signed valsets window has passed
+ // so that slashing can occur the block before we remove them
+ lastObserved := k.GetLastObservedSignerSetTx(ctx)
+ currentBlock := uint64(ctx.BlockHeight())
+ tooEarly := currentBlock < params.SignedSignerSetTxsWindow
+ if lastObserved != nil && !tooEarly {
+ earliestToPrune := currentBlock - params.SignedSignerSetTxsWindow
+ for _, set := range k.GetSignerSetTxs(ctx) {
+ if set.Nonce < lastObserved.Nonce && set.Height < earliestToPrune {
+ k.DeleteOutgoingTx(ctx, set.GetStoreIndex())
+ }
+ }
+ }
+}
+
+// Iterate over all attestations currently being voted on in order of nonce and
+// "Observe" those who have passed the threshold. Break the loop once we see
+// an attestation that has not passed the threshold
+func eventVoteRecordTally(ctx sdk.Context, k keeper.Keeper) {
+ attmap := k.GetEthereumEventVoteRecordMapping(ctx)
+
+ // We make a slice with all the event nonces that are in the attestation mapping
+ keys := make([]uint64, 0, len(attmap))
+ for k := range attmap {
+ keys = append(keys, k)
+ }
+ // Then we sort it
+ sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
+
+ // This iterates over all keys (event nonces) in the attestation mapping. Each value contains
+ // a slice with one or more attestations at that event nonce. There can be multiple attestations
+ // at one event nonce when validators disagree about what event happened at that nonce.
+ for _, nonce := range keys {
+ // This iterates over all attestations at a particular event nonce.
+ // They are ordered by when the first attestation at the event nonce was received.
+ // This order is not important.
+ for _, att := range attmap[nonce] {
+ // We check if the event nonce is exactly 1 higher than the last attestation that was
+ // observed. If it is not, we just move on to the next nonce. This will skip over all
+ // attestations that have already been observed.
+ //
+ // Once we hit an event nonce that is one higher than the last observed event, we stop
+ // skipping over this conditional and start calling tryAttestation (counting votes)
+ // Once an attestation at a given event nonce has enough votes and becomes observed,
+ // every other attestation at that nonce will be skipped, since the lastObservedEventNonce
+ // will be incremented.
+ //
+ // Then we go to the next event nonce in the attestation mapping, if there is one. This
+ // nonce will once again be one higher than the lastObservedEventNonce.
+ // If there is an attestation at this event nonce which has enough votes to be observed,
+ // we skip the other attestations and move on to the next nonce again.
+ // If no attestation becomes observed, when we get to the next nonce, every attestation in
+ // it will be skipped. The same will happen for every nonce after that.
+ if nonce == uint64(k.GetLastObservedEventNonce(ctx))+1 {
+ k.TryEventVoteRecord(ctx, att)
+ }
+ }
+ }
+}
+
+// cleanupTimedOutBatchTxs deletes batches that have passed their expiration on Ethereum
+// keep in mind several things when modifying this function
+// A) unlike nonces timeouts are not monotonically increasing, meaning batch 5 can have a later timeout than batch 6
+// this means that we MUST only cleanup a single batch at a time
+// B) it is possible for ethereumHeight to be zero if no events have ever occurred, make sure your code accounts for this
+// C) When we compute the timeout we do our best to estimate the Ethereum block height at that very second. But what we work with
+// here is the Ethereum block height at the time of the last Deposit or Withdraw to be observed. It's very important we do not
+// project, if we do a slowdown on ethereum could cause a double spend. Instead timeouts will *only* occur after the timeout period
+// AND any deposit or withdraw has occurred to update the Ethereum block height.
+func cleanupTimedOutBatchTxs(ctx sdk.Context, k keeper.Keeper) {
+ ethereumHeight := k.GetLastObservedEthereumBlockHeight(ctx).EthereumHeight
+ k.IterateOutgoingTxsByType(ctx, types.BatchTxPrefixByte, func(key []byte, otx types.OutgoingTx) bool {
+ btx, _ := otx.(*types.BatchTx)
+
+ if btx.Timeout < ethereumHeight {
+ k.CancelBatchTx(ctx, common.HexToAddress(btx.TokenContract), btx.BatchNonce)
+ }
+
+ return false
+ })
+}
+
+// cleanupTimedOutBatchTxs deletes logic calls that have passed their expiration on Ethereum
+// keep in mind several things when modifying this function
+// A) unlike nonces timeouts are not monotonically increasing, meaning call 5 can have a later timeout than batch 6
+// this means that we MUST only cleanup a single call at a time
+// B) it is possible for ethereumHeight to be zero if no events have ever occurred, make sure your code accounts for this
+// C) When we compute the timeout we do our best to estimate the Ethereum block height at that very second. But what we work with
+// here is the Ethereum block height at the time of the last Deposit or Withdraw to be observed. It's very important we do not
+// project, if we do a slowdown on ethereum could cause a double spend. Instead timeouts will *only* occur after the timeout period
+// AND any deposit or withdraw has occurred to update the Ethereum block height.
+func cleanupTimedOutContractCallTxs(ctx sdk.Context, k keeper.Keeper) {
+ ethereumHeight := k.GetLastObservedEthereumBlockHeight(ctx).EthereumHeight
+ k.IterateOutgoingTxsByType(ctx, types.ContractCallTxPrefixByte, func(_ []byte, otx types.OutgoingTx) bool {
+ cctx, _ := otx.(*types.ContractCallTx)
+ if cctx.Timeout < ethereumHeight {
+ k.DeleteOutgoingTx(ctx, cctx.GetStoreIndex())
+ }
+ return true
+ })
+}
+
+func outgoingTxSlashing(ctx sdk.Context, k keeper.Keeper) {
+ params := k.GetParams(ctx)
+ maxHeight := uint64(0)
+ if uint64(ctx.BlockHeight()) > params.SignedBatchesWindow {
+ maxHeight = uint64(ctx.BlockHeight()) - params.SignedBatchesWindow
+ } else {
+ return
+ }
+
+ usotxs := k.GetUnSlashedOutgoingTxs(ctx, maxHeight)
+ if len(usotxs) == 0 {
+ return
+ }
+
+ // get signing info for each validator
+ type valInfo struct {
+ val stakingtypes.Validator
+ exist bool
+ sigs slashingtypes.ValidatorSigningInfo
+ cons sdk.ConsAddress
+ }
+
+ var valInfos []valInfo
+
+ for _, val := range k.StakingKeeper.GetBondedValidatorsByPower(ctx) {
+ consAddr, _ := val.GetConsAddr()
+ sigs, exist := k.SlashingKeeper.GetValidatorSigningInfo(ctx, consAddr)
+ valInfos = append(valInfos, valInfo{val, exist, sigs, consAddr})
+ }
+
+ var unbondingValInfos []valInfo
+
+ blockTime := ctx.BlockTime().Add(k.StakingKeeper.GetParams(ctx).UnbondingTime)
+ blockHeight := ctx.BlockHeight()
+ unbondingValIterator := k.StakingKeeper.ValidatorQueueIterator(ctx, blockTime, blockHeight)
+ defer unbondingValIterator.Close()
+
+ // All unbonding validators
+ for ; unbondingValIterator.Valid(); unbondingValIterator.Next() {
+ unbondingValidators := k.GetUnbondingvalidators(unbondingValIterator.Value())
+ for _, valAddr := range unbondingValidators.Addresses {
+ addr, _ := sdk.ValAddressFromBech32(valAddr)
+ validator, _ := k.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addr))
+ valConsAddr, _ := validator.GetConsAddr()
+ valSigningInfo, exist := k.SlashingKeeper.GetValidatorSigningInfo(ctx, valConsAddr)
+ unbondingValInfos = append(unbondingValInfos, valInfo{validator, exist, valSigningInfo, valConsAddr})
+ }
+ }
+
+ for _, otx := range usotxs {
+ // SLASH BONDED VALIDATORS who didn't sign batch txs
+ signatures := k.GetEthereumSignatures(ctx, otx.GetStoreIndex())
+ for _, valInfo := range valInfos {
+ // Don't slash validators who joined after outgoingtx is created
+ if valInfo.exist && valInfo.sigs.StartHeight < int64(otx.GetCosmosHeight()) {
+ if _, ok := signatures[valInfo.val.GetOperator().String()]; !ok {
+ if !valInfo.val.IsJailed() {
+ k.StakingKeeper.Slash(
+ ctx,
+ valInfo.cons,
+ ctx.BlockHeight(),
+ valInfo.val.ConsensusPower(k.PowerReduction),
+ params.SlashFractionBatch,
+ )
+ k.StakingKeeper.Jail(ctx, valInfo.cons)
+ }
+ }
+ }
+ }
+
+ if sstx, ok := otx.(*types.SignerSetTx); ok {
+ for _, valInfo := range unbondingValInfos {
+ // Only slash validators who joined after valset is created and they are unbonding and UNBOND_SLASHING_WINDOW didn't pass
+ if valInfo.exist && valInfo.sigs.StartHeight < int64(sstx.Nonce) && valInfo.val.IsUnbonding() && sstx.Height < uint64(valInfo.val.UnbondingHeight)+params.UnbondSlashingSignerSetTxsWindow {
+ // Check if validator has confirmed valset or not
+ if _, found := signatures[valInfo.val.GetOperator().String()]; !found {
+ if !valInfo.val.IsJailed() {
+ // TODO: do we want to slash jailed validators
+ k.StakingKeeper.Slash(
+ ctx,
+ valInfo.cons,
+ ctx.BlockHeight(),
+ valInfo.val.ConsensusPower(k.PowerReduction),
+ params.SlashFractionSignerSetTx,
+ )
+ k.StakingKeeper.Jail(ctx, valInfo.cons)
+ }
+ }
+ }
+ }
+ }
+
+ // then we set the latest slashed outgoing tx block
+ k.SetLastSlashedOutgoingTxBlockHeight(ctx, otx.GetCosmosHeight())
+ }
+}
diff --git a/module/x/gravity/abci_test.go b/module/x/gravity/abci_test.go
new file mode 100644
index 0000000..6a90707
--- /dev/null
+++ b/module/x/gravity/abci_test.go
@@ -0,0 +1,316 @@
+package gravity_test
+
+import (
+ "fmt"
+ "testing"
+ "time"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
+ "github.com/cosmos/cosmos-sdk/x/staking"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/require"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/keeper"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+func TestSignerSetTxCreationIfNotAvailable(t *testing.T) {
+ input, ctx := keeper.SetupFiveValChain(t)
+ gravityKeeper := input.GravityKeeper
+
+ // BeginBlocker should set a new validator set if not available
+ gravity.BeginBlocker(ctx, gravityKeeper)
+ otx := gravityKeeper.GetOutgoingTx(ctx, types.MakeSignerSetTxKey(1))
+ require.NotNil(t, otx)
+ _, ok := otx.(*types.SignerSetTx)
+ require.True(t, ok)
+ require.True(t, len(gravityKeeper.GetSignerSetTxs(ctx)) == 1)
+}
+
+func TestSignerSetTxCreationUponUnbonding(t *testing.T) {
+ input, ctx := keeper.SetupFiveValChain(t)
+ gravityKeeper := input.GravityKeeper
+ gravityKeeper.CreateSignerSetTx(ctx)
+
+ input.Context = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
+ // begin unbonding
+ sh := staking.NewHandler(input.StakingKeeper)
+ undelegateMsg := keeper.NewTestMsgUnDelegateValidator(keeper.ValAddrs[0], keeper.StakingAmount)
+ sh(input.Context, undelegateMsg)
+
+ // Run the staking endblocker to ensure signer set tx is set in state
+ staking.EndBlocker(input.Context, input.StakingKeeper)
+ gravity.BeginBlocker(input.Context, gravityKeeper)
+
+ require.EqualValues(t, 2, gravityKeeper.GetLatestSignerSetTxNonce(ctx))
+}
+
+func TestSignerSetTxSlashing_SignerSetTxCreated_Before_ValidatorBonded(t *testing.T) {
+ // Don't slash validators if signer set tx is created before he is bonded.
+
+ input, ctx := keeper.SetupFiveValChain(t)
+ pk := input.GravityKeeper
+ params := input.GravityKeeper.GetParams(ctx)
+
+ signerSet := pk.CreateSignerSetTx(ctx)
+ height := uint64(ctx.BlockHeight()) - (params.SignedSignerSetTxsWindow + 1)
+ signerSet.Height = height
+ pk.SetOutgoingTx(ctx, signerSet)
+
+ gravity.EndBlocker(ctx, pk)
+
+ // ensure that the validator who is bonded after signer set tx is created is not slashed
+ val := input.StakingKeeper.Validator(ctx, keeper.ValAddrs[0])
+ require.False(t, val.IsJailed())
+}
+
+func TestSignerSetTxSlashing_SignerSetTxCreated_After_ValidatorBonded(t *testing.T) {
+ // Slashing Conditions for Bonded Validator
+
+ input, ctx := keeper.SetupFiveValChain(t)
+ pk := input.GravityKeeper
+ params := input.GravityKeeper.GetParams(ctx)
+
+ ctx = ctx.WithBlockHeight(ctx.BlockHeight() + int64(params.SignedSignerSetTxsWindow) + 2)
+ signerSet := pk.CreateSignerSetTx(ctx)
+ height := uint64(ctx.BlockHeight()) - (params.SignedSignerSetTxsWindow + 1)
+ signerSet.Height = height
+ pk.SetOutgoingTx(ctx, signerSet)
+
+ for i, val := range keeper.ValAddrs {
+ if i == 0 {
+ continue
+ }
+ pk.SetEthereumSignature(ctx, &types.SignerSetTxConfirmation{signerSet.Nonce, keeper.AccAddrs[i].String(), []byte("dummysig")}, val)
+ }
+
+ gravity.EndBlocker(ctx, pk)
+
+ // ensure that the validator who is bonded before signer set tx is created is slashed
+ val := input.StakingKeeper.Validator(ctx, keeper.ValAddrs[0])
+ require.True(t, val.IsJailed())
+
+ // ensure that the validator who attested the signer set tx is not slashed.
+ val = input.StakingKeeper.Validator(ctx, keeper.ValAddrs[1])
+ require.False(t, val.IsJailed())
+
+}
+
+func TestSignerSetTxSlashing_UnbondingValidator_UnbondWindow_NotExpired(t *testing.T) {
+ // Slashing Conditions for Unbonding Validator
+
+ // Create 5 validators
+ input, ctx := keeper.SetupFiveValChain(t)
+ // val := input.StakingKeeper.Validator(ctx, keeper.ValAddrs[0])
+ // fmt.Println("val1 tokens", val.GetTokens().ToDec())
+
+ gravityKeeper := input.GravityKeeper
+ params := input.GravityKeeper.GetParams(ctx)
+
+ // Define slashing variables
+ validatorStartHeight := ctx.BlockHeight() // 0
+ signerSetTxHeight := validatorStartHeight + 1 // 1
+ valUnbondingHeight := signerSetTxHeight + 1 // 2
+ signerSetTxSlashedAt := signerSetTxHeight + int64(params.SignedSignerSetTxsWindow) // 11
+ validatorUnbondingWindowExpiry := valUnbondingHeight + int64(params.UnbondSlashingSignerSetTxsWindow) // 17
+ currentBlockHeight := signerSetTxSlashedAt + 1 // 12
+
+ require.True(t, signerSetTxSlashedAt < currentBlockHeight)
+ require.True(t, signerSetTxHeight < validatorUnbondingWindowExpiry)
+
+ // Create signer set tx request
+ ctx = ctx.WithBlockHeight(signerSetTxHeight)
+ vs := gravityKeeper.CreateSignerSetTx(ctx)
+ vs.Height = uint64(signerSetTxHeight)
+ vs.Nonce = uint64(signerSetTxHeight)
+ gravityKeeper.SetOutgoingTx(ctx, vs)
+
+ // Start Unbonding validators
+ // Validator-1 Unbond slash window is not expired. if not attested, slash
+ // Validator-2 Unbond slash window is not expired. if attested, don't slash
+ input.Context = ctx.WithBlockHeight(valUnbondingHeight)
+ sh := staking.NewHandler(input.StakingKeeper)
+ undelegateMsg1 := keeper.NewTestMsgUnDelegateValidator(keeper.ValAddrs[0], keeper.StakingAmount)
+ sh(input.Context, undelegateMsg1)
+ undelegateMsg2 := keeper.NewTestMsgUnDelegateValidator(keeper.ValAddrs[1], keeper.StakingAmount)
+ sh(input.Context, undelegateMsg2)
+
+ for i, val := range keeper.ValAddrs {
+ if i == 0 {
+ // don't sign with first validator
+ continue
+ }
+ gravityKeeper.SetEthereumSignature(ctx, &types.SignerSetTxConfirmation{vs.Nonce, keeper.EthAddrs[i].Hex(), []byte("dummySig")}, val)
+ }
+ staking.EndBlocker(input.Context, input.StakingKeeper)
+
+ ctx = ctx.WithBlockHeight(currentBlockHeight)
+ gravity.EndBlocker(ctx, gravityKeeper)
+
+ // Assertions
+ val1 := input.StakingKeeper.Validator(ctx, keeper.ValAddrs[0])
+ require.True(t, val1.IsJailed())
+ fmt.Println("val1 tokens", val1.GetTokens().ToDec())
+ // check if tokens are slashed for val1.
+
+ val2 := input.StakingKeeper.Validator(ctx, keeper.ValAddrs[1])
+ require.True(t, val2.IsJailed())
+ fmt.Println("val2 tokens", val2.GetTokens().ToDec())
+ // check if tokens shouldn't be slashed for val2.
+}
+
+func TestBatchSlashing(t *testing.T) {
+ input, ctx := keeper.SetupFiveValChain(t)
+ gravityKeeper := input.GravityKeeper
+ params := gravityKeeper.GetParams(ctx)
+
+ ctx = ctx.WithBlockHeight(ctx.BlockHeight() + int64(params.SignedBatchesWindow) + 2)
+
+ // First store a batch
+ batch := &types.BatchTx{
+ BatchNonce: 1,
+ Transactions: []*types.SendToEthereum{},
+ TokenContract: keeper.TokenContractAddrs[0],
+ Height: uint64(ctx.BlockHeight() - int64(params.SignedBatchesWindow+1)),
+ }
+ gravityKeeper.SetOutgoingTx(ctx, batch)
+
+ for i, val := range keeper.ValAddrs {
+ if i == 0 {
+ // don't sign with first validator
+ continue
+ }
+ if i == 1 {
+ // don't sign with 2nd validator. set val bond height > batch block height
+ validator := input.StakingKeeper.Validator(ctx, keeper.ValAddrs[i])
+ valConsAddr, _ := validator.GetConsAddr()
+ valSigningInfo := slashingtypes.ValidatorSigningInfo{StartHeight: int64(batch.Height + 1)}
+ input.SlashingKeeper.SetValidatorSigningInfo(ctx, valConsAddr, valSigningInfo)
+ continue
+ }
+ gravityKeeper.SetEthereumSignature(ctx, &types.BatchTxConfirmation{
+ BatchNonce: batch.BatchNonce,
+ TokenContract: keeper.TokenContractAddrs[0],
+ EthereumSigner: keeper.EthAddrs[i].String(),
+ Signature: []byte("dummysig"),
+ }, val)
+ }
+
+ gravity.EndBlocker(ctx, gravityKeeper)
+
+ // ensure that the validator is jailed and slashed
+ require.True(t, input.StakingKeeper.Validator(ctx, keeper.ValAddrs[0]).IsJailed())
+
+ // ensure that the 2nd validator is not jailed and slashed
+ require.False(t, input.StakingKeeper.Validator(ctx, keeper.ValAddrs[1]).IsJailed())
+
+ // Ensure that the last slashed signer set tx nonce is set properly
+ require.Equal(t, input.GravityKeeper.GetLastSlashedOutgoingTxBlockHeight(ctx), batch.Height)
+}
+
+func TestSignerSetTxEmission(t *testing.T) {
+ input, ctx := keeper.SetupFiveValChain(t)
+ gravityKeeper := input.GravityKeeper
+
+ // Store a validator set with a power change as the most recent validator set
+ sstx := gravityKeeper.CreateSignerSetTx(ctx)
+ delta := float64(types.EthereumSigners(sstx.Signers).TotalPower()) * 0.05
+ sstx.Signers[0].Power = uint64(float64(sstx.Signers[0].Power) - delta/2)
+ sstx.Signers[1].Power = uint64(float64(sstx.Signers[1].Power) + delta/2)
+ gravityKeeper.SetOutgoingTx(ctx, sstx)
+
+ // BeginBlocker should set a new validator set
+ gravity.BeginBlocker(ctx, gravityKeeper)
+ require.NotNil(t, gravityKeeper.GetOutgoingTx(ctx, types.MakeSignerSetTxKey(2)))
+ require.EqualValues(t, 2, len(gravityKeeper.GetSignerSetTxs(ctx)))
+}
+
+func TestSignerSetTxSetting(t *testing.T) {
+ input, ctx := keeper.SetupFiveValChain(t)
+ gk := input.GravityKeeper
+ gk.CreateSignerSetTx(ctx)
+ require.EqualValues(t, 1, len(gk.GetSignerSetTxs(ctx)))
+}
+
+/// Test batch timeout
+func TestBatchTxTimeout(t *testing.T) {
+ input, ctx := keeper.SetupFiveValChain(t)
+ gravityKeeper := input.GravityKeeper
+ params := gravityKeeper.GetParams(ctx)
+ var (
+ now = time.Now().UTC()
+ mySender, _ = sdk.AccAddressFromBech32("cosmos1ahx7f8wyertuus9r20284ej0asrs085case3kn")
+ myReceiver = common.HexToAddress("0xd041c41EA1bf0F006ADBb6d2c9ef9D425dE5eaD7")
+ myTokenContractAddr = common.HexToAddress("0x429881672B9AE42b8EbA0E26cD9C73711b891Ca5") // Pickle
+ allVouchers = sdk.NewCoins(types.NewERC20Token(99999, myTokenContractAddr.Hex()).GravityCoin())
+ )
+
+ require.Greater(t, params.AverageBlockTime, uint64(0))
+ require.Greater(t, params.AverageEthereumBlockTime, uint64(0))
+
+ // mint some vouchers first
+ require.NoError(t, input.BankKeeper.MintCoins(ctx, types.ModuleName, allVouchers))
+ // set senders balance
+ input.AccountKeeper.NewAccountWithAddress(ctx, mySender)
+ require.NoError(t, fundAccount(ctx, input.BankKeeper, mySender, allVouchers))
+
+ // add some TX to the pool
+ input.AddSendToEthTxsToPool(t, ctx, myTokenContractAddr, mySender, myReceiver, 2, 3, 2, 1, 5, 6)
+
+ // when
+ ctx = ctx.WithBlockTime(now).WithBlockHeight(250)
+
+ // check that we can make a batch without first setting an ethereum block height
+ b1 := gravityKeeper.BuildBatchTx(ctx, myTokenContractAddr, 2)
+ require.Equal(t, b1.Timeout, uint64(0))
+
+ gravityKeeper.SetLastObservedEthereumBlockHeight(ctx, 500)
+
+ b2 := gravityKeeper.BuildBatchTx(ctx, myTokenContractAddr, 2)
+ // this is exactly block 500 plus twelve hours
+ require.Equal(t, b2.Timeout, uint64(504))
+
+ // make sure the batches got stored in the first place
+ gotFirstBatch := input.GravityKeeper.GetOutgoingTx(ctx, types.MakeBatchTxKey(common.HexToAddress(b1.TokenContract), b1.BatchNonce))
+ require.NotNil(t, gotFirstBatch)
+ gotSecondBatch := input.GravityKeeper.GetOutgoingTx(ctx, types.MakeBatchTxKey(common.HexToAddress(b2.TokenContract), b2.BatchNonce))
+ require.NotNil(t, gotSecondBatch)
+
+ // when, way into the future
+ ctx = ctx.WithBlockTime(now).WithBlockHeight(9)
+
+ b3 := gravityKeeper.BuildBatchTx(ctx, myTokenContractAddr, 2)
+
+ gravity.BeginBlocker(ctx, gravityKeeper)
+
+ // this had a timeout of zero should be deleted.
+ gotFirstBatch = input.GravityKeeper.GetOutgoingTx(ctx, types.MakeBatchTxKey(common.HexToAddress(b1.TokenContract), b1.BatchNonce))
+ require.Nil(t, gotFirstBatch)
+ // make sure the end blocker does not delete these, as the block height has not officially
+ // been updated by a relay event
+ gotSecondBatch = input.GravityKeeper.GetOutgoingTx(ctx, types.MakeBatchTxKey(common.HexToAddress(b2.TokenContract), b2.BatchNonce))
+ require.NotNil(t, gotSecondBatch)
+ gotThirdBatch := input.GravityKeeper.GetOutgoingTx(ctx, types.MakeBatchTxKey(common.HexToAddress(b3.TokenContract), b3.BatchNonce))
+ require.NotNil(t, gotThirdBatch)
+
+ gravityKeeper.SetLastObservedEthereumBlockHeight(ctx, 5000)
+ gravity.BeginBlocker(ctx, gravityKeeper)
+
+ // make sure the end blocker does delete these, as we've got a new Ethereum block height
+ gotFirstBatch = input.GravityKeeper.GetOutgoingTx(ctx, types.MakeBatchTxKey(common.HexToAddress(b1.TokenContract), b1.BatchNonce))
+ require.Nil(t, gotFirstBatch)
+ gotSecondBatch = input.GravityKeeper.GetOutgoingTx(ctx, types.MakeBatchTxKey(common.HexToAddress(b2.TokenContract), b2.BatchNonce))
+ require.Nil(t, gotSecondBatch)
+ gotThirdBatch = input.GravityKeeper.GetOutgoingTx(ctx, types.MakeBatchTxKey(common.HexToAddress(b3.TokenContract), b3.BatchNonce))
+ require.NotNil(t, gotThirdBatch)
+}
+
+func fundAccount(ctx sdk.Context, bankKeeper types.BankKeeper, addr sdk.AccAddress, amounts sdk.Coins) error {
+ if err := bankKeeper.MintCoins(ctx, types.ModuleName, amounts); err != nil {
+ return err
+ }
+
+ return bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, amounts)
+}
diff --git a/module/x/gravity/client/cli/query.go b/module/x/gravity/client/cli/query.go
new file mode 100644
index 0000000..4a87ed9
--- /dev/null
+++ b/module/x/gravity/client/cli/query.go
@@ -0,0 +1,837 @@
+package cli
+
+import (
+ "fmt"
+ "strconv"
+
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/spf13/cobra"
+)
+
+func GetQueryCmd() *cobra.Command {
+ gravityQueryCmd := &cobra.Command{
+ Use: types.ModuleName,
+ Short: "Querying commands for the gravity module",
+ DisableFlagParsing: true,
+ SuggestionsMinimumDistance: 2,
+ RunE: client.ValidateCmd,
+ }
+ gravityQueryCmd.AddCommand(
+ CmdBatchTx(),
+ CmdBatchTxConfirmations(),
+ CmdBatchTxFees(),
+ CmdBatchTxs(),
+ CmdContractCallTx(),
+ CmdContractCallTxConfirmations(),
+ CmdContractCallTxs(),
+ CmdDenomToERC20Params(),
+ CmdERC20ToDenom(),
+ CmdLastSubmittedEthereumEvent(),
+ CmdLatestSignerSetTx(),
+ CmdParams(),
+ CmdSignerSetTx(),
+ CmdSignerSetTxConfirmations(),
+ CmdSignerSetTxs(),
+ CmdUnsignedBatchTxs(),
+ CmdUnsignedContractCallTxs(),
+ CmdUnsignedSignerSetTxs(),
+ CmdDenomToERC20(),
+ CmdUnbatchedSendToEthereums(),
+ CmdDelegateKeysByValidator(),
+ CmdDelegateKeysByEthereumSigner(),
+ CmdDelegateKeysByOrchestrator(),
+ CmdDelegateKeys(),
+ )
+
+ return gravityQueryCmd
+}
+
+func CmdParams() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "params",
+ Args: cobra.NoArgs,
+ Short: "Query votes on a proposal",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ req := types.ParamsRequest{}
+
+ res, err := queryClient.Params(cmd.Context(), &req)
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdSignerSetTx() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "signer-set-tx [nonce]",
+ Args: cobra.ExactArgs(1),
+ Short: "query an individual signer set transaction by its nonce",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ nonce, err := parseNonce(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.SignerSetTx(cmd.Context(), &types.SignerSetTxRequest{SignerSetNonce: nonce})
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdBatchTx() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "batch-tx [contract-address] [nonce]",
+ Args: cobra.ExactArgs(2),
+ Short: "query an outgoing batch by its contract address and nonce",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ contractAddress, err := parseContractAddress(args[0])
+ if err != nil {
+ return nil
+ }
+
+ nonce, err := parseNonce(args[1])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.BatchTx(cmd.Context(), &types.BatchTxRequest{
+ TokenContract: contractAddress,
+ BatchNonce: nonce,
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdContractCallTx() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "contract-call-tx [invalidation-scope] [invalidation-nonce]",
+ Args: cobra.ExactArgs(2),
+ Short: "query an outgoing contract call by scope and nonce",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ // TODO: validate this scope somehow
+ invalidationScope := []byte(args[0])
+
+ invalidationNonce, err := parseNonce(args[1])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.ContractCallTx(cmd.Context(), &types.ContractCallTxRequest{
+ InvalidationScope: invalidationScope,
+ InvalidationNonce: invalidationNonce,
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdSignerSetTxs() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "signer-set-txs",
+ Args: cobra.NoArgs,
+ Short: "query all the signer set transactions from the chain",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ pageReq, err := client.ReadPageRequest(cmd.Flags())
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.SignerSetTxs(cmd.Context(), &types.SignerSetTxsRequest{Pagination: pageReq})
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ flags.AddPaginationFlagsToCmd(cmd, "signer-set-txs")
+ return cmd
+}
+
+func CmdBatchTxs() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "batch-txs",
+ Args: cobra.NoArgs,
+ Short: "query all the batch transactions from the chain",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ pageReq, err := client.ReadPageRequest(cmd.Flags())
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.BatchTxs(cmd.Context(), &types.BatchTxsRequest{Pagination: pageReq})
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ flags.AddPaginationFlagsToCmd(cmd, "batch-txs")
+ return cmd
+}
+
+func CmdContractCallTxs() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "contract-call-txs",
+ Args: cobra.NoArgs,
+ Short: "query all contract call transactions from the chain",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ pageReq, err := client.ReadPageRequest(cmd.Flags())
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.ContractCallTxs(cmd.Context(), &types.ContractCallTxsRequest{Pagination: pageReq})
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ flags.AddPaginationFlagsToCmd(cmd, "contract-call-txs")
+ return cmd
+}
+
+func CmdSignerSetTxConfirmations() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "signer-set-tx-ethereum-signatures [nonce]",
+ Args: cobra.ExactArgs(1),
+ Short: "query signer set transaction signatures from the validators identified by nonce",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ nonce, err := parseNonce(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.SignerSetTxConfirmations(cmd.Context(), &types.SignerSetTxConfirmationsRequest{
+ SignerSetNonce: nonce,
+ })
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdBatchTxConfirmations() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "batch-tx-ethereum-signatures [nonce] [contract-address]",
+ Args: cobra.ExactArgs(2),
+ Short: "query signatures for a given batch transaction identified by nonce and contract",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ nonce, err := parseNonce(args[0])
+ if err != nil {
+ return err
+ }
+
+ contractAddress, err := parseContractAddress(args[1])
+ if err != nil {
+ return nil
+ }
+
+ res, err := queryClient.BatchTxConfirmations(cmd.Context(), &types.BatchTxConfirmationsRequest{
+ BatchNonce: nonce,
+ TokenContract: contractAddress,
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdContractCallTxConfirmations() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "contract-call-tx-ethereum-signatures [invalidation-scope] [invalidation-nonce]",
+ Args: cobra.MinimumNArgs(2),
+ Short: "query signatures for a given contract call transaction identified by invalidation nonce and invalidation scope",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ // TODO: some sort of validation here?
+ invalidationScope := []byte(args[0])
+
+ invalidationNonce, err := parseNonce(args[1])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.ContractCallTxConfirmations(cmd.Context(), &types.ContractCallTxConfirmationsRequest{
+ InvalidationNonce: invalidationNonce,
+ InvalidationScope: invalidationScope,
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdUnsignedSignerSetTxs() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "pending-signer-set-tx-ethereum-signatures [validator-or-orchestrator-acc-address]",
+ Args: cobra.ExactArgs(1),
+ Short: "query signatures for any pending signer set transactions given a validator or orchestrator address (sdk.AccAddress format)",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ address, err := sdk.AccAddressFromBech32(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.UnsignedSignerSetTxs(cmd.Context(), &types.UnsignedSignerSetTxsRequest{
+ Address: address.String(),
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdUnsignedBatchTxs() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "pending-batch-tx-ethereum-signatures [validator-or-orchestrator-acc-address]",
+ Args: cobra.ExactArgs(1),
+ Short: "query signatures for any pending batch transactions given a validator or orchestrator address (sdk.AccAddress format)",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ address, err := sdk.AccAddressFromBech32(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.UnsignedBatchTxs(cmd.Context(), &types.UnsignedBatchTxsRequest{
+ Address: address.String(),
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdUnsignedContractCallTxs() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "pending-contract-call-tx-ethereum-signatures [validator-or-orchestrator-acc-address]",
+ Args: cobra.ExactArgs(1),
+ Short: "query signatures for any pending contract call transactions given a validator or orchestrator address (sdk.AccAddress format)",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ address, err := sdk.AccAddressFromBech32(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.UnsignedContractCallTxs(cmd.Context(), &types.UnsignedContractCallTxsRequest{
+ Address: address.String(),
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdLatestSignerSetTx() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "latest-signer-set-tx",
+ Args: cobra.NoArgs,
+ Short: "query for the latest signer set from the chain",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ req := &types.LatestSignerSetTxRequest{}
+
+ res, err := queryClient.LatestSignerSetTx(cmd.Context(), req)
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdLastSubmittedEthereumEvent() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "last-submitted-ethereum-event [validator-or-orchestrator-acc-address]",
+ Args: cobra.ExactArgs(1),
+ Short: "query for the last event nonce that was submitted by a given validator",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ address, err := sdk.AccAddressFromBech32(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.LastSubmittedEthereumEvent(cmd.Context(), &types.LastSubmittedEthereumEventRequest{
+ Address: address.String(),
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+// TODO: this looks broken
+func CmdBatchTxFees() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "batch-tx-fees",
+ Args: cobra.NoArgs,
+ Short: "query amount of fees for any unrelayed batches",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.BatchTxFees(cmd.Context(), &types.BatchTxFeesRequest{})
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdERC20ToDenom() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "erc20-to-denom [erc20]",
+ Args: cobra.ExactArgs(1),
+ Short: "given an erc20 contract address return the cosmos denom",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ contract, err := parseContractAddress(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.ERC20ToDenom(cmd.Context(), &types.ERC20ToDenomRequest{
+ Erc20: contract,
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdDenomToERC20Params() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "denom-to-erc20-params [denom]",
+ Args: cobra.ExactArgs(1),
+ Short: "given a cosmos base denom return the correct erc20 name, symbol and decimals",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ if err := sdk.ValidateDenom(args[0]); err != nil {
+ return err
+ }
+
+ req := &types.DenomToERC20ParamsRequest{
+ Denom: args[0],
+ }
+
+ res, err := queryClient.DenomToERC20Params(cmd.Context(), req)
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdDenomToERC20() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "denom-to-erc20 [denom]",
+ Args: cobra.ExactArgs(1),
+ Short: "given a cosmos denom return an erc20 contract address",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ if err := sdk.ValidateDenom(args[0]); err != nil {
+ return err
+ }
+
+ res, err := queryClient.DenomToERC20(cmd.Context(), &types.DenomToERC20Request{
+ Denom: args[0],
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdUnbatchedSendToEthereums() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "unbatched-send-to-ethereums [sender-address]",
+ Args: cobra.MaximumNArgs(1),
+ Short: "query all unbatched send to ethereum messages",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ pageReq, err := client.ReadPageRequest(cmd.Flags())
+ if err != nil {
+ return err
+ }
+
+ sender, err := sdk.AccAddressFromBech32(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.UnbatchedSendToEthereums(cmd.Context(), &types.UnbatchedSendToEthereumsRequest{
+ SenderAddress: sender.String(),
+ Pagination: pageReq,
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ flags.AddPaginationFlagsToCmd(cmd, "unbatched-send-to-ethereums")
+ return cmd
+}
+
+func CmdDelegateKeysByValidator() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delegate-keys-by-validator [validator-address]",
+ Args: cobra.ExactArgs(1),
+ Short: "query which public keys/addresses a validator has delegated to",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ validatorAddress, err := sdk.ValAddressFromBech32(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.DelegateKeysByValidator(cmd.Context(), &types.DelegateKeysByValidatorRequest{
+ ValidatorAddress: validatorAddress.String(),
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdDelegateKeysByEthereumSigner() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delegate-keys-by-ethereum-signer [ethereum-signer]",
+ Args: cobra.ExactArgs(1),
+ Short: "query the valdiator and orchestartor keys for a given ethsigner",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ if !common.IsHexAddress(args[0]) {
+ return fmt.Errorf("address is not an etheruem address")
+ }
+
+ res, err := queryClient.DelegateKeysByEthereumSigner(cmd.Context(), &types.DelegateKeysByEthereumSignerRequest{
+ EthereumSigner: args[0],
+ })
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdDelegateKeysByOrchestrator() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delegate-keys-by-orchestrator [orchestrator-address]",
+ Args: cobra.ExactArgs(1),
+ Short: "query the validator and eth signer keys for a given orchestrator address",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ orcAddr, err := sdk.AccAddressFromBech32(args[0])
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.DelegateKeysByOrchestrator(cmd.Context(), &types.DelegateKeysByOrchestratorRequest{
+ OrchestratorAddress: orcAddr.String(),
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdDelegateKeys() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "all-delegate-keys",
+ Args: cobra.NoArgs,
+ Short: "query all delegate keys tracked by the chain",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, queryClient, err := newContextAndQueryClient(cmd)
+ if err != nil {
+ return err
+ }
+
+ res, err := queryClient.DelegateKeys(cmd.Context(), &types.DelegateKeysRequest{})
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
+
+func newContextAndQueryClient(cmd *cobra.Command) (client.Context, types.QueryClient, error) {
+ clientCtx, err := client.GetClientQueryContext(cmd)
+ if err != nil {
+ return clientCtx, nil, err
+ }
+ return clientCtx, types.NewQueryClient(clientCtx), nil
+}
+
+func parseContractAddress(s string) (string, error) {
+ if !common.IsHexAddress(s) {
+ return "", fmt.Errorf("%s not a valid contract address, please input a valid contract address", s)
+ }
+ return s, nil
+}
+
+func parseCount(s string) (int64, error) {
+ count, err := strconv.ParseInt(s, 10, 64)
+ if err != nil {
+ return 0, fmt.Errorf("count %s not a valid int, please input a valid count", s)
+ }
+ return count, nil
+}
+
+func parseNonce(s string) (uint64, error) {
+ nonce, err := strconv.ParseUint(s, 10, 64)
+ if err != nil {
+ return 0, fmt.Errorf("nonce %s not a valid uint, please input a valid nonce", s)
+ }
+ return nonce, nil
+}
diff --git a/module/x/gravity/client/cli/tx.go b/module/x/gravity/client/cli/tx.go
new file mode 100644
index 0000000..ac89502
--- /dev/null
+++ b/module/x/gravity/client/cli/tx.go
@@ -0,0 +1,190 @@
+package cli
+
+import (
+ "fmt"
+ "strconv"
+
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ "github.com/cosmos/cosmos-sdk/client/tx"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/spf13/cobra"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+func GetTxCmd(storeKey string) *cobra.Command {
+ gravityTxCmd := &cobra.Command{
+ Use: types.ModuleName,
+ Short: "Gravity transaction subcommands",
+ DisableFlagParsing: true,
+ SuggestionsMinimumDistance: 2,
+ RunE: client.ValidateCmd,
+ }
+
+ gravityTxCmd.AddCommand(
+ CmdSendToEthereum(),
+ CmdCancelSendToEthereum(),
+ CmdRequestBatchTx(),
+ CmdSetDelegateKeys(),
+ )
+
+ return gravityTxCmd
+}
+
+func CmdSendToEthereum() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "send-to-ethereum [ethereum-reciever] [send-coins] [fee-coins]",
+ Aliases: []string{"send", "transfer"},
+ Args: cobra.ExactArgs(3),
+ Short: "Send tokens from cosmos chain to connected ethereum chain",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, err := client.GetClientTxContext(cmd)
+ if err != nil {
+ return err
+ }
+
+ from := clientCtx.GetFromAddress()
+ if from == nil {
+ return fmt.Errorf("must pass from flag")
+ }
+
+ if !common.IsHexAddress(args[0]) {
+ return fmt.Errorf("must be a valid ethereum address got %s", args[0])
+ }
+
+ // Get amount of coins
+ sendCoin, err := sdk.ParseCoinNormalized(args[1])
+ if err != nil {
+ return err
+ }
+
+ feeCoin, err := sdk.ParseCoinNormalized(args[2])
+ if err != nil {
+ return err
+ }
+
+ msg := types.NewMsgSendToEthereum(from, common.HexToAddress(args[0]).Hex(), sendCoin, feeCoin)
+ if err = msg.ValidateBasic(); err != nil {
+ return err
+ }
+
+ return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
+ },
+ }
+
+ flags.AddTxFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdCancelSendToEthereum() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "cancel-send-to-ethereum [id]",
+ Args: cobra.ExactArgs(2),
+ Short: "Cancel ethereum send by id",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, err := client.GetClientTxContext(cmd)
+ if err != nil {
+ return err
+ }
+
+ from := clientCtx.GetFromAddress()
+ if from == nil {
+ return fmt.Errorf("must pass from flag")
+ }
+
+ id, err := strconv.ParseUint(args[0], 10, 64)
+ if err != nil {
+ return err
+ }
+
+ msg := types.NewMsgCancelSendToEthereum(id, from)
+ if err = msg.ValidateBasic(); err != nil {
+ return err
+ }
+
+ return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
+ },
+ }
+
+ flags.AddTxFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdRequestBatchTx() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "request-batch-tx [denom] [signer]",
+ Args: cobra.ExactArgs(2),
+ Short: "Request batch transaction for denom by signer",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, err := client.GetClientTxContext(cmd)
+ if err != nil {
+ return err
+ }
+
+ denom := args[0]
+ signer, err := sdk.AccAddressFromHex(args[1])
+ if err != nil {
+ return err
+ }
+
+ msg := types.NewMsgRequestBatchTx(denom, signer)
+ if err = msg.ValidateBasic(); err != nil {
+ return err
+ }
+ return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
+ },
+ }
+
+ flags.AddTxFlagsToCmd(cmd)
+ return cmd
+}
+
+func CmdSetDelegateKeys() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "set-delegate-keys [validator-address] [orchestrator-address] [ethereum-address] [ethereum-signature]",
+ Args: cobra.ExactArgs(4),
+ Short: "Set gravity delegate keys",
+ Long: `Set a validator's Ethereum and orchestrator addresses. The validator must
+sign over a binary Proto-encoded DelegateKeysSignMsg message. The message contains
+the validator's address and operator account current nonce.`,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, err := client.GetClientTxContext(cmd)
+ if err != nil {
+ return err
+ }
+
+ valAddr, err := sdk.ValAddressFromBech32(args[0])
+ if err != nil {
+ return err
+ }
+
+ orcAddr, err := sdk.AccAddressFromBech32(args[1])
+ if err != nil {
+ return err
+ }
+
+ ethAddr, err := parseContractAddress(args[2])
+ if err != nil {
+ return err
+ }
+
+ ethSig, err := hexutil.Decode(args[3])
+ if err != nil {
+ return err
+ }
+
+ msg := types.NewMsgDelegateKeys(valAddr, orcAddr, ethAddr, ethSig)
+ if err = msg.ValidateBasic(); err != nil {
+ return err
+ }
+
+ return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
+ },
+ }
+
+ flags.AddTxFlagsToCmd(cmd)
+ return cmd
+}
diff --git a/module/x/gravity/cosmos_originated_test.go b/module/x/gravity/cosmos_originated_test.go
new file mode 100644
index 0000000..85e0a6b
--- /dev/null
+++ b/module/x/gravity/cosmos_originated_test.go
@@ -0,0 +1,199 @@
+package gravity_test
+
+import (
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ bank "github.com/cosmos/cosmos-sdk/x/bank/types"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/cosmos/gravity-bridge/module/app"
+ "github.com/cosmos/gravity-bridge/module/x/gravity"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/keeper"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+// Have the validators put in a erc20<>denom relation with ERC20DeployedEvent
+// Send some coins of that denom into the cosmos module
+// Check that the coins are locked, not burned
+// Have the validators put in a deposit event for that ERC20
+// Check that the coins are unlocked and sent to the right account
+
+func TestCosmosOriginated(t *testing.T) {
+ tv := initializeTestingVars(t)
+ addDenomToERC20Relation(tv)
+ lockCoinsInModule(tv)
+ acceptDepositEvent(tv)
+}
+
+type testingVars struct {
+ myOrchestratorAddr sdk.AccAddress
+ myValAddr sdk.ValAddress
+ erc20 string
+ denom string
+ input keeper.TestInput
+ ctx sdk.Context
+ h sdk.Handler
+ t *testing.T
+}
+
+func initializeTestingVars(t *testing.T) *testingVars {
+ var tv testingVars
+
+ tv.t = t
+
+ tv.myOrchestratorAddr = make([]byte, app.MaxAddrLen)
+ tv.myValAddr = sdk.ValAddress(tv.myOrchestratorAddr) // revisit when proper mapping is impl in keeper
+
+ tv.erc20 = common.HexToAddress("0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e").Hex()
+ tv.denom = "uatom"
+
+ tv.input = keeper.CreateTestEnv(t)
+ tv.ctx = tv.input.Context
+ tv.input.GravityKeeper.StakingKeeper = keeper.NewStakingKeeperMock(tv.myValAddr)
+ tv.input.GravityKeeper.SetOrchestratorValidatorAddress(tv.ctx, tv.myValAddr, tv.myOrchestratorAddr)
+ tv.h = gravity.NewHandler(tv.input.GravityKeeper)
+
+ return &tv
+}
+
+func addDenomToERC20Relation(tv *testingVars) {
+ tv.input.BankKeeper.SetDenomMetaData(tv.ctx, bank.Metadata{
+ Description: "The native staking token of the Cosmos Hub.",
+ DenomUnits: []*bank.DenomUnit{
+ {Denom: "uatom", Exponent: uint32(0), Aliases: []string{"microatom"}},
+ {Denom: "matom", Exponent: uint32(3), Aliases: []string{"milliatom"}},
+ {Denom: "atom", Exponent: uint32(6), Aliases: []string{}},
+ },
+ Base: "uatom",
+ Display: "atom",
+ })
+
+ var myNonce = uint64(1)
+
+ deployedEvent := &types.ERC20DeployedEvent{
+ CosmosDenom: tv.denom,
+ TokenContract: tv.erc20,
+ Erc20Name: "atom",
+ Erc20Symbol: "atom",
+ Erc20Decimals: 6,
+ EventNonce: myNonce,
+ }
+
+ eva, err := types.PackEvent(deployedEvent)
+ require.NoError(tv.t, err)
+
+ msgSumbitEvent := &types.MsgSubmitEthereumEvent{Event: eva, Signer: tv.myOrchestratorAddr.String()}
+
+ _, err = tv.h(tv.ctx, msgSumbitEvent)
+ require.NoError(tv.t, err)
+
+ gravity.EndBlocker(tv.ctx, tv.input.GravityKeeper)
+
+ // check if event vote record persisted
+ a := tv.input.GravityKeeper.GetEthereumEventVoteRecord(tv.ctx, myNonce, deployedEvent.Hash())
+ require.NotNil(tv.t, a)
+
+ // check if erc20<>denom relation added to db
+ isCosmosOriginated, gotERC20, err := tv.input.GravityKeeper.DenomToERC20Lookup(tv.ctx, tv.denom)
+ require.NoError(tv.t, err)
+ assert.True(tv.t, isCosmosOriginated)
+
+ isCosmosOriginated, gotDenom := tv.input.GravityKeeper.ERC20ToDenomLookup(tv.ctx, tv.erc20)
+ assert.True(tv.t, isCosmosOriginated)
+
+ assert.Equal(tv.t, tv.denom, gotDenom)
+ assert.Equal(tv.t, tv.erc20, gotERC20.Hex())
+}
+
+func lockCoinsInModule(tv *testingVars) {
+ var (
+ userCosmosAddr, _ = sdk.AccAddressFromBech32("cosmos1990z7dqsvh8gthw9pa5sn4wuy2xrsd80mg5z6y")
+ denom = "uatom"
+ startingCoinAmount sdk.Int = sdk.NewIntFromUint64(150)
+ sendAmount sdk.Int = sdk.NewIntFromUint64(50)
+ feeAmount sdk.Int = sdk.NewIntFromUint64(5)
+ startingCoins sdk.Coins = sdk.Coins{sdk.NewCoin(denom, startingCoinAmount)}
+ sendingCoin sdk.Coin = sdk.NewCoin(denom, sendAmount)
+ feeCoin sdk.Coin = sdk.NewCoin(denom, feeAmount)
+ ethDestination = "0x3c9289da00b02dC623d0D8D907619890301D26d4"
+ )
+
+ // we start by depositing some funds into the users balance to send
+ tv.input.BankKeeper.MintCoins(tv.ctx, types.ModuleName, startingCoins)
+ tv.input.BankKeeper.SendCoinsFromModuleToAccount(tv.ctx, types.ModuleName, userCosmosAddr, startingCoins)
+ balance1 := tv.input.BankKeeper.GetAllBalances(tv.ctx, userCosmosAddr)
+ assert.Equal(tv.t, sdk.Coins{sdk.NewCoin(denom, startingCoinAmount)}, balance1)
+
+ // send some coins
+ msg := &types.MsgSendToEthereum{
+ Sender: userCosmosAddr.String(),
+ EthereumRecipient: ethDestination,
+ Amount: sendingCoin,
+ BridgeFee: feeCoin,
+ }
+
+ _, err := tv.h(tv.ctx, msg)
+ require.NoError(tv.t, err)
+
+ // Check that user balance has gone down
+ balance2 := tv.input.BankKeeper.GetAllBalances(tv.ctx, userCosmosAddr)
+ assert.Equal(tv.t, sdk.Coins{sdk.NewCoin(denom, startingCoinAmount.Sub(sendAmount).Sub(feeAmount))}, balance2)
+
+ // Check that gravity balance has gone up
+ gravityAddr := tv.input.AccountKeeper.GetModuleAddress(types.ModuleName)
+ assert.Equal(tv.t,
+ sdk.Coins{sdk.NewCoin(denom, sendAmount.Add(feeAmount))},
+ tv.input.BankKeeper.GetAllBalances(tv.ctx, gravityAddr),
+ )
+}
+
+func acceptDepositEvent(tv *testingVars) {
+ var (
+ myOrchestratorAddr sdk.AccAddress = make([]byte, app.MaxAddrLen)
+ myCosmosAddr, _ = sdk.AccAddressFromBech32("cosmos16ahjkfqxpp6lvfy9fpfnfjg39xr96qett0alj5")
+ myNonce = uint64(2)
+ anyETHAddr = "0xf9613b532673Cc223aBa451dFA8539B87e1F666D"
+ )
+
+ myErc20 := types.ERC20Token{
+ Amount: sdk.NewInt(12),
+ Contract: tv.erc20,
+ }
+
+ sendToCosmosEvent := &types.SendToCosmosEvent{
+ EventNonce: myNonce,
+ TokenContract: myErc20.Contract,
+ Amount: myErc20.Amount,
+ EthereumSender: anyETHAddr,
+ CosmosReceiver: myCosmosAddr.String(),
+ EthereumHeight: 1000,
+ }
+
+ eva, err := types.PackEvent(sendToCosmosEvent)
+ require.NoError(tv.t, err)
+
+ msgSubmitEvent := &types.MsgSubmitEthereumEvent{eva, myOrchestratorAddr.String()}
+ _, err = tv.h(tv.ctx, msgSubmitEvent)
+ require.NoError(tv.t, err)
+ gravity.EndBlocker(tv.ctx, tv.input.GravityKeeper)
+
+ // check that attestation persisted
+ a := tv.input.GravityKeeper.GetEthereumEventVoteRecord(tv.ctx, myNonce, sendToCosmosEvent.Hash())
+ require.NotNil(tv.t, a)
+
+ // Check that user balance has gone up
+ assert.Equal(tv.t,
+ sdk.Coins{sdk.NewCoin(tv.denom, myErc20.Amount)},
+ tv.input.BankKeeper.GetAllBalances(tv.ctx, myCosmosAddr))
+
+ // Check that gravity balance has gone down
+ gravityAddr := tv.input.AccountKeeper.GetModuleAddress(types.ModuleName)
+ assert.Equal(tv.t,
+ sdk.Coins{sdk.NewCoin(tv.denom, sdk.NewIntFromUint64(55).Sub(myErc20.Amount))},
+ tv.input.BankKeeper.GetAllBalances(tv.ctx, gravityAddr),
+ )
+}
diff --git a/module/x/gravity/handler.go b/module/x/gravity/handler.go
new file mode 100644
index 0000000..a7ec176
--- /dev/null
+++ b/module/x/gravity/handler.go
@@ -0,0 +1,47 @@
+package gravity
+
+import (
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/keeper"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+// NewHandler returns a handler for "Gravity" type messages.
+func NewHandler(k keeper.Keeper) sdk.Handler {
+ msgServer := keeper.NewMsgServerImpl(k)
+
+ return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
+ ctx = ctx.WithEventManager(sdk.NewEventManager())
+
+ switch msg := msg.(type) {
+ case *types.MsgSendToEthereum:
+ res, err := msgServer.SendToEthereum(sdk.WrapSDKContext(ctx), msg)
+ return sdk.WrapServiceResult(ctx, res, err)
+
+ case *types.MsgCancelSendToEthereum:
+ res, err := msgServer.CancelSendToEthereum(sdk.WrapSDKContext(ctx), msg)
+ return sdk.WrapServiceResult(ctx, res, err)
+
+ case *types.MsgRequestBatchTx:
+ res, err := msgServer.RequestBatchTx(sdk.WrapSDKContext(ctx), msg)
+ return sdk.WrapServiceResult(ctx, res, err)
+
+ case *types.MsgSubmitEthereumTxConfirmation:
+ res, err := msgServer.SubmitEthereumTxConfirmation(sdk.WrapSDKContext(ctx), msg)
+ return sdk.WrapServiceResult(ctx, res, err)
+
+ case *types.MsgSubmitEthereumEvent:
+ res, err := msgServer.SubmitEthereumEvent(sdk.WrapSDKContext(ctx), msg)
+ return sdk.WrapServiceResult(ctx, res, err)
+
+ case *types.MsgDelegateKeys:
+ res, err := msgServer.SetDelegateKeys(sdk.WrapSDKContext(ctx), msg)
+ return sdk.WrapServiceResult(ctx, res, err)
+
+ default:
+ return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
+ }
+ }
+}
diff --git a/module/x/gravity/handler_test.go b/module/x/gravity/handler_test.go
new file mode 100644
index 0000000..dfc4587
--- /dev/null
+++ b/module/x/gravity/handler_test.go
@@ -0,0 +1,385 @@
+package gravity_test
+
+import (
+ "bytes"
+ "testing"
+ "time"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/stretchr/testify/require"
+
+ "github.com/cosmos/gravity-bridge/module/app"
+ "github.com/cosmos/gravity-bridge/module/x/gravity"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/keeper"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+ ethCrypto "github.com/ethereum/go-ethereum/crypto"
+)
+
+func TestHandleMsgSendToEthereum(t *testing.T) {
+ var (
+ userCosmosAddr, _ = sdk.AccAddressFromBech32("cosmos1990z7dqsvh8gthw9pa5sn4wuy2xrsd80mg5z6y")
+ blockTime = time.Date(2020, 9, 14, 15, 20, 10, 0, time.UTC)
+ blockHeight int64 = 200
+ denom = "gravity0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e"
+ startingCoinAmount, _ = sdk.NewIntFromString("150000000000000000000") // 150 ETH worth, required to reach above u64 limit (which is about 18 ETH)
+ sendAmount, _ = sdk.NewIntFromString("50000000000000000000") // 50 ETH
+ feeAmount, _ = sdk.NewIntFromString("5000000000000000000") // 5 ETH
+ startingCoins sdk.Coins = sdk.Coins{sdk.NewCoin(denom, startingCoinAmount)}
+ sendingCoin sdk.Coin = sdk.NewCoin(denom, sendAmount)
+ feeCoin sdk.Coin = sdk.NewCoin(denom, feeAmount)
+ ethDestination = "0x3c9289da00b02dC623d0D8D907619890301D26d4"
+ )
+
+ // we start by depositing some funds into the users balance to send
+ input := keeper.CreateTestEnv(t)
+ ctx := input.Context
+ h := gravity.NewHandler(input.GravityKeeper)
+ input.BankKeeper.MintCoins(ctx, types.ModuleName, startingCoins)
+ input.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, userCosmosAddr, startingCoins) // 150
+ balance1 := input.BankKeeper.GetAllBalances(ctx, userCosmosAddr)
+ require.Equal(t, sdk.Coins{sdk.NewCoin(denom, startingCoinAmount)}, balance1) // 150
+
+ // send some coins
+ msg := &types.MsgSendToEthereum{
+ Sender: userCosmosAddr.String(),
+ EthereumRecipient: ethDestination,
+ Amount: sendingCoin,
+ BridgeFee: feeCoin}
+ ctx = ctx.WithBlockTime(blockTime).WithBlockHeight(blockHeight)
+ _, err := h(ctx, msg) // send 55
+ require.NoError(t, err)
+ balance2 := input.BankKeeper.GetAllBalances(ctx, userCosmosAddr)
+ require.Equal(t, sdk.Coins{sdk.NewCoin(denom, startingCoinAmount.Sub(sendAmount).Sub(feeAmount))}, balance2)
+
+ // do the same thing again and make sure it works twice
+ msg1 := &types.MsgSendToEthereum{
+ Sender: userCosmosAddr.String(),
+ EthereumRecipient: ethDestination,
+ Amount: sendingCoin,
+ BridgeFee: feeCoin}
+ ctx = ctx.WithBlockTime(blockTime).WithBlockHeight(blockHeight)
+ _, err1 := h(ctx, msg1) // send 55
+ require.NoError(t, err1)
+ balance3 := input.BankKeeper.GetAllBalances(ctx, userCosmosAddr)
+ finalAmount3 := startingCoinAmount.Sub(sendAmount).Sub(sendAmount).Sub(feeAmount).Sub(feeAmount)
+ require.Equal(t, sdk.Coins{sdk.NewCoin(denom, finalAmount3)}, balance3)
+
+ // now we should be out of coins and error
+ msg2 := &types.MsgSendToEthereum{
+ Sender: userCosmosAddr.String(),
+ EthereumRecipient: ethDestination,
+ Amount: sendingCoin,
+ BridgeFee: feeCoin}
+ ctx = ctx.WithBlockTime(blockTime).WithBlockHeight(blockHeight)
+ _, err2 := h(ctx, msg2) // send 55
+ require.Error(t, err2)
+ balance4 := input.BankKeeper.GetAllBalances(ctx, userCosmosAddr)
+ require.Equal(t, sdk.Coins{sdk.NewCoin(denom, finalAmount3)}, balance4)
+}
+
+func TestMsgSubmitEthreumEventSendToCosmosSingleValidator(t *testing.T) {
+ var (
+ myOrchestratorAddr sdk.AccAddress = make([]byte, app.MaxAddrLen)
+ myCosmosAddr, _ = sdk.AccAddressFromBech32("cosmos16ahjkfqxpp6lvfy9fpfnfjg39xr96qett0alj5")
+ myValAddr = sdk.ValAddress(myOrchestratorAddr) // revisit when proper mapping is impl in keeper
+ myNonce = uint64(1)
+ anyETHAddr = "0xf9613b532673Cc223aBa451dFA8539B87e1F666D"
+ tokenETHAddr = "0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e"
+ myBlockTime = time.Date(2020, 9, 14, 15, 20, 10, 0, time.UTC)
+ amountA, _ = sdk.NewIntFromString("50000000000000000000") // 50 ETH
+ amountB, _ = sdk.NewIntFromString("100000000000000000000") // 100 ETH
+ )
+ input := keeper.CreateTestEnv(t)
+ ctx := input.Context
+ gk := input.GravityKeeper
+ bk := input.BankKeeper
+ gk.StakingKeeper = keeper.NewStakingKeeperMock(myValAddr)
+ gk.SetOrchestratorValidatorAddress(ctx, myValAddr, myOrchestratorAddr)
+ h := gravity.NewHandler(gk)
+
+ myErc20 := types.ERC20Token{
+ Amount: amountA,
+ Contract: tokenETHAddr,
+ }
+
+ sendToCosmosEvent := &types.SendToCosmosEvent{
+ EventNonce: myNonce,
+ TokenContract: myErc20.Contract,
+ Amount: myErc20.Amount,
+ EthereumSender: anyETHAddr,
+ CosmosReceiver: myCosmosAddr.String(),
+ }
+
+ eva, err := types.PackEvent(sendToCosmosEvent)
+ require.NoError(t, err)
+
+ msgSubmitEvent := &types.MsgSubmitEthereumEvent{eva, myOrchestratorAddr.String()}
+ // when
+ ctx = ctx.WithBlockTime(myBlockTime)
+ _, err = h(ctx, msgSubmitEvent)
+ gravity.EndBlocker(ctx, gk)
+ require.NoError(t, err)
+
+ // and attestation persisted
+ a := gk.GetEthereumEventVoteRecord(ctx, myNonce, sendToCosmosEvent.Hash())
+ require.NotNil(t, a)
+ // and vouchers added to the account
+
+ balance := bk.GetAllBalances(ctx, myCosmosAddr)
+ require.Equal(t, sdk.Coins{sdk.NewCoin("gravity0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e", amountA)}, balance)
+
+ // Test to reject duplicate deposit
+ // when
+ ctx = ctx.WithBlockTime(myBlockTime)
+ _, err = h(ctx, msgSubmitEvent)
+ gravity.EndBlocker(ctx, gk)
+ // then
+ require.Error(t, err)
+ balance = bk.GetAllBalances(ctx, myCosmosAddr)
+ require.Equal(t, sdk.Coins{sdk.NewCoin("gravity0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e", amountA)}, balance)
+
+ // Test to reject skipped nonce
+
+ sendToCosmosEvent = &types.SendToCosmosEvent{
+ EventNonce: uint64(3),
+ TokenContract: myErc20.Contract,
+ Amount: myErc20.Amount,
+ EthereumSender: anyETHAddr,
+ CosmosReceiver: myCosmosAddr.String(),
+ }
+
+ eva, err = types.PackEvent(sendToCosmosEvent)
+ require.NoError(t, err)
+
+ msgSubmitEvent = &types.MsgSubmitEthereumEvent{eva, myOrchestratorAddr.String()}
+
+ // when
+ ctx = ctx.WithBlockTime(myBlockTime)
+ _, err = h(ctx, msgSubmitEvent)
+ require.Error(t, err)
+
+ gravity.EndBlocker(ctx, gk)
+ // then
+ balance = bk.GetAllBalances(ctx, myCosmosAddr)
+ require.Equal(t, sdk.Coins{sdk.NewCoin("gravity0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e", amountA)}, balance)
+
+ // Test to finally accept consecutive nonce
+ sendToCosmosEvent = &types.SendToCosmosEvent{
+ EventNonce: uint64(2),
+ TokenContract: myErc20.Contract,
+ Amount: myErc20.Amount,
+ EthereumSender: anyETHAddr,
+ CosmosReceiver: myCosmosAddr.String(),
+ }
+
+ eva, err = types.PackEvent(sendToCosmosEvent)
+ require.NoError(t, err)
+
+ msgSubmitEvent = &types.MsgSubmitEthereumEvent{eva, myOrchestratorAddr.String()}
+ // when
+ ctx = ctx.WithBlockTime(myBlockTime)
+ _, err = h(ctx, msgSubmitEvent)
+ gravity.EndBlocker(ctx, gk)
+
+ // then
+ require.NoError(t, err)
+ balance = bk.GetAllBalances(ctx, myCosmosAddr)
+ require.Equal(t, sdk.Coins{sdk.NewCoin("gravity0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e", amountB)}, balance)
+}
+
+func TestMsgSubmitEthreumEventSendToCosmosMultiValidator(t *testing.T) {
+ var (
+ orchestratorAddr1, _ = sdk.AccAddressFromBech32("cosmos1dg55rtevlfxh46w88yjpdd08sqhh5cc3xhkcej")
+ orchestratorAddr2, _ = sdk.AccAddressFromBech32("cosmos164knshrzuuurf05qxf3q5ewpfnwzl4gj4m4dfy")
+ orchestratorAddr3, _ = sdk.AccAddressFromBech32("cosmos193fw83ynn76328pty4yl7473vg9x86alq2cft7")
+ myCosmosAddr, _ = sdk.AccAddressFromBech32("cosmos16ahjkfqxpp6lvfy9fpfnfjg39xr96qett0alj5")
+ valAddr1 = sdk.ValAddress(orchestratorAddr1) // revisit when proper mapping is impl in keeper
+ valAddr2 = sdk.ValAddress(orchestratorAddr2) // revisit when proper mapping is impl in keeper
+ valAddr3 = sdk.ValAddress(orchestratorAddr3) // revisit when proper mapping is impl in keeper
+ myNonce = uint64(1)
+ anyETHAddr = "0xf9613b532673Cc223aBa451dFA8539B87e1F666D"
+ tokenETHAddr = "0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e"
+ myBlockTime = time.Date(2020, 9, 14, 15, 20, 10, 0, time.UTC)
+ )
+ input := keeper.CreateTestEnv(t)
+ ctx := input.Context
+ input.GravityKeeper.StakingKeeper = keeper.NewStakingKeeperMock(valAddr1, valAddr2, valAddr3)
+ input.GravityKeeper.SetOrchestratorValidatorAddress(ctx, valAddr1, orchestratorAddr1)
+ input.GravityKeeper.SetOrchestratorValidatorAddress(ctx, valAddr2, orchestratorAddr2)
+ input.GravityKeeper.SetOrchestratorValidatorAddress(ctx, valAddr3, orchestratorAddr3)
+ h := gravity.NewHandler(input.GravityKeeper)
+
+ myErc20 := types.ERC20Token{
+ Amount: sdk.NewInt(12),
+ Contract: tokenETHAddr,
+ }
+
+ ethClaim1 := &types.SendToCosmosEvent{
+ EventNonce: myNonce,
+ TokenContract: myErc20.Contract,
+ Amount: myErc20.Amount,
+ EthereumSender: anyETHAddr,
+ CosmosReceiver: myCosmosAddr.String(),
+ }
+ ethClaim1a, err := types.PackEvent(ethClaim1)
+ require.NoError(t, err)
+ ethClaim1Msg := &types.MsgSubmitEthereumEvent{ethClaim1a, orchestratorAddr1.String()}
+ ethClaim2 := &types.SendToCosmosEvent{
+ EventNonce: myNonce,
+ TokenContract: myErc20.Contract,
+ Amount: myErc20.Amount,
+ EthereumSender: anyETHAddr,
+ CosmosReceiver: myCosmosAddr.String(),
+ }
+ ethClaim2a, err := types.PackEvent(ethClaim2)
+ require.NoError(t, err)
+ ethClaim2Msg := &types.MsgSubmitEthereumEvent{ethClaim2a, orchestratorAddr2.String()}
+ ethClaim3 := &types.SendToCosmosEvent{
+ EventNonce: myNonce,
+ TokenContract: myErc20.Contract,
+ Amount: myErc20.Amount,
+ EthereumSender: anyETHAddr,
+ CosmosReceiver: myCosmosAddr.String(),
+ }
+ ethClaim3a, err := types.PackEvent(ethClaim3)
+ require.NoError(t, err)
+ ethClaim3Msg := &types.MsgSubmitEthereumEvent{ethClaim3a, orchestratorAddr3.String()}
+
+ // when
+ ctx = ctx.WithBlockTime(myBlockTime)
+ _, err = h(ctx, ethClaim1Msg)
+ gravity.EndBlocker(ctx, input.GravityKeeper)
+ require.NoError(t, err)
+ // and attestation persisted
+ a1 := input.GravityKeeper.GetEthereumEventVoteRecord(ctx, myNonce, ethClaim1.Hash())
+ require.NotNil(t, a1)
+ // and vouchers not yet added to the account
+ balance1 := input.BankKeeper.GetAllBalances(ctx, myCosmosAddr)
+ require.NotEqual(t, sdk.Coins{sdk.NewInt64Coin("gravity0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e", 12)}, balance1)
+
+ // when
+ ctx = ctx.WithBlockTime(myBlockTime)
+ _, err = h(ctx, ethClaim2Msg)
+ gravity.EndBlocker(ctx, input.GravityKeeper)
+ require.NoError(t, err)
+
+ // and attestation persisted
+ a2 := input.GravityKeeper.GetEthereumEventVoteRecord(ctx, myNonce, ethClaim2.Hash())
+ require.NotNil(t, a2)
+ // and vouchers now added to the account
+ balance2 := input.BankKeeper.GetAllBalances(ctx, myCosmosAddr)
+ require.Equal(t, sdk.Coins{sdk.NewInt64Coin("gravity0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e", 12)}, balance2)
+
+ // when
+ ctx = ctx.WithBlockTime(myBlockTime)
+ _, err = h(ctx, ethClaim3Msg)
+ gravity.EndBlocker(ctx, input.GravityKeeper)
+ require.NoError(t, err)
+
+ // and attestation persisted
+ a3 := input.GravityKeeper.GetEthereumEventVoteRecord(ctx, myNonce, ethClaim3.Hash())
+ require.NotNil(t, a3)
+ // and no additional added to the account
+ balance3 := input.BankKeeper.GetAllBalances(ctx, myCosmosAddr)
+ require.Equal(t, sdk.Coins{sdk.NewInt64Coin("gravity0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e", 12)}, balance3)
+}
+
+func TestMsgSetDelegateAddresses(t *testing.T) {
+ ethPrivKey, err := ethCrypto.GenerateKey()
+ ethPrivKey2, err := ethCrypto.GenerateKey()
+
+ var (
+ ethAddress = crypto.PubkeyToAddress(ethPrivKey.PublicKey)
+ cosmosAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, app.MaxAddrLen)
+ ethAddress2 = crypto.PubkeyToAddress(ethPrivKey2.PublicKey)
+ cosmosAddress2 sdk.AccAddress = bytes.Repeat([]byte{0x2}, app.MaxAddrLen)
+ cosmosAddress3 sdk.AccAddress = bytes.Repeat([]byte{0x3}, app.MaxAddrLen)
+
+ valAddress sdk.ValAddress = bytes.Repeat([]byte{0x3}, app.MaxAddrLen)
+ blockTime = time.Date(2020, 9, 14, 15, 20, 10, 0, time.UTC)
+ blockTime2 = time.Date(2020, 9, 15, 15, 20, 10, 0, time.UTC)
+ blockHeight int64 = 200
+ blockHeight2 int64 = 210
+ )
+
+ input := keeper.CreateTestEnv(t)
+ input.GravityKeeper.StakingKeeper = keeper.NewStakingKeeperMock(valAddress)
+ ctx := input.Context
+ wctx := sdk.WrapSDKContext(ctx)
+
+ acc := input.AccountKeeper.NewAccountWithAddress(ctx, cosmosAddress)
+ acc2 := input.AccountKeeper.NewAccountWithAddress(ctx, cosmosAddress2)
+ acc3 := input.AccountKeeper.NewAccountWithAddress(ctx, cosmosAddress3)
+
+ // Set the sequence to 1 because the antehandler will do this in the full
+ // chain.
+ acc.SetSequence(1)
+ acc2.SetSequence(1)
+ acc3.SetSequence(1)
+
+ input.AccountKeeper.SetAccount(ctx, acc)
+ input.AccountKeeper.SetAccount(ctx, acc2)
+ input.AccountKeeper.SetAccount(ctx, acc3)
+
+ ethMsg := types.DelegateKeysSignMsg{
+ ValidatorAddress: valAddress.String(),
+ Nonce: 0,
+ }
+ signMsgBz := input.Marshaler.MustMarshal(ðMsg)
+ hash := crypto.Keccak256Hash(signMsgBz).Bytes()
+ sig, err := types.NewEthereumSignature(hash, ethPrivKey)
+ require.NoError(t, err)
+
+ k := input.GravityKeeper
+ h := gravity.NewHandler(input.GravityKeeper)
+ ctx = ctx.WithBlockTime(blockTime)
+
+ msg := types.NewMsgDelegateKeys(valAddress, cosmosAddress, ethAddress.String(), sig)
+ ctx = ctx.WithBlockTime(blockTime).WithBlockHeight(blockHeight)
+ _, err = h(ctx, msg)
+ require.NoError(t, err)
+
+ require.Equal(t, ethAddress.String(), k.GetValidatorEthereumAddress(ctx, valAddress).Hex())
+ require.Equal(t, valAddress, k.GetOrchestratorValidatorAddress(ctx, cosmosAddress))
+ require.Equal(t, cosmosAddress, k.GetEthereumOrchestratorAddress(ctx, common.HexToAddress(ethAddress.String())))
+
+ _, err = k.DelegateKeysByOrchestrator(wctx, &types.DelegateKeysByOrchestratorRequest{OrchestratorAddress: cosmosAddress.String()})
+ require.NoError(t, err)
+
+ _, err = k.DelegateKeysByEthereumSigner(wctx, &types.DelegateKeysByEthereumSignerRequest{EthereumSigner: ethAddress.String()})
+ require.NoError(t, err)
+
+ _, err = k.DelegateKeysByValidator(wctx, &types.DelegateKeysByValidatorRequest{ValidatorAddress: valAddress.String()})
+ require.NoError(t, err)
+
+ // delegate new orch and eth addrs for same validator
+ ethMsg = types.DelegateKeysSignMsg{
+ ValidatorAddress: valAddress.String(),
+ Nonce: 0,
+ }
+ signMsgBz = input.Marshaler.MustMarshal(ðMsg)
+ hash = crypto.Keccak256Hash(signMsgBz).Bytes()
+
+ sig, err = types.NewEthereumSignature(hash, ethPrivKey2)
+ require.NoError(t, err)
+
+ msg = types.NewMsgDelegateKeys(valAddress, cosmosAddress2, ethAddress2.String(), sig)
+ ctx = ctx.WithBlockTime(blockTime2).WithBlockHeight(blockHeight2)
+ _, err = h(ctx, msg)
+ require.NoError(t, err)
+
+ require.Equal(t, ethAddress2.String(), k.GetValidatorEthereumAddress(ctx, valAddress).Hex())
+ require.Equal(t, valAddress, k.GetOrchestratorValidatorAddress(ctx, cosmosAddress2))
+ require.Equal(t, cosmosAddress2, k.GetEthereumOrchestratorAddress(ctx, common.HexToAddress(ethAddress2.String())))
+
+ _, err = k.DelegateKeysByOrchestrator(wctx, &types.DelegateKeysByOrchestratorRequest{OrchestratorAddress: cosmosAddress2.String()})
+ require.NoError(t, err)
+
+ _, err = k.DelegateKeysByEthereumSigner(wctx, &types.DelegateKeysByEthereumSignerRequest{EthereumSigner: ethAddress2.String()})
+ require.NoError(t, err)
+
+ _, err = k.DelegateKeysByValidator(wctx, &types.DelegateKeysByValidatorRequest{ValidatorAddress: valAddress.String()})
+ require.NoError(t, err)
+}
diff --git a/module/x/gravity/keeper/batch.go b/module/x/gravity/keeper/batch.go
new file mode 100644
index 0000000..5bae0a1
--- /dev/null
+++ b/module/x/gravity/keeper/batch.go
@@ -0,0 +1,203 @@
+package keeper
+
+import (
+ "encoding/binary"
+ "fmt"
+ "strconv"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+// TODO: should we make this a parameter or a a call arg?
+const BatchTxSize = 100
+
+// BuildBatchTx starts the following process chain:
+// - find bridged denominator for given voucher type
+// - determine if a an unexecuted batch is already waiting for this token type, if so confirm the new batch would
+// have a higher total fees. If not exit withtout creating a batch
+// - select available transactions from the outgoing transaction pool sorted by fee desc
+// - persist an outgoing batch object with an incrementing ID = nonce
+// - emit an event
+func (k Keeper) BuildBatchTx(ctx sdk.Context, contractAddress common.Address, maxElements int) *types.BatchTx {
+ // if there is a more profitable batch for this token type do not create a new batch
+ if lastBatch := k.getLastOutgoingBatchByTokenType(ctx, contractAddress); lastBatch != nil {
+ if lastBatch.GetFees().GTE(k.getBatchFeesByTokenType(ctx, contractAddress, maxElements)) {
+ return nil
+ }
+ }
+
+ var selectedStes []*types.SendToEthereum
+ k.iterateUnbatchedSendToEthereumsByContract(ctx, contractAddress, func(ste *types.SendToEthereum) bool {
+ selectedStes = append(selectedStes, ste)
+ k.deleteUnbatchedSendToEthereum(ctx, ste.Id, ste.Erc20Fee)
+ return len(selectedStes) == maxElements
+ })
+
+ batch := &types.BatchTx{
+ BatchNonce: k.incrementLastOutgoingBatchNonce(ctx),
+ Timeout: k.getBatchTimeoutHeight(ctx),
+ Transactions: selectedStes,
+ TokenContract: contractAddress.Hex(),
+ Height: uint64(ctx.BlockHeight()),
+ }
+ k.SetOutgoingTx(ctx, batch)
+
+ ctx.EventManager().EmitEvent(sdk.NewEvent(
+ types.EventTypeOutgoingBatch,
+ sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
+ sdk.NewAttribute(types.AttributeKeyContract, k.getBridgeContractAddress(ctx)),
+ sdk.NewAttribute(types.AttributeKeyBridgeChainID, strconv.Itoa(int(k.getBridgeChainID(ctx)))),
+ sdk.NewAttribute(types.AttributeKeyOutgoingBatchID, fmt.Sprint(batch.BatchNonce)),
+ sdk.NewAttribute(types.AttributeKeyNonce, fmt.Sprint(batch.BatchNonce)),
+ ))
+
+ return batch
+}
+
+// This gets the batch timeout height in Ethereum blocks.
+func (k Keeper) getBatchTimeoutHeight(ctx sdk.Context) uint64 {
+ params := k.GetParams(ctx)
+ currentCosmosHeight := ctx.BlockHeight()
+ // we store the last observed Cosmos and Ethereum heights, we do not concern ourselves if these values are zero because
+ // no batch can be produced if the last Ethereum block height is not first populated by a deposit event.
+ heights := k.GetLastObservedEthereumBlockHeight(ctx)
+ if heights.CosmosHeight == 0 || heights.EthereumHeight == 0 {
+ return 0
+ }
+ // we project how long it has been in milliseconds since the last Ethereum block height was observed
+ projectedMillis := (uint64(currentCosmosHeight) - heights.CosmosHeight) * params.AverageBlockTime
+ // we convert that projection into the current Ethereum height using the average Ethereum block time in millis
+ projectedCurrentEthereumHeight := (projectedMillis / params.AverageEthereumBlockTime) + heights.EthereumHeight
+ // we convert our target time for block timeouts (lets say 12 hours) into a number of blocks to
+ // place on top of our projection of the current Ethereum block height.
+ blocksToAdd := params.TargetEthTxTimeout / params.AverageEthereumBlockTime
+ return projectedCurrentEthereumHeight + blocksToAdd
+}
+
+// batchTxExecuted is run when the Cosmos chain detects that a batch has been executed on Ethereum
+// It deletes all the transactions in the batch, then cancels all earlier batches
+func (k Keeper) batchTxExecuted(ctx sdk.Context, tokenContract common.Address, nonce uint64) {
+ otx := k.GetOutgoingTx(ctx, types.MakeBatchTxKey(tokenContract, nonce))
+ batchTx, _ := otx.(*types.BatchTx)
+ k.IterateOutgoingTxsByType(ctx, types.BatchTxPrefixByte, func(key []byte, otx types.OutgoingTx) bool {
+ // If the iterated batches nonce is lower than the one that was just executed, cancel it
+ btx, _ := otx.(*types.BatchTx)
+ if (btx.BatchNonce < batchTx.BatchNonce) && (batchTx.TokenContract == tokenContract.Hex()) {
+ k.CancelBatchTx(ctx, tokenContract, btx.BatchNonce)
+ }
+ return false
+ })
+ k.DeleteOutgoingTx(ctx, batchTx.GetStoreIndex())
+}
+
+// getBatchFeesByTokenType gets the fees the next batch of a given token type would
+// have if created. This info is both presented to relayers for the purpose of determining
+// when to request batches and also used by the batch creation process to decide not to create
+// a new batch
+func (k Keeper) getBatchFeesByTokenType(ctx sdk.Context, tokenContractAddr common.Address, maxElements int) sdk.Int {
+ feeAmount := sdk.ZeroInt()
+ i := 0
+ k.iterateUnbatchedSendToEthereumsByContract(ctx, tokenContractAddr, func(tx *types.SendToEthereum) bool {
+ feeAmount = feeAmount.Add(tx.Erc20Fee.Amount)
+ i++
+ return i == maxElements
+ })
+
+ return feeAmount
+}
+
+// GetBatchFeesByTokenType gets the fees the next batch of a given token type would
+// have if created. This info is both presented to relayers for the purpose of determining
+// when to request batches and also used by the batch creation process to decide not to create
+// a new batch
+func (k Keeper) GetBatchFeesByTokenType(ctx sdk.Context, tokenContractAddr common.Address, maxElements int) sdk.Int {
+ feeAmount := sdk.ZeroInt()
+ i := 0
+ k.iterateUnbatchedSendToEthereumsByContract(ctx, tokenContractAddr, func(tx *types.SendToEthereum) bool {
+ feeAmount = feeAmount.Add(tx.Erc20Fee.Amount)
+ i++
+ return i == maxElements
+ })
+ return feeAmount
+}
+
+// CancelBatchTx releases all TX in the batch and deletes the batch
+func (k Keeper) CancelBatchTx(ctx sdk.Context, tokenContract common.Address, nonce uint64) {
+ otx := k.GetOutgoingTx(ctx, types.MakeBatchTxKey(tokenContract, nonce))
+ batch, _ := otx.(*types.BatchTx)
+
+ // free transactions from batch and reindex them
+ for _, tx := range batch.Transactions {
+ k.setUnbatchedSendToEthereum(ctx, tx)
+ }
+
+ // Delete batch since it is finished
+ k.DeleteOutgoingTx(ctx, batch.GetStoreIndex())
+
+ ctx.EventManager().EmitEvent(
+ sdk.NewEvent(
+ types.EventTypeOutgoingBatchCanceled,
+ sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
+ sdk.NewAttribute(types.AttributeKeyContract, k.getBridgeContractAddress(ctx)),
+ sdk.NewAttribute(types.AttributeKeyBridgeChainID, strconv.Itoa(int(k.getBridgeChainID(ctx)))),
+ sdk.NewAttribute(types.AttributeKeyOutgoingBatchID, fmt.Sprint(nonce)),
+ sdk.NewAttribute(types.AttributeKeyNonce, fmt.Sprint(nonce)),
+ ),
+ )
+}
+
+// getLastOutgoingBatchByTokenType gets the latest outgoing tx batch by token type
+func (k Keeper) getLastOutgoingBatchByTokenType(ctx sdk.Context, token common.Address) *types.BatchTx {
+ var lastBatch *types.BatchTx = nil
+ lastNonce := uint64(0)
+ k.IterateOutgoingTxsByType(ctx, types.BatchTxPrefixByte, func(key []byte, otx types.OutgoingTx) bool {
+ btx, _ := otx.(*types.BatchTx)
+ if common.HexToAddress(btx.TokenContract) == token && btx.BatchNonce > lastNonce {
+ lastBatch = btx
+ lastNonce = btx.BatchNonce
+ }
+ return false
+ })
+ return lastBatch
+}
+
+// SetLastSlashedOutgoingTxBlockHeight sets the latest slashed Batch block height
+func (k Keeper) SetLastSlashedOutgoingTxBlockHeight(ctx sdk.Context, blockHeight uint64) {
+ ctx.KVStore(k.storeKey).Set([]byte{types.LastSlashedOutgoingTxBlockKey}, sdk.Uint64ToBigEndian(blockHeight))
+}
+
+// GetLastSlashedOutgoingTxBlockHeight returns the latest slashed Batch block
+func (k Keeper) GetLastSlashedOutgoingTxBlockHeight(ctx sdk.Context) uint64 {
+ if bz := ctx.KVStore(k.storeKey).Get([]byte{types.LastSlashedOutgoingTxBlockKey}); bz == nil {
+ return 0
+ } else {
+ return binary.BigEndian.Uint64(bz)
+ }
+}
+
+func (k Keeper) GetUnSlashedOutgoingTxs(ctx sdk.Context, maxHeight uint64) (out []types.OutgoingTx) {
+ lastSlashed := k.GetLastSlashedOutgoingTxBlockHeight(ctx)
+ k.iterateOutgoingTxs(ctx, func(key []byte, otx types.OutgoingTx) bool {
+ if (otx.GetCosmosHeight() < maxHeight) && (otx.GetCosmosHeight() > lastSlashed) {
+ out = append(out, otx)
+ }
+ return false
+ })
+ return
+}
+
+func (k Keeper) incrementLastOutgoingBatchNonce(ctx sdk.Context) uint64 {
+ store := ctx.KVStore(k.storeKey)
+ bz := store.Get([]byte{types.LastOutgoingBatchNonceKey})
+ var id uint64 = 0
+ if bz != nil {
+ id = binary.BigEndian.Uint64(bz)
+ }
+ newId := id + 1
+ bz = sdk.Uint64ToBigEndian(newId)
+ store.Set([]byte{types.LastOutgoingBatchNonceKey}, bz)
+ return newId
+}
diff --git a/module/x/gravity/keeper/batch_test.go b/module/x/gravity/keeper/batch_test.go
new file mode 100644
index 0000000..264c62a
--- /dev/null
+++ b/module/x/gravity/keeper/batch_test.go
@@ -0,0 +1,356 @@
+package keeper
+
+import (
+ "testing"
+ "time"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+func TestBatches(t *testing.T) {
+ input := CreateTestEnv(t)
+ ctx := input.Context
+ var (
+ now = time.Now().UTC()
+ mySender, _ = sdk.AccAddressFromBech32("cosmos1ahx7f8wyertuus9r20284ej0asrs085case3kn")
+ myReceiver = common.HexToAddress("0xd041c41EA1bf0F006ADBb6d2c9ef9D425dE5eaD7")
+ myTokenContractAddr = common.HexToAddress("0x429881672B9AE42b8EbA0E26cD9C73711b891Ca5") // Pickle
+ allVouchers = sdk.NewCoins(
+ types.NewERC20Token(99999, myTokenContractAddr.Hex()).GravityCoin(),
+ )
+ )
+
+ // mint some voucher first
+ require.NoError(t, input.BankKeeper.MintCoins(ctx, types.ModuleName, allVouchers))
+ // set senders balance
+ input.AccountKeeper.NewAccountWithAddress(ctx, mySender)
+ require.NoError(t, fundAccount(ctx, input.BankKeeper, mySender, allVouchers))
+
+ // CREATE FIRST BATCH
+ // ==================
+
+ // add some TX to the pool
+ input.AddSendToEthTxsToPool(t, ctx, myTokenContractAddr, mySender, myReceiver, 2, 3, 2, 1)
+
+ // when
+ ctx = ctx.WithBlockTime(now)
+
+ // tx batch size is 2, so that some of them stay behind
+ firstBatch := input.GravityKeeper.BuildBatchTx(ctx, myTokenContractAddr, 2)
+
+ // then batch is persisted
+ gotFirstBatch := input.GravityKeeper.GetOutgoingTx(ctx, firstBatch.GetStoreIndex())
+ require.NotNil(t, gotFirstBatch)
+
+ gfb := gotFirstBatch.(*types.BatchTx)
+ expFirstBatch := &types.BatchTx{
+ BatchNonce: 1,
+ Transactions: []*types.SendToEthereum{
+ types.NewSendToEthereumTx(2, myTokenContractAddr, mySender, myReceiver, 101, 3),
+ types.NewSendToEthereumTx(3, myTokenContractAddr, mySender, myReceiver, 102, 2),
+ },
+ TokenContract: myTokenContractAddr.Hex(),
+ Height: 1234567,
+ }
+
+ assert.Equal(t, expFirstBatch.Transactions, gfb.Transactions)
+
+ // and verify remaining available Tx in the pool
+ var gotUnbatchedTx []*types.SendToEthereum
+ input.GravityKeeper.IterateUnbatchedSendToEthereums(ctx, func(tx *types.SendToEthereum) bool {
+ gotUnbatchedTx = append(gotUnbatchedTx, tx)
+ return false
+ })
+ expUnbatchedTx := []*types.SendToEthereum{
+ types.NewSendToEthereumTx(1, myTokenContractAddr, mySender, myReceiver, 100, 2),
+ types.NewSendToEthereumTx(4, myTokenContractAddr, mySender, myReceiver, 103, 1),
+ }
+ assert.Equal(t, expUnbatchedTx, gotUnbatchedTx)
+
+ // CREATE SECOND, MORE PROFITABLE BATCH
+ // ====================================
+
+ // add some more TX to the pool to create a more profitable batch
+ input.AddSendToEthTxsToPool(t, ctx, myTokenContractAddr, mySender, myReceiver, 4, 5)
+
+ // create the more profitable batch
+ ctx = ctx.WithBlockTime(now)
+ // tx batch size is 2, so that some of them stay behind
+ secondBatch := input.GravityKeeper.BuildBatchTx(ctx, myTokenContractAddr, 2)
+
+ // check that the more profitable batch has the right txs in it
+ expSecondBatch := &types.BatchTx{
+ BatchNonce: 2,
+ Transactions: []*types.SendToEthereum{
+ types.NewSendToEthereumTx(6, myTokenContractAddr, mySender, myReceiver, 101, 5),
+ types.NewSendToEthereumTx(5, myTokenContractAddr, mySender, myReceiver, 100, 4),
+ },
+ TokenContract: myTokenContractAddr.Hex(),
+ Height: 1234567,
+ }
+
+ assert.Equal(t, expSecondBatch, secondBatch)
+
+ // EXECUTE THE MORE PROFITABLE BATCH
+ // =================================
+
+ // Execute the batch
+ input.GravityKeeper.batchTxExecuted(ctx, common.HexToAddress(secondBatch.TokenContract), secondBatch.BatchNonce)
+
+ // check batch has been deleted
+ gotSecondBatch := input.GravityKeeper.GetOutgoingTx(ctx, secondBatch.GetStoreIndex())
+ require.Nil(t, gotSecondBatch)
+
+ // check that txs from first batch have been freed
+ gotUnbatchedTx = nil
+ input.GravityKeeper.IterateUnbatchedSendToEthereums(ctx, func(tx *types.SendToEthereum) bool {
+ gotUnbatchedTx = append(gotUnbatchedTx, tx)
+ return false
+ })
+ expUnbatchedTx = []*types.SendToEthereum{
+ types.NewSendToEthereumTx(2, myTokenContractAddr, mySender, myReceiver, 101, 3),
+ types.NewSendToEthereumTx(3, myTokenContractAddr, mySender, myReceiver, 102, 2),
+ types.NewSendToEthereumTx(1, myTokenContractAddr, mySender, myReceiver, 100, 2),
+ types.NewSendToEthereumTx(4, myTokenContractAddr, mySender, myReceiver, 103, 1),
+ }
+ assert.Equal(t, expUnbatchedTx, gotUnbatchedTx)
+}
+
+// tests that batches work with large token amounts, mostly a duplicate of the above
+// tests but using much bigger numbers
+func TestBatchesFullCoins(t *testing.T) {
+ input := CreateTestEnv(t)
+ ctx := input.Context
+ var (
+ now = time.Now().UTC()
+ mySender, _ = sdk.AccAddressFromBech32("cosmos1ahx7f8wyertuus9r20284ej0asrs085case3kn")
+ myReceiver = common.HexToAddress("0xd041c41EA1bf0F006ADBb6d2c9ef9D425dE5eaD7")
+ myTokenContractAddr = common.HexToAddress("0x429881672B9AE42b8EbA0E26cD9C73711b891Ca5") // Pickle
+ totalCoins, _ = sdk.NewIntFromString("1500000000000000000000") // 1,500 ETH worth
+ oneEth, _ = sdk.NewIntFromString("1000000000000000000")
+ allVouchers = sdk.NewCoins(
+ types.NewSDKIntERC20Token(totalCoins, myTokenContractAddr).GravityCoin(),
+ )
+ )
+
+ // mint some voucher first
+ require.NoError(t, input.BankKeeper.MintCoins(ctx, types.ModuleName, allVouchers))
+ // set senders balance
+ input.AccountKeeper.NewAccountWithAddress(ctx, mySender)
+ require.NoError(t, fundAccount(ctx, input.BankKeeper, mySender, allVouchers))
+
+ // CREATE FIRST BATCH
+ // ==================
+
+ // add some TX to the pool
+ for _, v := range []uint64{20, 300, 25, 10} {
+ vAsSDKInt := sdk.NewIntFromUint64(v)
+ amount := types.NewSDKIntERC20Token(oneEth.Mul(vAsSDKInt), myTokenContractAddr).GravityCoin()
+ fee := types.NewSDKIntERC20Token(oneEth.Mul(vAsSDKInt), myTokenContractAddr).GravityCoin()
+ _, err := input.GravityKeeper.createSendToEthereum(ctx, mySender, myReceiver.Hex(), amount, fee)
+ require.NoError(t, err)
+ }
+
+ // when
+ ctx = ctx.WithBlockTime(now)
+
+ // tx batch size is 2, so that some of them stay behind
+ firstBatch := input.GravityKeeper.BuildBatchTx(ctx, myTokenContractAddr, 2)
+
+ // then batch is persisted
+ gotFirstBatch := input.GravityKeeper.GetOutgoingTx(ctx, firstBatch.GetStoreIndex())
+ require.NotNil(t, gotFirstBatch)
+
+ expFirstBatch := &types.BatchTx{
+ BatchNonce: 1,
+ Transactions: []*types.SendToEthereum{
+ {
+ Id: 2,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(300)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(300)), myTokenContractAddr),
+ },
+ {
+ Id: 3,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(25)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(25)), myTokenContractAddr),
+ },
+ },
+ TokenContract: myTokenContractAddr.Hex(),
+ Height: 1234567,
+ }
+ assert.Equal(t, expFirstBatch, gotFirstBatch)
+
+ // and verify remaining available Tx in the pool
+ var gotUnbatchedTx []*types.SendToEthereum
+ input.GravityKeeper.IterateUnbatchedSendToEthereums(ctx, func(tx *types.SendToEthereum) bool {
+ gotUnbatchedTx = append(gotUnbatchedTx, tx)
+ return false
+ })
+ expUnbatchedTx := []*types.SendToEthereum{
+ {
+ Id: 1,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(20)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(20)), myTokenContractAddr),
+ },
+ {
+ Id: 4,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(10)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(10)), myTokenContractAddr),
+ },
+ }
+ assert.Equal(t, expUnbatchedTx, gotUnbatchedTx)
+
+ // CREATE SECOND, MORE PROFITABLE BATCH
+ // ====================================
+
+ // add some more TX to the pool to create a more profitable batch
+ for _, v := range []uint64{4, 5} {
+ vAsSDKInt := sdk.NewIntFromUint64(v)
+ amount := types.NewSDKIntERC20Token(oneEth.Mul(vAsSDKInt), myTokenContractAddr).GravityCoin()
+ fee := types.NewSDKIntERC20Token(oneEth.Mul(vAsSDKInt), myTokenContractAddr).GravityCoin()
+ _, err := input.GravityKeeper.createSendToEthereum(ctx, mySender, myReceiver.Hex(), amount, fee)
+ require.NoError(t, err)
+ }
+
+ // create the more profitable batch
+ ctx = ctx.WithBlockTime(now)
+ // tx batch size is 2, so that some of them stay behind
+ secondBatch := input.GravityKeeper.BuildBatchTx(ctx, myTokenContractAddr, 2)
+
+ // check that the more profitable batch has the right txs in it
+ expSecondBatch := &types.BatchTx{
+ BatchNonce: 2,
+ Transactions: []*types.SendToEthereum{
+ {
+ Id: 1,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(20)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(20)), myTokenContractAddr),
+ },
+ {
+ Id: 4,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(10)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(10)), myTokenContractAddr),
+ },
+ },
+ TokenContract: myTokenContractAddr.Hex(),
+ Height: 1234567,
+ }
+
+ assert.Equal(t, expSecondBatch, secondBatch)
+
+ // EXECUTE THE MORE PROFITABLE BATCH
+ // =================================
+
+ // Execute the batch
+ input.GravityKeeper.batchTxExecuted(ctx, common.HexToAddress(secondBatch.TokenContract), secondBatch.BatchNonce)
+
+ // check batch has been deleted
+ gotSecondBatch := input.GravityKeeper.GetOutgoingTx(ctx, secondBatch.GetStoreIndex())
+ require.Nil(t, gotSecondBatch)
+
+ // check that txs from first batch have been freed
+ gotUnbatchedTx = nil
+ input.GravityKeeper.IterateUnbatchedSendToEthereums(ctx, func(tx *types.SendToEthereum) bool {
+ gotUnbatchedTx = append(gotUnbatchedTx, tx)
+ return false
+ })
+ expUnbatchedTx = []*types.SendToEthereum{
+ {
+ Id: 2,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(300)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(300)), myTokenContractAddr),
+ },
+ {
+ Id: 3,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(25)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(25)), myTokenContractAddr),
+ },
+ {
+ Id: 6,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(5)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(5)), myTokenContractAddr),
+ },
+ {
+ Id: 5,
+ Erc20Fee: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(4)), myTokenContractAddr),
+ Sender: mySender.String(),
+ EthereumRecipient: myReceiver.Hex(),
+ Erc20Token: types.NewSDKIntERC20Token(oneEth.Mul(sdk.NewIntFromUint64(4)), myTokenContractAddr),
+ },
+ }
+ assert.Equal(t, expUnbatchedTx, gotUnbatchedTx)
+}
+
+func TestPoolTxRefund(t *testing.T) {
+ input := CreateTestEnv(t)
+ ctx := input.Context
+ var (
+ now = time.Now().UTC()
+ mySender, _ = sdk.AccAddressFromBech32("cosmos1ahx7f8wyertuus9r20284ej0asrs085case3kn")
+ myReceiver = common.HexToAddress("0xd041c41EA1bf0F006ADBb6d2c9ef9D425dE5eaD7")
+ myTokenContractAddr = common.HexToAddress("0x429881672B9AE42b8EbA0E26cD9C73711b891Ca5") // Pickle
+ allVouchers = sdk.NewCoins(
+ types.NewERC20Token(414, myTokenContractAddr.Hex()).GravityCoin(),
+ )
+ myDenom = types.NewERC20Token(1, myTokenContractAddr.Hex()).GravityCoin().Denom
+ )
+
+ // mint some voucher first
+ require.NoError(t, input.BankKeeper.MintCoins(ctx, types.ModuleName, allVouchers))
+ // set senders balance
+ input.AccountKeeper.NewAccountWithAddress(ctx, mySender)
+ require.NoError(t, fundAccount(ctx, input.BankKeeper, mySender, allVouchers))
+
+ // CREATE FIRST BATCH
+ // ==================
+
+ // add some TX to the pool
+ // for i, v := range []uint64{2, 3, 2, 1} {
+ // amount := types.NewERC20Token(uint64(i+100), myTokenContractAddr).GravityCoin()
+ // fee := types.NewERC20Token(v, myTokenContractAddr).GravityCoin()
+ // _, err := input.GravityKeeper.CreateSendToEthereum(ctx, mySender, myReceiver, amount, fee)
+ // require.NoError(t, err)
+ // }
+ input.AddSendToEthTxsToPool(t, ctx, myTokenContractAddr, mySender, myReceiver, 2, 3, 2, 1)
+
+ // when
+ ctx = ctx.WithBlockTime(now)
+
+ // tx batch size is 2, so that some of them stay behind
+ input.GravityKeeper.BuildBatchTx(ctx, myTokenContractAddr, 2)
+
+ // try to refund a tx that's in a batch
+ err := input.GravityKeeper.cancelSendToEthereum(ctx, 2, mySender.String())
+ require.Error(t, err)
+
+ // try to refund a tx that's in the pool
+ err = input.GravityKeeper.cancelSendToEthereum(ctx, 4, mySender.String())
+ require.NoError(t, err)
+
+ // make sure refund was issued
+ balances := input.BankKeeper.GetAllBalances(ctx, mySender)
+ require.Equal(t, sdk.NewInt(104), balances.AmountOf(myDenom))
+}
diff --git a/module/x/gravity/keeper/cosmos_originated.go b/module/x/gravity/keeper/cosmos_originated.go
new file mode 100644
index 0000000..1681671
--- /dev/null
+++ b/module/x/gravity/keeper/cosmos_originated.go
@@ -0,0 +1,94 @@
+package keeper
+
+import (
+ "fmt"
+
+ "github.com/cosmos/cosmos-sdk/store/prefix"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+func (k Keeper) getCosmosOriginatedDenom(ctx sdk.Context, tokenContract string) (string, bool) {
+ store := ctx.KVStore(k.storeKey)
+ bz := store.Get(types.MakeERC20ToDenomKey(tokenContract))
+
+ if bz != nil {
+ return string(bz), true
+ }
+ return "", false
+}
+
+func (k Keeper) getCosmosOriginatedERC20(ctx sdk.Context, denom string) (common.Address, bool) {
+ store := ctx.KVStore(k.storeKey)
+ bz := store.Get(types.MakeDenomToERC20Key(denom))
+
+ if bz != nil {
+ return common.BytesToAddress(bz), true
+ }
+ return common.BytesToAddress([]byte{}), false
+}
+
+func (k Keeper) setCosmosOriginatedDenomToERC20(ctx sdk.Context, denom string, tokenContract string) {
+ store := ctx.KVStore(k.storeKey)
+ store.Set(types.MakeDenomToERC20Key(denom), common.HexToAddress(tokenContract).Bytes())
+ store.Set(types.MakeERC20ToDenomKey(tokenContract), []byte(denom))
+}
+
+// DenomToERC20 returns (bool isCosmosOriginated, string ERC20, err)
+// Using this information, you can see if an asset is native to Cosmos or Ethereum,
+// and get its corresponding ERC20 address.
+// This will return an error if it cant parse the denom as a gravity denom, and then also can't find the denom
+// in an index of ERC20 contracts deployed on Ethereum to serve as synthetic Cosmos assets.
+func (k Keeper) DenomToERC20Lookup(ctx sdk.Context, denom string) (bool, common.Address, error) {
+ // First try parsing the ERC20 out of the denom
+ tc1, err := types.GravityDenomToERC20(denom)
+ if err != nil {
+ // Look up ERC20 contract in index and error if it's not in there.
+ tc2, exists := k.getCosmosOriginatedERC20(ctx, denom)
+ if !exists {
+ return false, common.Address{},
+ fmt.Errorf("denom not a gravity voucher coin: %s, and also not in cosmos-originated ERC20 index", err)
+ }
+ // This is a cosmos-originated asset
+ return true, tc2, nil
+ }
+
+ // This is an ethereum-originated asset
+ return false, common.HexToAddress(tc1), nil
+}
+
+// ERC20ToDenom returns (bool isCosmosOriginated, string denom, err)
+// Using this information, you can see if an ERC20 address represents an asset is native to Cosmos or Ethereum,
+// and get its corresponding denom
+func (k Keeper) ERC20ToDenomLookup(ctx sdk.Context, tokenContract string) (bool, string) {
+ // First try looking up tokenContract in index
+ dn1, exists := k.getCosmosOriginatedDenom(ctx, tokenContract)
+ if exists {
+ // It is a cosmos originated asset
+ return true, dn1
+ }
+
+ // If it is not in there, it is not a cosmos originated token, turn the ERC20 into a gravity denom
+
+ return false, types.NewERC20Token(0, tokenContract).GravityCoin().Denom
+}
+
+// iterateERC20ToDenom iterates over erc20 to denom relations
+func (k Keeper) iterateERC20ToDenom(ctx sdk.Context, cb func([]byte, *types.ERC20ToDenom) bool) {
+ prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{types.ERC20ToDenomKey})
+ iter := prefixStore.Iterator(nil, nil)
+ defer iter.Close()
+
+ for ; iter.Valid(); iter.Next() {
+ erc20ToDenom := types.ERC20ToDenom{
+ Erc20: string(iter.Key()),
+ Denom: string(iter.Value()),
+ }
+ // cb returns true to stop early
+ if cb(iter.Key(), &erc20ToDenom) {
+ break
+ }
+ }
+}
diff --git a/module/x/gravity/keeper/ethereum_event_handler.go b/module/x/gravity/keeper/ethereum_event_handler.go
new file mode 100644
index 0000000..085b587
--- /dev/null
+++ b/module/x/gravity/keeper/ethereum_event_handler.go
@@ -0,0 +1,194 @@
+package keeper
+
+import (
+ "math/big"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+// EthereumEventProcessor processes `accepted` EthereumEvents
+type EthereumEventProcessor struct {
+ keeper Keeper
+ bankKeeper types.BankKeeper
+}
+
+func (a EthereumEventProcessor) DetectMaliciousSupply(ctx sdk.Context, denom string, amount sdk.Int) (err error) {
+ currentSupply := a.keeper.bankKeeper.GetSupply(ctx, denom)
+ newSupply := new(big.Int).Add(currentSupply.Amount.BigInt(), amount.BigInt())
+ if newSupply.BitLen() > 256 {
+ return sdkerrors.Wrapf(types.ErrSupplyOverflow, "malicious supply of %s detected", denom)
+ }
+
+ return nil
+}
+
+// Handle is the entry point for EthereumEvent processing
+func (a EthereumEventProcessor) Handle(ctx sdk.Context, eve types.EthereumEvent) (err error) {
+ switch event := eve.(type) {
+ case *types.SendToCosmosEvent:
+ // Check if coin is Cosmos-originated asset and get denom
+ isCosmosOriginated, denom := a.keeper.ERC20ToDenomLookup(ctx, event.TokenContract)
+ addr, _ := sdk.AccAddressFromBech32(event.CosmosReceiver)
+ coins := sdk.Coins{sdk.NewCoin(denom, event.Amount)}
+
+ if !isCosmosOriginated {
+ if err := a.DetectMaliciousSupply(ctx, denom, event.Amount); err != nil {
+ return err
+ }
+
+ // if it is not cosmos originated, mint the coins (aka vouchers)
+ if err := a.bankKeeper.MintCoins(ctx, types.ModuleName, coins); err != nil {
+ return sdkerrors.Wrapf(err, "mint vouchers coins: %s", coins)
+ }
+ }
+
+ if err := a.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins); err != nil {
+ return err
+ }
+ a.keeper.AfterSendToCosmosEvent(ctx, *event)
+ return nil
+
+ case *types.BatchExecutedEvent:
+ a.keeper.batchTxExecuted(ctx, common.HexToAddress(event.TokenContract), event.BatchNonce)
+ a.keeper.AfterBatchExecutedEvent(ctx, *event)
+ return nil
+
+ case *types.ERC20DeployedEvent:
+ if err := a.verifyERC20DeployedEvent(ctx, event); err != nil {
+ return err
+ }
+
+ // add to denom-erc20 mapping
+ a.keeper.setCosmosOriginatedDenomToERC20(ctx, event.CosmosDenom, event.TokenContract)
+ a.keeper.AfterERC20DeployedEvent(ctx, *event)
+ return nil
+
+ case *types.ContractCallExecutedEvent:
+ a.keeper.AfterContractCallExecutedEvent(ctx, *event)
+ return nil
+
+ case *types.SignerSetTxExecutedEvent:
+ // TODO here we should check the contents of the validator set against
+ // the store, if they differ we should take some action to indicate to the
+ // user that bridge highjacking has occurred
+ a.keeper.setLastObservedSignerSetTx(ctx, types.SignerSetTx{
+ Nonce: event.SignerSetTxNonce,
+ Signers: event.Members,
+ })
+ a.keeper.AfterSignerSetExecutedEvent(ctx, *event)
+ return nil
+
+ default:
+ return sdkerrors.Wrapf(types.ErrInvalid, "event type: %T", event)
+ }
+}
+
+func (a EthereumEventProcessor) verifyERC20DeployedEvent(ctx sdk.Context, event *types.ERC20DeployedEvent) error {
+ if existingERC20, exists := a.keeper.getCosmosOriginatedERC20(ctx, event.CosmosDenom); exists {
+ return sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "ERC20 token %s already exists for denom %s", existingERC20.Hex(), event.CosmosDenom,
+ )
+ }
+
+ // We expect that all Cosmos-based tokens have metadata defined. In the case
+ // a token does not have metadata defined, e.g. an IBC token, we successfully
+ // handle the token under the following conditions:
+ //
+ // 1. The ERC20 name is equal to the token's denomination. Otherwise, this
+ // means that ERC20 tokens would have an untenable UX.
+ // 2. The ERC20 token has zero decimals as this is what we default to since
+ // we cannot know or infer the real decimal value for the Cosmos token.
+ // 3. The ERC20 symbol is empty.
+ //
+ // NOTE: This path is not encouraged and all supported assets should have
+ // metadata defined. If metadata cannot be defined, consider adding the token's
+ // metadata on the fly.
+ if md, ok := a.keeper.bankKeeper.GetDenomMetaData(ctx, event.CosmosDenom); ok && md.Base != "" {
+ return verifyERC20Token(md, event)
+ }
+
+ if supply := a.keeper.bankKeeper.GetSupply(ctx, event.CosmosDenom); supply.IsZero() {
+ return sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "no supply exists for token %s without metadata", event.CosmosDenom,
+ )
+ }
+
+ if event.Erc20Name != event.CosmosDenom {
+ return sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "invalid ERC20 name for token without metadata; got: %s, expected: %s", event.Erc20Name, event.CosmosDenom,
+ )
+ }
+
+ if event.Erc20Symbol != "" {
+ return sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "expected empty ERC20 symbol for token without metadata; got: %s", event.Erc20Symbol,
+ )
+ }
+
+ if event.Erc20Decimals != 0 {
+ return sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "expected zero ERC20 decimals for token without metadata; got: %d", event.Erc20Decimals,
+ )
+ }
+
+ return nil
+}
+
+func verifyERC20Token(metadata banktypes.Metadata, event *types.ERC20DeployedEvent) error {
+ if event.Erc20Name != metadata.Display {
+ return sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "ERC20 name %s does not match the denom display %s", event.Erc20Name, metadata.Display,
+ )
+ }
+
+ if event.Erc20Symbol != metadata.Display {
+ return sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "ERC20 symbol %s does not match denom display %s", event.Erc20Symbol, metadata.Display,
+ )
+ }
+
+ // ERC20 tokens use a very simple mechanism to tell you where to display the
+ // decimal point. The "decimals" field simply tells you how many decimal places
+ // there will be.
+ //
+ // Cosmos denoms have a system that is much more full featured, with
+ // enterprise-ready token denominations. There is a DenomUnits array that
+ // tells you what the name of each denomination of the token is.
+ //
+ // To correlate this with an ERC20 "decimals" field, we have to search through
+ // the DenomUnits array to find the DenomUnit which matches up to the main
+ // token "display" value. Then we take the "exponent" from this DenomUnit.
+ //
+ // If the correct DenomUnit is not found, it will default to 0. This will
+ // result in there being no decimal places in the token's ERC20 on Ethereum.
+ // For example, if this happened with ATOM, 1 ATOM would appear on Ethereum
+ // as 1 million ATOM, having 6 extra places before the decimal point.
+ var decimals uint32
+ for _, denomUnit := range metadata.DenomUnits {
+ if denomUnit.Denom == metadata.Display {
+ decimals = denomUnit.Exponent
+ break
+ }
+ }
+
+ if uint64(decimals) != event.Erc20Decimals {
+ return sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "ERC20 decimals %d does not match denom decimals %d", event.Erc20Decimals, decimals,
+ )
+ }
+
+ return nil
+}
diff --git a/module/x/gravity/keeper/ethereum_event_handler_test.go b/module/x/gravity/keeper/ethereum_event_handler_test.go
new file mode 100644
index 0000000..8f45c19
--- /dev/null
+++ b/module/x/gravity/keeper/ethereum_event_handler_test.go
@@ -0,0 +1,21 @@
+package keeper
+
+import (
+ sdktypes "github.com/cosmos/cosmos-sdk/types"
+ "github.com/stretchr/testify/require"
+ "math/big"
+ "testing"
+)
+
+func TestEthereumEventProcessor_DetectMaliciousSupply(t *testing.T) {
+ input := CreateTestEnv(t)
+ eep := EthereumEventProcessor{keeper: input.GravityKeeper, bankKeeper: input.BankKeeper}
+
+ // set supply to maximum value
+ var testBigInt big.Int
+ testBigInt.SetBit(new(big.Int), 256, 1).Sub(&testBigInt, big.NewInt(1))
+ bigCoinAmount := sdktypes.NewIntFromBigInt(&testBigInt)
+
+ err := eep.DetectMaliciousSupply(input.Context, "stake", bigCoinAmount)
+ require.Error(t, err, "didn't error out on too much added supply")
+}
\ No newline at end of file
diff --git a/module/x/gravity/keeper/ethereum_event_vote.go b/module/x/gravity/keeper/ethereum_event_vote.go
new file mode 100644
index 0000000..b7c7489
--- /dev/null
+++ b/module/x/gravity/keeper/ethereum_event_vote.go
@@ -0,0 +1,280 @@
+package keeper
+
+import (
+ "encoding/binary"
+ "fmt"
+ "strconv"
+
+ "github.com/cosmos/cosmos-sdk/store/prefix"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+func (k Keeper) recordEventVote(
+ ctx sdk.Context,
+ event types.EthereumEvent,
+ val sdk.ValAddress,
+) (*types.EthereumEventVoteRecord, error) {
+ // Check that the nonce of this event is exactly one higher than the last nonce stored by this validator.
+ // We check the event nonce in processEthereumEvent as well,
+ // but checking it here gives individual eth signers a chance to retry,
+ // and prevents validators from submitting two claims with the same nonce
+ lastEventNonce := k.getLastEventNonceByValidator(ctx, val)
+ expectedNonce := lastEventNonce + 1
+ if event.GetEventNonce() != expectedNonce {
+ return nil, sdkerrors.Wrapf(types.ErrInvalid,
+ "non contiguous event nonce expected %v observed %v for validator %v",
+ expectedNonce,
+ event.GetEventNonce(),
+ val,
+ )
+ }
+
+ // Tries to get an EthereumEventVoteRecord with the same eventNonce and event as the event that was submitted.
+ eventVoteRecord := k.GetEthereumEventVoteRecord(ctx, event.GetEventNonce(), event.Hash())
+
+ // If it does not exist, create a new one.
+ if eventVoteRecord == nil {
+ any, err := types.PackEvent(event)
+ if err != nil {
+ return nil, err
+ }
+ eventVoteRecord = &types.EthereumEventVoteRecord{
+ Accepted: false,
+ Event: any,
+ }
+ }
+
+ // Add the validator's vote to this EthereumEventVoteRecord
+ eventVoteRecord.Votes = append(eventVoteRecord.Votes, val.String())
+
+ k.setEthereumEventVoteRecord(ctx, event.GetEventNonce(), event.Hash(), eventVoteRecord)
+ k.setLastEventNonceByValidator(ctx, val, event.GetEventNonce())
+
+ return eventVoteRecord, nil
+}
+
+// TryEventVoteRecord checks if an event vote record has enough votes to be applied to the consensus state
+// and has not already been marked Observed, then calls processEthereumEvent to actually apply it to the state,
+// and then marks it Observed and emits an event.
+func (k Keeper) TryEventVoteRecord(ctx sdk.Context, eventVoteRecord *types.EthereumEventVoteRecord) {
+ // If the event vote record has not yet been Observed, sum up the votes and see if it is ready to apply to the state.
+ // This conditional stops the event vote record from accidentally being applied twice.
+ if !eventVoteRecord.Accepted {
+ var event types.EthereumEvent
+ if err := k.cdc.UnpackAny(eventVoteRecord.Event, &event); err != nil {
+ panic("unpacking packed any")
+ }
+
+ // Sum the current powers of all validators who have voted and see if it passes the current threshold
+ // TODO: The different integer types and math here needs a careful review
+ requiredPower := types.EventVoteRecordPowerThreshold(k.StakingKeeper.GetLastTotalPower(ctx))
+ eventVotePower := sdk.NewInt(0)
+ for _, validator := range eventVoteRecord.Votes {
+ val, _ := sdk.ValAddressFromBech32(validator)
+
+ validatorPower := k.StakingKeeper.GetLastValidatorPower(ctx, val)
+ // Add it to the attestation power's sum
+ eventVotePower = eventVotePower.Add(sdk.NewInt(validatorPower))
+ // If the power of all the validators that have voted on the attestation is higher or equal to the threshold,
+ // process the attestation, set Observed to true, and break
+ if eventVotePower.GTE(requiredPower) {
+ lastEventNonce := k.GetLastObservedEventNonce(ctx)
+ // this check is performed at the next level up so this should never panic
+ // outside of programmer error.
+ if event.GetEventNonce() != lastEventNonce+1 {
+ panic("attempting to apply events to state out of order")
+ }
+ k.setLastObservedEventNonce(ctx, event.GetEventNonce())
+ k.SetLastObservedEthereumBlockHeight(ctx, event.GetEthereumHeight())
+
+ eventVoteRecord.Accepted = true
+ k.setEthereumEventVoteRecord(ctx, event.GetEventNonce(), event.Hash(), eventVoteRecord)
+
+ k.processEthereumEvent(ctx, event)
+ ctx.EventManager().EmitEvent(sdk.NewEvent(
+ types.EventTypeObservation,
+ sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
+ sdk.NewAttribute(types.AttributeKeyEthereumEventType, fmt.Sprintf("%T", event)),
+ sdk.NewAttribute(types.AttributeKeyContract, k.getBridgeContractAddress(ctx)),
+ sdk.NewAttribute(types.AttributeKeyBridgeChainID, strconv.Itoa(int(k.getBridgeChainID(ctx)))),
+ sdk.NewAttribute(types.AttributeKeyEthereumEventVoteRecordID,
+ string(types.MakeEthereumEventVoteRecordKey(event.GetEventNonce(), event.Hash()))),
+ sdk.NewAttribute(types.AttributeKeyNonce, fmt.Sprint(event.GetEventNonce())),
+ ))
+
+ break
+ }
+ }
+ } else {
+ // We panic here because this should never happen
+ panic("attempting to process observed ethereum event")
+ }
+}
+
+// processEthereumEvent actually applies the attestation to the consensus state
+func (k Keeper) processEthereumEvent(ctx sdk.Context, event types.EthereumEvent) {
+ // then execute in a new Tx so that we can store state on failure
+ xCtx, commit := ctx.CacheContext()
+ if err := k.EthereumEventProcessor.Handle(xCtx, event); err != nil { // execute with a transient storage
+ // If the attestation fails, something has gone wrong and we can't recover it. Log and move on
+ // The attestation will still be marked "Observed", and validators can still be slashed for not
+ // having voted for it.
+ k.Logger(ctx).Error(
+ "ethereum event vote record failed",
+ "cause", err.Error(),
+ "event type", fmt.Sprintf("%T", event),
+ "id", types.MakeEthereumEventVoteRecordKey(event.GetEventNonce(), event.Hash()),
+ "nonce", fmt.Sprint(event.GetEventNonce()),
+ )
+ } else {
+ commit() // persist transient storage
+ }
+}
+
+// setEthereumEventVoteRecord sets the attestation in the store
+func (k Keeper) setEthereumEventVoteRecord(ctx sdk.Context, eventNonce uint64, claimHash []byte, eventVoteRecord *types.EthereumEventVoteRecord) {
+ ctx.KVStore(k.storeKey).Set(types.MakeEthereumEventVoteRecordKey(eventNonce, claimHash), k.cdc.MustMarshal(eventVoteRecord))
+}
+
+// GetEthereumEventVoteRecord return a vote record given a nonce
+func (k Keeper) GetEthereumEventVoteRecord(ctx sdk.Context, eventNonce uint64, claimHash []byte) *types.EthereumEventVoteRecord {
+ if bz := ctx.KVStore(k.storeKey).Get(types.MakeEthereumEventVoteRecordKey(eventNonce, claimHash)); bz == nil {
+ return nil
+ } else {
+ var out types.EthereumEventVoteRecord
+ k.cdc.MustUnmarshal(bz, &out)
+ return &out
+ }
+}
+
+// GetEthereumEventVoteRecordMapping returns a mapping of eventnonce -> attestations at that nonce
+func (k Keeper) GetEthereumEventVoteRecordMapping(ctx sdk.Context) (out map[uint64][]*types.EthereumEventVoteRecord) {
+ out = make(map[uint64][]*types.EthereumEventVoteRecord)
+ k.iterateEthereumEventVoteRecords(ctx, func(key []byte, eventVoteRecord *types.EthereumEventVoteRecord) bool {
+ event, err := types.UnpackEvent(eventVoteRecord.Event)
+ if err != nil {
+ panic(err)
+ }
+ if val, ok := out[event.GetEventNonce()]; !ok {
+ out[event.GetEventNonce()] = []*types.EthereumEventVoteRecord{eventVoteRecord}
+ } else {
+ out[event.GetEventNonce()] = append(val, eventVoteRecord)
+ }
+ return false
+ })
+ return
+}
+
+// iterateEthereumEventVoteRecords iterates through all attestations
+func (k Keeper) iterateEthereumEventVoteRecords(ctx sdk.Context, cb func([]byte, *types.EthereumEventVoteRecord) bool) {
+ store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{types.EthereumEventVoteRecordKey})
+ iter := store.Iterator(nil, nil)
+ defer iter.Close()
+ for ; iter.Valid(); iter.Next() {
+ att := &types.EthereumEventVoteRecord{}
+ k.cdc.MustUnmarshal(iter.Value(), att)
+ // cb returns true to stop early
+ if cb(iter.Key(), att) {
+ return
+ }
+ }
+}
+
+// GetLastObservedEventNonce returns the latest observed event nonce
+func (k Keeper) GetLastObservedEventNonce(ctx sdk.Context) uint64 {
+ store := ctx.KVStore(k.storeKey)
+ bytes := store.Get([]byte{types.LastObservedEventNonceKey})
+
+ if len(bytes) == 0 {
+ return 0
+ }
+ return binary.BigEndian.Uint64(bytes)
+}
+
+// GetLastObservedEthereumBlockHeight height gets the block height to of the last observed attestation from
+// the store
+func (k Keeper) GetLastObservedEthereumBlockHeight(ctx sdk.Context) types.LatestEthereumBlockHeight {
+ store := ctx.KVStore(k.storeKey)
+ bytes := store.Get([]byte{types.LastEthereumBlockHeightKey})
+
+ if len(bytes) == 0 {
+ return types.LatestEthereumBlockHeight{
+ CosmosHeight: 0,
+ EthereumHeight: 0,
+ }
+ }
+ height := types.LatestEthereumBlockHeight{}
+ k.cdc.MustUnmarshal(bytes, &height)
+ return height
+}
+
+// SetLastObservedEthereumBlockHeight sets the block height in the store.
+func (k Keeper) SetLastObservedEthereumBlockHeight(ctx sdk.Context, ethereumHeight uint64) {
+ store := ctx.KVStore(k.storeKey)
+ height := types.LatestEthereumBlockHeight{
+ EthereumHeight: ethereumHeight,
+ CosmosHeight: uint64(ctx.BlockHeight()),
+ }
+ store.Set([]byte{types.LastEthereumBlockHeightKey}, k.cdc.MustMarshal(&height))
+}
+
+// setLastObservedEventNonce sets the latest observed event nonce
+func (k Keeper) setLastObservedEventNonce(ctx sdk.Context, nonce uint64) {
+ store := ctx.KVStore(k.storeKey)
+ store.Set([]byte{types.LastObservedEventNonceKey}, sdk.Uint64ToBigEndian(nonce))
+}
+
+// getLastEventNonceByValidator returns the latest event nonce for a given validator
+func (k Keeper) getLastEventNonceByValidator(ctx sdk.Context, validator sdk.ValAddress) uint64 {
+ store := ctx.KVStore(k.storeKey)
+ bytes := store.Get(types.MakeLastEventNonceByValidatorKey(validator))
+
+ if len(bytes) == 0 {
+ // in the case that we have no existing value this is the first
+ // time a validator is submitting a claim. Since we don't want to force
+ // them to replay the entire history of all events ever we can't start
+ // at zero
+ //
+ // We could start at the LastObservedEventNonce but if we do that this
+ // validator will be slashed, because they are responsible for making a claim
+ // on any attestation that has not yet passed the slashing window.
+ //
+ // Therefore we need to return to them the lowest attestation that is still within
+ // the slashing window. Since we delete attestations after the slashing window that's
+ // just the lowest observed event in the store. If no claims have been submitted in for
+ // params.SignedClaimsWindow we may have no attestations in our nonce. At which point
+ // the last observed which is a persistent and never cleaned counter will suffice.
+ lowestObserved := k.GetLastObservedEventNonce(ctx)
+ attmap := k.GetEthereumEventVoteRecordMapping(ctx)
+ // no new claims in params.SignedClaimsWindow, we can return the current value
+ // because the validator can't be slashed for an event that has already passed.
+ // so they only have to worry about the *next* event to occur
+ if len(attmap) == 0 {
+ return lowestObserved
+ }
+ for nonce, atts := range attmap {
+ for att := range atts {
+ if atts[att].Accepted && nonce < lowestObserved {
+ lowestObserved = nonce
+ }
+ }
+ }
+ // return the latest event minus one so that the validator
+ // can submit that event and avoid slashing. special case
+ // for zero
+ if lowestObserved > 0 {
+ return lowestObserved - 1
+ }
+ return 0
+ }
+ return binary.BigEndian.Uint64(bytes)
+}
+
+// setLastEventNonceByValidator sets the latest event nonce for a give validator
+func (k Keeper) setLastEventNonceByValidator(ctx sdk.Context, validator sdk.ValAddress, nonce uint64) {
+ store := ctx.KVStore(k.storeKey)
+ store.Set(types.MakeLastEventNonceByValidatorKey(validator), sdk.Uint64ToBigEndian(nonce))
+}
diff --git a/module/x/gravity/keeper/genesis.go b/module/x/gravity/keeper/genesis.go
new file mode 100644
index 0000000..e3ecfe0
--- /dev/null
+++ b/module/x/gravity/keeper/genesis.go
@@ -0,0 +1,170 @@
+package keeper
+
+import (
+ cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+// InitGenesis starts a chain from a genesis state
+func InitGenesis(ctx sdk.Context, k Keeper, data types.GenesisState) {
+ k.setParams(ctx, *data.Params)
+
+ // reset pool transactions in state
+ for _, tx := range data.UnbatchedSendToEthereumTxs {
+ k.setUnbatchedSendToEthereum(ctx, tx)
+ }
+
+ // reset ethereum event vote records in state
+ for _, evr := range data.EthereumEventVoteRecords {
+ event, err := types.UnpackEvent(evr.Event)
+ if err != nil {
+ panic("couldn't cast to event")
+ }
+ if err := event.Validate(); err != nil {
+ panic("invalid event in genesis")
+ }
+ k.setEthereumEventVoteRecord(ctx, event.GetEventNonce(), event.Hash(), evr)
+ }
+
+ // reset last observed event nonce
+ k.setLastObservedEventNonce(ctx, data.LastObservedEventNonce)
+
+ // reset attestation state of all validators
+ for _, eventVoteRecord := range data.EthereumEventVoteRecords {
+ event, _ := types.UnpackEvent(eventVoteRecord.Event)
+ for _, vote := range eventVoteRecord.Votes {
+ val, err := sdk.ValAddressFromBech32(vote)
+ if err != nil {
+ panic(err)
+ }
+ last := k.getLastEventNonceByValidator(ctx, val)
+ if event.GetEventNonce() > last {
+ k.setLastEventNonceByValidator(ctx, val, event.GetEventNonce())
+ }
+ }
+ }
+
+ // reset delegate keys in state
+ for _, keys := range data.DelegateKeys {
+ if err := keys.ValidateBasic(); err != nil {
+ panic("Invalid delegate key in Genesis!")
+ }
+
+ val, _ := sdk.ValAddressFromBech32(keys.ValidatorAddress)
+ orch, _ := sdk.AccAddressFromBech32(keys.OrchestratorAddress)
+ eth := common.HexToAddress(keys.EthereumAddress)
+
+ // set the orchestrator address
+ k.SetOrchestratorValidatorAddress(ctx, val, orch)
+ // set the ethereum address
+ k.setValidatorEthereumAddress(ctx, val, common.HexToAddress(keys.EthereumAddress))
+ k.setEthereumOrchestratorAddress(ctx, eth, orch)
+ }
+
+ // populate state with cosmos originated denom-erc20 mapping
+ for _, item := range data.Erc20ToDenoms {
+ k.setCosmosOriginatedDenomToERC20(ctx, item.Denom, item.Erc20)
+ }
+
+ // reset outgoing txs in state
+ for _, ota := range data.OutgoingTxs {
+ otx, err := types.UnpackOutgoingTx(ota)
+ if err != nil {
+ panic("invalid outgoing tx any in genesis file")
+ }
+ k.SetOutgoingTx(ctx, otx)
+ }
+
+ // reset signatures in state
+ for _, confa := range data.Confirmations {
+ conf, err := types.UnpackConfirmation(confa)
+ if err != nil {
+ panic("invalid etheruem signature in genesis")
+ }
+ // TODO: not currently an easy way to get the validator address from the
+ // etherum address here. once we implement the third index for keys
+ // this will be easy.
+ k.SetEthereumSignature(ctx, conf, sdk.ValAddress{})
+ }
+}
+
+// ExportGenesis exports all the state needed to restart the chain
+// from the current state of the chain
+func ExportGenesis(ctx sdk.Context, k Keeper) types.GenesisState {
+ var (
+ p = k.GetParams(ctx)
+ outgoingTxs []*cdctypes.Any
+ ethereumTxConfirmations []*cdctypes.Any
+ attmap = k.GetEthereumEventVoteRecordMapping(ctx)
+ ethereumEventVoteRecords []*types.EthereumEventVoteRecord
+ delegates = k.getDelegateKeys(ctx)
+ lastobserved = k.GetLastObservedEventNonce(ctx)
+ erc20ToDenoms []*types.ERC20ToDenom
+ unbatchedTransfers = k.getUnbatchedSendToEthereums(ctx)
+ )
+
+ // export ethereumEventVoteRecords from state
+ for _, atts := range attmap {
+ // TODO: set height = 0?
+ ethereumEventVoteRecords = append(ethereumEventVoteRecords, atts...)
+ }
+
+ // export erc20 to denom relations
+ k.iterateERC20ToDenom(ctx, func(key []byte, erc20ToDenom *types.ERC20ToDenom) bool {
+ erc20ToDenoms = append(erc20ToDenoms, erc20ToDenom)
+ return false
+ })
+
+ // export signer set txs and sigs
+ k.IterateOutgoingTxsByType(ctx, types.SignerSetTxPrefixByte, func(_ []byte, otx types.OutgoingTx) bool {
+ ota, _ := types.PackOutgoingTx(otx)
+ outgoingTxs = append(outgoingTxs, ota)
+ sstx, _ := otx.(*types.SignerSetTx)
+ k.iterateEthereumSignatures(ctx, sstx.GetStoreIndex(), func(val sdk.ValAddress, sig []byte) bool {
+ siga, _ := types.PackConfirmation(&types.SignerSetTxConfirmation{sstx.Nonce, k.GetValidatorEthereumAddress(ctx, val).Hex(), sig})
+ ethereumTxConfirmations = append(ethereumTxConfirmations, siga)
+ return false
+ })
+ return false
+ })
+
+ // export batch txs and sigs
+ k.IterateOutgoingTxsByType(ctx, types.BatchTxPrefixByte, func(_ []byte, otx types.OutgoingTx) bool {
+ ota, _ := types.PackOutgoingTx(otx)
+ outgoingTxs = append(outgoingTxs, ota)
+ btx, _ := otx.(*types.BatchTx)
+ k.iterateEthereumSignatures(ctx, btx.GetStoreIndex(), func(val sdk.ValAddress, sig []byte) bool {
+ siga, _ := types.PackConfirmation(&types.BatchTxConfirmation{btx.TokenContract, btx.BatchNonce, k.GetValidatorEthereumAddress(ctx, val).Hex(), sig})
+ ethereumTxConfirmations = append(ethereumTxConfirmations, siga)
+ return false
+ })
+ return false
+ })
+
+ // export contract call txs and sigs
+ k.IterateOutgoingTxsByType(ctx, types.ContractCallTxPrefixByte, func(_ []byte, otx types.OutgoingTx) bool {
+ ota, _ := types.PackOutgoingTx(otx)
+ outgoingTxs = append(outgoingTxs, ota)
+ btx, _ := otx.(*types.ContractCallTx)
+ k.iterateEthereumSignatures(ctx, btx.GetStoreIndex(), func(val sdk.ValAddress, sig []byte) bool {
+ siga, _ := types.PackConfirmation(&types.ContractCallTxConfirmation{btx.InvalidationScope, btx.InvalidationNonce, k.GetValidatorEthereumAddress(ctx, val).Hex(), sig})
+ ethereumTxConfirmations = append(ethereumTxConfirmations, siga)
+ return false
+ })
+ return false
+ })
+
+ return types.GenesisState{
+ Params: &p,
+ LastObservedEventNonce: lastobserved,
+ OutgoingTxs: outgoingTxs,
+ Confirmations: ethereumTxConfirmations,
+ EthereumEventVoteRecords: ethereumEventVoteRecords,
+ DelegateKeys: delegates,
+ Erc20ToDenoms: erc20ToDenoms,
+ UnbatchedSendToEthereumTxs: unbatchedTransfers,
+ }
+}
diff --git a/module/x/gravity/keeper/grpc_query.go b/module/x/gravity/keeper/grpc_query.go
new file mode 100644
index 0000000..5887ad8
--- /dev/null
+++ b/module/x/gravity/keeper/grpc_query.go
@@ -0,0 +1,461 @@
+package keeper
+
+import (
+ "context"
+
+ cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
+ "github.com/cosmos/cosmos-sdk/types/query"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+
+ "github.com/cosmos/cosmos-sdk/store/prefix"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+ "github.com/ethereum/go-ethereum/common"
+)
+
+var _ types.QueryServer = Keeper{}
+
+func (k Keeper) Params(c context.Context, req *types.ParamsRequest) (*types.ParamsResponse, error) {
+ params := k.GetParams(sdk.UnwrapSDKContext(c))
+ return &types.ParamsResponse{Params: params}, nil
+}
+
+func (k Keeper) LatestSignerSetTx(c context.Context, req *types.LatestSignerSetTxRequest) (*types.SignerSetTxResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+
+ store := prefix.NewStore(ctx.KVStore(k.storeKey), append([]byte{types.OutgoingTxKey}, types.SignerSetTxPrefixByte))
+ iter := store.ReverseIterator(nil, nil)
+ defer iter.Close()
+
+ if !iter.Valid() {
+ return nil, status.Errorf(codes.NotFound, "latest signer set not found")
+ }
+
+ var any cdctypes.Any
+ k.cdc.MustUnmarshal(iter.Value(), &any)
+
+ var otx types.OutgoingTx
+ if err := k.cdc.UnpackAny(&any, &otx); err != nil {
+ return nil, err
+ }
+ ss, ok := otx.(*types.SignerSetTx)
+ if !ok {
+ return nil, status.Errorf(codes.InvalidArgument, "couldn't cast to signer set for latest")
+ }
+ return &types.SignerSetTxResponse{SignerSet: ss}, nil
+}
+
+func (k Keeper) SignerSetTx(c context.Context, req *types.SignerSetTxRequest) (*types.SignerSetTxResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+
+ key := types.MakeSignerSetTxKey(req.SignerSetNonce)
+ otx := k.GetOutgoingTx(ctx, key)
+ if otx == nil {
+ return &types.SignerSetTxResponse{}, nil
+ }
+
+ ss, ok := otx.(*types.SignerSetTx)
+ if !ok {
+ return nil, status.Errorf(codes.InvalidArgument, "couldn't cast to signer set for %d", req.SignerSetNonce)
+ }
+
+ return &types.SignerSetTxResponse{SignerSet: ss}, nil
+}
+
+func (k Keeper) BatchTx(c context.Context, req *types.BatchTxRequest) (*types.BatchTxResponse, error) {
+ if !common.IsHexAddress(req.TokenContract) {
+ return nil, status.Errorf(codes.InvalidArgument, "invalid hex address %s", req.TokenContract)
+ }
+
+ res := &types.BatchTxResponse{}
+
+ key := types.MakeBatchTxKey(common.HexToAddress(req.TokenContract), req.BatchNonce)
+ otx := k.GetOutgoingTx(sdk.UnwrapSDKContext(c), key)
+ if otx == nil {
+ return nil, status.Errorf(codes.InvalidArgument, "no batch tx found for %d %s", req.BatchNonce, req.TokenContract)
+ }
+ batch, ok := otx.(*types.BatchTx)
+ if !ok {
+ return nil, status.Errorf(codes.InvalidArgument, "couldn't cast to batch tx for %d %s", req.BatchNonce, req.TokenContract)
+ }
+ res.Batch = batch
+
+ return res, nil
+}
+
+func (k Keeper) ContractCallTx(c context.Context, req *types.ContractCallTxRequest) (*types.ContractCallTxResponse, error) {
+ key := types.MakeContractCallTxKey(req.InvalidationScope, req.InvalidationNonce)
+ otx := k.GetOutgoingTx(sdk.UnwrapSDKContext(c), key)
+ if otx == nil {
+ return nil, status.Errorf(codes.InvalidArgument, "no contract call found for %d %s", req.InvalidationNonce, req.InvalidationScope)
+ }
+
+ cctx, ok := otx.(*types.ContractCallTx)
+ if !ok {
+ return nil, status.Errorf(codes.InvalidArgument, "couldn't cast to contract call for %d %s", req.InvalidationNonce, req.InvalidationScope)
+ }
+
+ return &types.ContractCallTxResponse{LogicCall: cctx}, nil
+}
+
+func (k Keeper) SignerSetTxs(c context.Context, req *types.SignerSetTxsRequest) (*types.SignerSetTxsResponse, error) {
+ var signers []*types.SignerSetTx
+ pageRes, err := k.PaginateOutgoingTxsByType(sdk.UnwrapSDKContext(c), req.Pagination, types.SignerSetTxPrefixByte, func(_ []byte, otx types.OutgoingTx) (hit bool) {
+ signer, ok := otx.(*types.SignerSetTx)
+ if !ok {
+ panic(sdkerrors.Wrapf(types.ErrInvalid, "couldn't cast to signer set for %s", otx))
+ }
+ signers = append(signers, signer)
+
+ return true
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return &types.SignerSetTxsResponse{SignerSets: signers, Pagination: pageRes}, nil
+}
+
+func (k Keeper) BatchTxs(c context.Context, req *types.BatchTxsRequest) (*types.BatchTxsResponse, error) {
+ var batches []*types.BatchTx
+ pageRes, err := k.PaginateOutgoingTxsByType(sdk.UnwrapSDKContext(c), req.Pagination, types.BatchTxPrefixByte, func(_ []byte, otx types.OutgoingTx) (hit bool) {
+ batch, ok := otx.(*types.BatchTx)
+ if !ok {
+ panic(sdkerrors.Wrapf(types.ErrInvalid, "couldn't cast to batch tx for %s", otx))
+ }
+ batches = append(batches, batch)
+ return true
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return &types.BatchTxsResponse{Batches: batches, Pagination: pageRes}, nil
+}
+
+func (k Keeper) ContractCallTxs(c context.Context, req *types.ContractCallTxsRequest) (*types.ContractCallTxsResponse, error) {
+ var calls []*types.ContractCallTx
+ pageRes, err := k.PaginateOutgoingTxsByType(sdk.UnwrapSDKContext(c), req.Pagination, types.ContractCallTxPrefixByte, func(_ []byte, otx types.OutgoingTx) (hit bool) {
+ call, ok := otx.(*types.ContractCallTx)
+ if !ok {
+ panic(sdkerrors.Wrapf(types.ErrInvalid, "couldn't cast to contract call for %s", otx))
+ }
+ calls = append(calls, call)
+ return true
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return &types.ContractCallTxsResponse{Calls: calls, Pagination: pageRes}, nil
+}
+
+func (k Keeper) SignerSetTxConfirmations(c context.Context, req *types.SignerSetTxConfirmationsRequest) (*types.SignerSetTxConfirmationsResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ key := types.MakeSignerSetTxKey(req.SignerSetNonce)
+
+ var out []*types.SignerSetTxConfirmation
+ k.iterateEthereumSignatures(ctx, key, func(val sdk.ValAddress, sig []byte) bool {
+ out = append(out, &types.SignerSetTxConfirmation{
+ SignerSetNonce: req.SignerSetNonce,
+ EthereumSigner: k.GetValidatorEthereumAddress(ctx, val).Hex(),
+ Signature: sig,
+ })
+ return false
+ })
+
+ return &types.SignerSetTxConfirmationsResponse{Signatures: out}, nil
+}
+
+func (k Keeper) BatchTxConfirmations(c context.Context, req *types.BatchTxConfirmationsRequest) (*types.BatchTxConfirmationsResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ key := types.MakeBatchTxKey(common.HexToAddress(req.TokenContract), req.BatchNonce)
+
+ var out []*types.BatchTxConfirmation
+ k.iterateEthereumSignatures(ctx, key, func(val sdk.ValAddress, sig []byte) bool {
+ out = append(out, &types.BatchTxConfirmation{
+ TokenContract: req.TokenContract,
+ BatchNonce: req.BatchNonce,
+ EthereumSigner: k.GetValidatorEthereumAddress(ctx, val).Hex(),
+ Signature: sig,
+ })
+ return false
+ })
+ return &types.BatchTxConfirmationsResponse{Signatures: out}, nil
+}
+
+func (k Keeper) ContractCallTxConfirmations(c context.Context, req *types.ContractCallTxConfirmationsRequest) (*types.ContractCallTxConfirmationsResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ key := types.MakeContractCallTxKey(req.InvalidationScope, req.InvalidationNonce)
+
+ var out []*types.ContractCallTxConfirmation
+ k.iterateEthereumSignatures(ctx, key, func(val sdk.ValAddress, sig []byte) bool {
+ out = append(out, &types.ContractCallTxConfirmation{
+ InvalidationScope: req.InvalidationScope,
+ InvalidationNonce: req.InvalidationNonce,
+ EthereumSigner: k.GetValidatorEthereumAddress(ctx, val).Hex(),
+ Signature: sig,
+ })
+ return false
+ })
+ return &types.ContractCallTxConfirmationsResponse{Signatures: out}, nil
+}
+
+func (k Keeper) UnsignedSignerSetTxs(c context.Context, req *types.UnsignedSignerSetTxsRequest) (*types.UnsignedSignerSetTxsResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ val, err := k.getSignerValidator(ctx, req.Address)
+ if err != nil {
+ return nil, err
+ }
+ var signerSets []*types.SignerSetTx
+ k.IterateOutgoingTxsByType(ctx, types.SignerSetTxPrefixByte, func(_ []byte, otx types.OutgoingTx) bool {
+ sig := k.getEthereumSignature(ctx, otx.GetStoreIndex(), val)
+ if len(sig) == 0 { // it's pending
+ signerSet, ok := otx.(*types.SignerSetTx)
+ if !ok {
+ panic(sdkerrors.Wrapf(types.ErrInvalid, "couldn't cast to signer set for %s", otx))
+ }
+ signerSets = append(signerSets, signerSet)
+ }
+ return false
+ })
+ return &types.UnsignedSignerSetTxsResponse{SignerSets: signerSets}, nil
+}
+
+func (k Keeper) UnsignedBatchTxs(c context.Context, req *types.UnsignedBatchTxsRequest) (*types.UnsignedBatchTxsResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ val, err := k.getSignerValidator(ctx, req.Address)
+ if err != nil {
+ return nil, err
+ }
+ var batches []*types.BatchTx
+ k.IterateOutgoingTxsByType(ctx, types.BatchTxPrefixByte, func(_ []byte, otx types.OutgoingTx) bool {
+ sig := k.getEthereumSignature(ctx, otx.GetStoreIndex(), val)
+ if len(sig) == 0 { // it's pending
+ batch, ok := otx.(*types.BatchTx)
+ if !ok {
+ panic(sdkerrors.Wrapf(types.ErrInvalid, "couldn't cast to batch tx for %s", otx))
+ }
+ batches = append(batches, batch)
+ }
+ return false
+ })
+ return &types.UnsignedBatchTxsResponse{Batches: batches}, nil
+}
+
+func (k Keeper) UnsignedContractCallTxs(c context.Context, req *types.UnsignedContractCallTxsRequest) (*types.UnsignedContractCallTxsResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ val, err := k.getSignerValidator(ctx, req.Address)
+ if err != nil {
+ return nil, err
+ }
+ var calls []*types.ContractCallTx
+ k.IterateOutgoingTxsByType(ctx, types.ContractCallTxPrefixByte, func(_ []byte, otx types.OutgoingTx) bool {
+ sig := k.getEthereumSignature(ctx, otx.GetStoreIndex(), val)
+ if len(sig) == 0 { // it's pending
+ call, ok := otx.(*types.ContractCallTx)
+ if !ok {
+ panic(sdkerrors.Wrapf(types.ErrInvalid, "couldn't cast to contract call for %s", otx))
+ }
+ calls = append(calls, call)
+ }
+ return false
+ })
+ return &types.UnsignedContractCallTxsResponse{Calls: calls}, nil
+}
+
+func (k Keeper) LastSubmittedEthereumEvent(c context.Context, req *types.LastSubmittedEthereumEventRequest) (*types.LastSubmittedEthereumEventResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ valAddr, err := k.getSignerValidator(ctx, req.Address)
+ if err != nil {
+ return nil, err
+ }
+
+ res := &types.LastSubmittedEthereumEventResponse{
+ EventNonce: k.getLastEventNonceByValidator(ctx, valAddr),
+ }
+ return res, nil
+}
+
+func (k Keeper) BatchTxFees(c context.Context, req *types.BatchTxFeesRequest) (*types.BatchTxFeesResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ res := &types.BatchTxFeesResponse{}
+
+ // TODO: is this what we want here?
+ // Should this calculation return a
+ // map[contract_address]fees or something similar?
+ k.IterateOutgoingTxsByType(ctx, types.BatchTxPrefixByte, func(key []byte, otx types.OutgoingTx) bool {
+ btx, _ := otx.(*types.BatchTx)
+ for _, tx := range btx.Transactions {
+ res.Fees = append(res.Fees, tx.Erc20Fee.GravityCoin())
+ }
+ return false
+ })
+
+ return res, nil
+}
+
+func (k Keeper) ERC20ToDenom(c context.Context, req *types.ERC20ToDenomRequest) (*types.ERC20ToDenomResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ cosmosOriginated, denom := k.ERC20ToDenomLookup(ctx, req.Erc20)
+ res := &types.ERC20ToDenomResponse{
+ Denom: denom,
+ CosmosOriginated: cosmosOriginated,
+ }
+ return res, nil
+}
+
+func (k Keeper) DenomToERC20Params(c context.Context, req *types.DenomToERC20ParamsRequest) (*types.DenomToERC20ParamsResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ if existingERC20, exists := k.getCosmosOriginatedERC20(ctx, req.Denom); exists {
+ return nil, sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "ERC20 token %s already exists for denom %s", existingERC20.Hex(), req.Denom,
+ )
+ }
+
+ // use metadata, if we can find it
+ if md, ok := k.bankKeeper.GetDenomMetaData(ctx, req.Denom); ok && md.Base != "" {
+ var erc20Decimals uint64
+ for _, denomUnit := range md.DenomUnits {
+ if denomUnit.Denom == md.Display {
+ erc20Decimals = uint64(denomUnit.Exponent)
+ break
+ }
+ }
+
+ return &types.DenomToERC20ParamsResponse{
+ BaseDenom: md.Base,
+ Erc20Name: md.Display,
+ Erc20Symbol: md.Display,
+ Erc20Decimals: erc20Decimals,
+ }, nil
+ }
+
+ if supply := k.bankKeeper.GetSupply(ctx, req.Denom); supply.IsZero() {
+ return nil, sdkerrors.Wrapf(
+ types.ErrInvalidERC20Event,
+ "no supply exists for token %s without metadata", req.Denom,
+ )
+ }
+
+ // no metadata, go with a zero decimal, no symbol erc-20
+ res := &types.DenomToERC20ParamsResponse{
+ BaseDenom: req.Denom,
+ Erc20Name: req.Denom,
+ Erc20Symbol: "",
+ Erc20Decimals: 0,
+ }
+
+ return res, nil
+}
+
+func (k Keeper) DenomToERC20(c context.Context, req *types.DenomToERC20Request) (*types.DenomToERC20Response, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ cosmosOriginated, erc20, err := k.DenomToERC20Lookup(ctx, req.Denom)
+ if err != nil {
+ return nil, err
+ }
+ res := &types.DenomToERC20Response{
+ Erc20: erc20.Hex(),
+ CosmosOriginated: cosmosOriginated,
+ }
+ return res, nil
+}
+
+func (k Keeper) BatchedSendToEthereums(c context.Context, req *types.BatchedSendToEthereumsRequest) (*types.BatchedSendToEthereumsResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ res := &types.BatchedSendToEthereumsResponse{}
+
+ k.IterateOutgoingTxsByType(ctx, types.BatchTxPrefixByte, func(_ []byte, outgoing types.OutgoingTx) bool {
+ batchTx := outgoing.(*types.BatchTx)
+ for _, ste := range batchTx.Transactions {
+ if ste.Sender == req.SenderAddress {
+ res.SendToEthereums = append(res.SendToEthereums, ste)
+ }
+ }
+
+ return false
+ })
+
+ return res, nil
+}
+
+func (k Keeper) UnbatchedSendToEthereums(c context.Context, req *types.UnbatchedSendToEthereumsRequest) (*types.UnbatchedSendToEthereumsResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ res := &types.UnbatchedSendToEthereumsResponse{}
+
+ prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{types.SendToEthereumKey})
+ pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) {
+ var ste types.SendToEthereum
+ k.cdc.MustUnmarshal(value, &ste)
+ if ste.Sender == req.SenderAddress {
+ res.SendToEthereums = append(res.SendToEthereums, &ste)
+ return true, nil
+ }
+ return false, nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ res.Pagination = pageRes
+
+ return res, nil
+}
+
+func (k Keeper) DelegateKeysByValidator(c context.Context, req *types.DelegateKeysByValidatorRequest) (*types.DelegateKeysByValidatorResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddress)
+ if err != nil {
+ return nil, err
+ }
+ ethAddr := k.GetValidatorEthereumAddress(ctx, valAddr)
+ orchAddr := k.GetEthereumOrchestratorAddress(ctx, ethAddr)
+ res := &types.DelegateKeysByValidatorResponse{
+ EthAddress: ethAddr.Hex(),
+ OrchestratorAddress: orchAddr.String(),
+ }
+ return res, nil
+}
+
+func (k Keeper) DelegateKeysByEthereumSigner(c context.Context, req *types.DelegateKeysByEthereumSignerRequest) (*types.DelegateKeysByEthereumSignerResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ if !common.IsHexAddress(req.EthereumSigner) {
+ return nil, nil // TODO(levi) make and return an error
+ }
+ ethAddr := common.HexToAddress(req.EthereumSigner)
+ orchAddr := k.GetEthereumOrchestratorAddress(ctx, ethAddr)
+ valAddr := k.GetOrchestratorValidatorAddress(ctx, orchAddr)
+ res := &types.DelegateKeysByEthereumSignerResponse{
+ ValidatorAddress: valAddr.String(),
+ OrchestratorAddress: orchAddr.String(),
+ }
+ return res, nil
+}
+
+func (k Keeper) DelegateKeysByOrchestrator(c context.Context, req *types.DelegateKeysByOrchestratorRequest) (*types.DelegateKeysByOrchestratorResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ orchAddr, err := sdk.AccAddressFromBech32(req.OrchestratorAddress)
+ if err != nil {
+ return nil, err
+ }
+ valAddr := k.GetOrchestratorValidatorAddress(ctx, orchAddr)
+ ethAddr := k.GetValidatorEthereumAddress(ctx, valAddr)
+ res := &types.DelegateKeysByOrchestratorResponse{
+ ValidatorAddress: valAddr.String(),
+ EthereumSigner: ethAddr.Hex(),
+ }
+ return res, nil
+}
+
+func (k Keeper) DelegateKeys(c context.Context, req *types.DelegateKeysRequest) (*types.DelegateKeysResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ delegateKeys := k.getDelegateKeys(ctx)
+
+ res := &types.DelegateKeysResponse{
+ DelegateKeys: delegateKeys,
+ }
+ return res, nil
+}
diff --git a/module/x/gravity/keeper/grpc_query_test.go b/module/x/gravity/keeper/grpc_query_test.go
new file mode 100644
index 0000000..7f34de7
--- /dev/null
+++ b/module/x/gravity/keeper/grpc_query_test.go
@@ -0,0 +1,236 @@
+package keeper
+
+import (
+ "testing"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+ "github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/libs/bytes"
+)
+
+func TestKeeper_Params(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := sdk.WrapSDKContext(env.Context)
+ gk := env.GravityKeeper
+
+ req := &types.ParamsRequest{}
+ res, err := gk.Params(ctx, req)
+ require.NoError(t, err)
+ require.NotNil(t, res)
+}
+
+func TestKeeper_LatestSignerSetTx(t *testing.T) {
+ t.Run("read before there's anything in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ req := &types.LatestSignerSetTxRequest{}
+ res, err := gk.LatestSignerSetTx(sdk.WrapSDKContext(ctx), req)
+ require.Error(t, err)
+ require.Nil(t, res)
+ })
+ t.Run("read after there's something in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+ { // setup
+ sstx := gk.CreateSignerSetTx(env.Context)
+ require.NotNil(t, sstx)
+ }
+ { // validate
+ req := &types.LatestSignerSetTxRequest{}
+ res, err := gk.LatestSignerSetTx(sdk.WrapSDKContext(ctx), req)
+ require.NoError(t, err)
+ require.NotNil(t, res)
+ }
+ })
+}
+
+func TestKeeper_SignerSetTx(t *testing.T) {
+ t.Run("read after there's something in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ var signerSetNonce uint64
+ { // setup
+ sstx := gk.CreateSignerSetTx(env.Context)
+ require.NotNil(t, sstx)
+ signerSetNonce = sstx.Nonce
+ }
+ { // validate
+ req := &types.SignerSetTxRequest{SignerSetNonce: signerSetNonce}
+ res, err := gk.SignerSetTx(sdk.WrapSDKContext(ctx), req)
+ require.NoError(t, err)
+ require.NotNil(t, res)
+ require.NotNil(t, res.SignerSet)
+ }
+ })
+}
+
+func TestKeeper_BatchTx(t *testing.T) {
+ t.Run("read after there's something in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ const (
+ batchNonce = 55
+ tokenContract = "0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4"
+ )
+
+ { // setup
+ gk.SetOutgoingTx(ctx, &types.BatchTx{
+ BatchNonce: batchNonce,
+ Timeout: 1000,
+ Transactions: nil,
+ TokenContract: tokenContract,
+ Height: 100,
+ })
+ }
+ { // validate
+ req := &types.BatchTxRequest{
+ BatchNonce: batchNonce,
+ TokenContract: tokenContract,
+ }
+
+ res, err := gk.BatchTx(sdk.WrapSDKContext(ctx), req)
+ require.NoError(t, err)
+ require.NotNil(t, res)
+ require.NotNil(t, res.Batch)
+ }
+ })
+}
+
+func TestKeeper_ContractCallTx(t *testing.T) {
+ t.Run("read after there's something in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ const (
+ invalidationNonce = 100
+ invalidationScope = "an-invalidation-scope"
+ )
+
+ { // setup
+ gk.SetOutgoingTx(ctx, &types.ContractCallTx{
+ InvalidationNonce: invalidationNonce,
+ InvalidationScope: bytes.HexBytes(invalidationScope),
+ })
+ }
+ { // validate
+ req := &types.ContractCallTxRequest{
+ InvalidationNonce: invalidationNonce,
+ InvalidationScope: bytes.HexBytes(invalidationScope),
+ }
+
+ res, err := gk.ContractCallTx(sdk.WrapSDKContext(ctx), req)
+ require.NoError(t, err)
+ require.NotNil(t, res)
+ require.NotNil(t, res.LogicCall)
+ }
+ })
+}
+
+func TestKeeper_SignerSetTxs(t *testing.T) {
+ t.Run("read after there's something in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ { // setup
+ require.NotNil(t, gk.CreateSignerSetTx(env.Context))
+ require.NotNil(t, gk.CreateSignerSetTx(env.Context))
+ }
+ { // validate
+ req := &types.SignerSetTxsRequest{}
+ res, err := gk.SignerSetTxs(sdk.WrapSDKContext(ctx), req)
+ require.NoError(t, err)
+ require.NotNil(t, res)
+ require.Len(t, res.SignerSets, 2)
+ }
+ })
+}
+
+func TestKeeper_BatchTxs(t *testing.T) {
+ t.Run("read after there's something in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ { // setup
+ gk.SetOutgoingTx(ctx, &types.BatchTx{
+ BatchNonce: 1000,
+ Timeout: 1000,
+ Transactions: nil,
+ TokenContract: "0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4",
+ Height: 1000,
+ })
+ gk.SetOutgoingTx(ctx, &types.BatchTx{
+ BatchNonce: 1001,
+ Timeout: 1000,
+ Transactions: nil,
+ TokenContract: "0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4",
+ Height: 1001,
+ })
+ }
+ { // validate
+ req := &types.BatchTxsRequest{}
+ got, err := gk.BatchTxs(sdk.WrapSDKContext(ctx), req)
+ require.NoError(t, err)
+ require.NotNil(t, got)
+ require.Len(t, got.Batches, 2)
+ }
+ })
+}
+
+func TestKeeper_ContractCallTxs(t *testing.T) {
+ t.Run("read after there's something in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ { // setup
+ gk.SetOutgoingTx(ctx, &types.ContractCallTx{
+ InvalidationNonce: 5,
+ InvalidationScope: []byte("an-invalidation-scope"),
+ // TODO
+ })
+ gk.SetOutgoingTx(ctx, &types.ContractCallTx{
+ InvalidationNonce: 6,
+ InvalidationScope: []byte("an-invalidation-scope"),
+ })
+ }
+ { // validate
+ req := &types.ContractCallTxsRequest{}
+ got, err := gk.ContractCallTxs(sdk.WrapSDKContext(ctx), req)
+ require.NoError(t, err)
+ require.NotNil(t, got)
+ require.Len(t, got.Calls, 2)
+ }
+ })
+}
+
+// TODO(levi) ensure coverage for:
+// ContractCallTx(context.Context, *ContractCallTxRequest) (*ContractCallTxResponse, error)
+// ContractCallTxs(context.Context, *ContractCallTxsRequest) (*ContractCallTxsResponse, error)
+
+// SignerSetTxConfirmations(context.Context, *SignerSetTxConfirmationsRequest) (*SignerSetTxConfirmationsResponse, error)
+// BatchTxConfirmations(context.Context, *BatchTxConfirmationsRequest) (*BatchTxConfirmationsResponse, error)
+// ContractCallTxConfirmations(context.Context, *ContractCallTxConfirmationsRequest) (*ContractCallTxConfirmationsResponse, error)
+
+// UnsignedSignerSetTxs(context.Context, *UnsignedSignerSetTxsRequest) (*UnsignedSignerSetTxsResponse, error)
+// UnsignedBatchTxs(context.Context, *UnsignedBatchTxsRequest) (*UnsignedBatchTxsResponse, error)
+// UnsignedContractCallTxs(context.Context, *UnsignedContractCallTxsRequest) (*UnsignedContractCallTxsResponse, error)
+
+// BatchTxFees(context.Context, *BatchTxFeesRequest) (*BatchTxFeesResponse, error)
+// ERC20ToDenom(context.Context, *ERC20ToDenomRequest) (*ERC20ToDenomResponse, error)
+// DenomToERC20(context.Context, *DenomToERC20Request) (*DenomToERC20Response, error)
+// BatchedSendToEthereums(context.Context, *BatchedSendToEthereumsRequest) (*BatchedSendToEthereumsResponse, error)
+// UnbatchedSendToEthereums(context.Context, *UnbatchedSendToEthereumsRequest) (*UnbatchedSendToEthereumsResponse, error)
+// DelegateKeysByValidator(context.Context, *DelegateKeysByValidatorRequest) (*DelegateKeysByValidatorResponse, error)
+// DelegateKeysByEthereumSigner(context.Context, *DelegateKeysByEthereumSignerRequest) (*DelegateKeysByEthereumSignerResponse, error)
+// DelegateKeysByOrchestrator(context.Context, *DelegateKeysByOrchestratorRequest) (*DelegateKeysByOrchestratorResponse, error)
diff --git a/module/x/gravity/keeper/hooks.go b/module/x/gravity/keeper/hooks.go
new file mode 100644
index 0000000..c812a36
--- /dev/null
+++ b/module/x/gravity/keeper/hooks.go
@@ -0,0 +1,82 @@
+package keeper
+
+import (
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+type Hooks struct {
+ k Keeper
+}
+
+var _ stakingtypes.StakingHooks = Hooks{}
+
+// Hooks Create new gravity hooks
+func (k Keeper) Hooks() Hooks { return Hooks{k} }
+
+func (h Hooks) AfterValidatorBeginUnbonding(ctx sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) {
+
+ // When Validator starts Unbonding, Persist the block height in the store
+ // Later in endblocker, check if there is at least one validator who started unbonding and create a valset request.
+ // The reason for creating valset requests in endblock is to create only one valset request per block,
+ // if multiple validators starts unbonding at same block.
+
+ h.k.setLastUnbondingBlockHeight(ctx, uint64(ctx.BlockHeight()))
+
+}
+
+func (h Hooks) BeforeDelegationCreated(_ sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
+}
+func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {}
+func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) {}
+func (h Hooks) AfterValidatorBonded(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) {}
+func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}
+func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {}
+func (h Hooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) {}
+func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
+}
+func (h Hooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
+}
+
+var _ types.GravityHooks = Keeper{}
+
+func (k Keeper) AfterContractCallExecutedEvent(ctx sdk.Context, event types.ContractCallExecutedEvent) {
+ if k.hooks != nil {
+ k.hooks.AfterContractCallExecutedEvent(ctx, event)
+ }
+}
+
+func (k Keeper) AfterERC20DeployedEvent(ctx sdk.Context, event types.ERC20DeployedEvent) {
+ if k.hooks != nil {
+ k.hooks.AfterERC20DeployedEvent(ctx, event)
+ }
+}
+
+func (k Keeper) AfterSignerSetExecutedEvent(ctx sdk.Context, event types.SignerSetTxExecutedEvent) {
+ if k.hooks != nil {
+ k.hooks.AfterSignerSetExecutedEvent(ctx, event)
+ }
+}
+
+func (k Keeper) AfterBatchExecutedEvent(ctx sdk.Context, event types.BatchExecutedEvent) {
+ if k.hooks != nil {
+ k.hooks.AfterBatchExecutedEvent(ctx, event)
+ }
+}
+
+func (k Keeper) AfterSendToCosmosEvent(ctx sdk.Context, event types.SendToCosmosEvent) {
+ if k.hooks != nil {
+ k.hooks.AfterSendToCosmosEvent(ctx, event)
+ }
+}
+
+func (k *Keeper) SetHooks(sh types.GravityHooks) *Keeper {
+ if k.hooks != nil {
+ panic("cannot set gravity hooks twice")
+ }
+
+ k.hooks = sh
+
+ return k
+}
diff --git a/module/x/gravity/keeper/keeper.go b/module/x/gravity/keeper/keeper.go
new file mode 100644
index 0000000..f5341b6
--- /dev/null
+++ b/module/x/gravity/keeper/keeper.go
@@ -0,0 +1,565 @@
+package keeper
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "math"
+ "sort"
+ "strconv"
+ "strings"
+
+ "github.com/cosmos/cosmos-sdk/codec"
+ cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
+ "github.com/cosmos/cosmos-sdk/store/prefix"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/cosmos/cosmos-sdk/types/query"
+ paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+ "github.com/ethereum/go-ethereum/common"
+ tmbytes "github.com/tendermint/tendermint/libs/bytes"
+ "github.com/tendermint/tendermint/libs/log"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+// Keeper maintains the link to storage and exposes getter/setter methods for the various parts of the state machine
+type Keeper struct {
+ StakingKeeper types.StakingKeeper
+ EthereumEventProcessor interface {
+ Handle(sdk.Context, types.EthereumEvent) error
+ }
+
+ storeKey sdk.StoreKey
+ paramSpace paramtypes.Subspace
+ cdc codec.Codec
+ accountKeeper types.AccountKeeper
+ bankKeeper types.BankKeeper
+ SlashingKeeper types.SlashingKeeper
+ PowerReduction sdk.Int
+ hooks types.GravityHooks
+}
+
+// NewKeeper returns a new instance of the gravity keeper
+func NewKeeper(
+ cdc codec.Codec,
+ storeKey sdk.StoreKey,
+ paramSpace paramtypes.Subspace,
+ accKeeper types.AccountKeeper,
+ stakingKeeper types.StakingKeeper,
+ bankKeeper types.BankKeeper,
+ slashingKeeper types.SlashingKeeper,
+ powerReduction sdk.Int,
+) Keeper {
+ // set KeyTable if it has not already been set
+ if !paramSpace.HasKeyTable() {
+ paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
+ }
+
+ k := Keeper{
+ cdc: cdc,
+ paramSpace: paramSpace,
+ storeKey: storeKey,
+ accountKeeper: accKeeper,
+ StakingKeeper: stakingKeeper,
+ bankKeeper: bankKeeper,
+ SlashingKeeper: slashingKeeper,
+ PowerReduction: powerReduction,
+ }
+ k.EthereumEventProcessor = EthereumEventProcessor{
+ keeper: k,
+ bankKeeper: bankKeeper,
+ }
+
+ return k
+}
+
+func (k Keeper) Logger(ctx sdk.Context) log.Logger {
+ return ctx.Logger().With("module", "x/"+types.ModuleName)
+}
+
+/////////////////////////////
+// SignerSetTxNonce //
+/////////////////////////////
+
+// incrementLatestSignerSetTxNonce sets the latest valset nonce
+func (k Keeper) incrementLatestSignerSetTxNonce(ctx sdk.Context) uint64 {
+ current := k.GetLatestSignerSetTxNonce(ctx)
+ next := current + 1
+ ctx.KVStore(k.storeKey).Set([]byte{types.LatestSignerSetTxNonceKey}, sdk.Uint64ToBigEndian(next))
+ return next
+}
+
+// GetLatestSignerSetTxNonce returns the latest valset nonce
+func (k Keeper) GetLatestSignerSetTxNonce(ctx sdk.Context) uint64 {
+ if bz := ctx.KVStore(k.storeKey).Get([]byte{types.LatestSignerSetTxNonceKey}); bz != nil {
+ return binary.BigEndian.Uint64(bz)
+ }
+ return 0
+}
+
+// GetLatestSignerSetTx returns the latest validator set in state
+func (k Keeper) GetLatestSignerSetTx(ctx sdk.Context) *types.SignerSetTx {
+ key := types.MakeSignerSetTxKey(k.GetLatestSignerSetTxNonce(ctx))
+ otx := k.GetOutgoingTx(ctx, key)
+ out, _ := otx.(*types.SignerSetTx)
+ return out
+}
+
+//////////////////////////////
+// LastUnbondingBlockHeight //
+//////////////////////////////
+
+// setLastUnbondingBlockHeight sets the last unbonding block height
+func (k Keeper) setLastUnbondingBlockHeight(ctx sdk.Context, unbondingBlockHeight uint64) {
+ ctx.KVStore(k.storeKey).Set([]byte{types.LastUnBondingBlockHeightKey}, sdk.Uint64ToBigEndian(unbondingBlockHeight))
+}
+
+// GetLastUnbondingBlockHeight returns the last unbonding block height
+func (k Keeper) GetLastUnbondingBlockHeight(ctx sdk.Context) uint64 {
+ if bz := ctx.KVStore(k.storeKey).Get([]byte{types.LastUnBondingBlockHeightKey}); len(bz) == 0 {
+ return 0
+ } else {
+ return binary.BigEndian.Uint64(bz)
+ }
+}
+
+///////////////////////////////
+// ETHEREUM SIGNATURES //
+///////////////////////////////
+
+// getEthereumSignature returns a valset confirmation by a nonce and validator address
+func (k Keeper) getEthereumSignature(ctx sdk.Context, storeIndex []byte, validator sdk.ValAddress) []byte {
+ return ctx.KVStore(k.storeKey).Get(types.MakeEthereumSignatureKey(storeIndex, validator))
+}
+
+// SetEthereumSignature sets a valset confirmation
+func (k Keeper) SetEthereumSignature(ctx sdk.Context, sig types.EthereumTxConfirmation, val sdk.ValAddress) []byte {
+ key := types.MakeEthereumSignatureKey(sig.GetStoreIndex(), val)
+ ctx.KVStore(k.storeKey).Set(key, sig.GetSignature())
+ return key
+}
+
+// GetEthereumSignatures returns all etherum signatures for a given outgoing tx by store index
+func (k Keeper) GetEthereumSignatures(ctx sdk.Context, storeIndex []byte) map[string][]byte {
+ var signatures = make(map[string][]byte)
+ k.iterateEthereumSignatures(ctx, storeIndex, func(val sdk.ValAddress, h []byte) bool {
+ signatures[val.String()] = h
+ return false
+ })
+ return signatures
+}
+
+// iterateEthereumSignatures iterates through all valset confirms by nonce in ASC order
+func (k Keeper) iterateEthereumSignatures(ctx sdk.Context, storeIndex []byte, cb func(sdk.ValAddress, []byte) bool) {
+ prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), append([]byte{types.EthereumSignatureKey}, storeIndex...))
+ iter := prefixStore.Iterator(nil, nil)
+ defer iter.Close()
+
+ for ; iter.Valid(); iter.Next() {
+ // cb returns true to stop early
+ if cb(iter.Key(), iter.Value()) {
+ break
+ }
+ }
+}
+
+/////////////////////////
+// ORC -> VAL ADDRESS //
+/////////////////////////
+
+// SetOrchestratorValidatorAddress sets the Orchestrator key for a given validator.
+func (k Keeper) SetOrchestratorValidatorAddress(ctx sdk.Context, val sdk.ValAddress, orchAddr sdk.AccAddress) {
+ store := ctx.KVStore(k.storeKey)
+ key := types.MakeOrchestratorValidatorAddressKey(orchAddr)
+
+ store.Set(key, val.Bytes())
+}
+
+// GetOrchestratorValidatorAddress returns the validator key associated with an
+// orchestrator key.
+func (k Keeper) GetOrchestratorValidatorAddress(ctx sdk.Context, orchAddr sdk.AccAddress) sdk.ValAddress {
+ store := ctx.KVStore(k.storeKey)
+ key := types.MakeOrchestratorValidatorAddressKey(orchAddr)
+
+ return store.Get(key)
+}
+
+////////////////////////
+// VAL -> ETH ADDRESS //
+////////////////////////
+
+// setValidatorEthereumAddress sets the ethereum address for a given validator
+func (k Keeper) setValidatorEthereumAddress(ctx sdk.Context, valAddr sdk.ValAddress, ethAddr common.Address) {
+ store := ctx.KVStore(k.storeKey)
+ key := types.MakeValidatorEthereumAddressKey(valAddr)
+
+ store.Set(key, ethAddr.Bytes())
+}
+
+// GetValidatorEthereumAddress returns the eth address for a given gravity validator.
+func (k Keeper) GetValidatorEthereumAddress(ctx sdk.Context, valAddr sdk.ValAddress) common.Address {
+ store := ctx.KVStore(k.storeKey)
+ key := types.MakeValidatorEthereumAddressKey(valAddr)
+
+ return common.BytesToAddress(store.Get(key))
+}
+
+func (k Keeper) getValidatorsByEthereumAddress(ctx sdk.Context, ethAddr common.Address) (vals []sdk.ValAddress) {
+ iter := ctx.KVStore(k.storeKey).Iterator(nil, nil)
+
+ for ; iter.Valid(); iter.Next() {
+ if common.BytesToAddress(iter.Value()) == ethAddr {
+ valBs := bytes.TrimPrefix(iter.Key(), []byte{types.ValidatorEthereumAddressKey})
+ val := sdk.ValAddress(valBs)
+ vals = append(vals, val)
+ }
+ }
+
+ return
+}
+
+////////////////////////
+// ETH -> ORC ADDRESS //
+////////////////////////
+
+// setEthereumOrchestratorAddress sets the eth orch addr mapping
+func (k Keeper) setEthereumOrchestratorAddress(ctx sdk.Context, ethAddr common.Address, orch sdk.AccAddress) {
+ store := ctx.KVStore(k.storeKey)
+ key := types.MakeEthereumOrchestratorAddressKey(ethAddr)
+
+ store.Set(key, orch.Bytes())
+}
+
+// GetEthereumOrchestratorAddress gets the orch address for a given eth address
+func (k Keeper) GetEthereumOrchestratorAddress(ctx sdk.Context, ethAddr common.Address) sdk.AccAddress {
+ store := ctx.KVStore(k.storeKey)
+ key := types.MakeEthereumOrchestratorAddressKey(ethAddr)
+
+ return store.Get(key)
+}
+
+func (k Keeper) getEthereumAddressesByOrchestrator(ctx sdk.Context, orch sdk.AccAddress) (ethAddrs []common.Address) {
+ iter := ctx.KVStore(k.storeKey).Iterator(nil, nil)
+
+ for ; iter.Valid(); iter.Next() {
+ if sdk.AccAddress(iter.Value()).String() == orch.String() {
+ ethBs := bytes.TrimPrefix(iter.Key(), []byte{types.EthereumOrchestratorAddressKey})
+ ethAddr := common.BytesToAddress(ethBs)
+ ethAddrs = append(ethAddrs, ethAddr)
+ }
+ }
+
+ return
+}
+
+// CreateSignerSetTx gets the current signer set from the staking keeper, increments the nonce,
+// creates the signer set tx object, emits an event and sets the signer set in state
+func (k Keeper) CreateSignerSetTx(ctx sdk.Context) *types.SignerSetTx {
+ nonce := k.incrementLatestSignerSetTxNonce(ctx)
+ currSignerSet := k.CurrentSignerSet(ctx)
+ newSignerSetTx := types.NewSignerSetTx(nonce, uint64(ctx.BlockHeight()), currSignerSet)
+
+ ctx.EventManager().EmitEvent(
+ sdk.NewEvent(
+ types.EventTypeMultisigUpdateRequest,
+ sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
+ sdk.NewAttribute(types.AttributeKeyContract, k.getBridgeContractAddress(ctx)),
+ sdk.NewAttribute(types.AttributeKeyBridgeChainID, strconv.Itoa(int(k.getBridgeChainID(ctx)))),
+ sdk.NewAttribute(types.AttributeKeySignerSetNonce, fmt.Sprint(nonce)),
+ ),
+ )
+ k.SetOutgoingTx(ctx, newSignerSetTx)
+ k.Logger(ctx).Info(
+ "SignerSetTx created",
+ "nonce", newSignerSetTx.Nonce,
+ "height", newSignerSetTx.Height,
+ "signers", len(newSignerSetTx.Signers),
+ )
+ return newSignerSetTx
+}
+
+// CurrentSignerSet gets powers from the store and normalizes them
+// into an integer percentage with a resolution of uint32 Max meaning
+// a given validators 'gravity power' is computed as
+// Cosmos power / total cosmos power = x / uint32 Max
+// where x is the voting power on the gravity contract. This allows us
+// to only use integer division which produces a known rounding error
+// from truncation equal to the ratio of the validators
+// Cosmos power / total cosmos power ratio, leaving us at uint32 Max - 1
+// total voting power. This is an acceptable rounding error since floating
+// point may cause consensus problems if different floating point unit
+// implementations are involved.
+func (k Keeper) CurrentSignerSet(ctx sdk.Context) types.EthereumSigners {
+ validators := k.StakingKeeper.GetBondedValidatorsByPower(ctx)
+ ethereumSigners := make([]*types.EthereumSigner, 0)
+ var totalPower uint64
+ for _, validator := range validators {
+ val := validator.GetOperator()
+
+ p := uint64(k.StakingKeeper.GetLastValidatorPower(ctx, val))
+
+ if ethAddr := k.GetValidatorEthereumAddress(ctx, val); ethAddr.Hex() != "0x0000000000000000000000000000000000000000" {
+ es := &types.EthereumSigner{Power: p, EthereumAddress: ethAddr.Hex()}
+ ethereumSigners = append(ethereumSigners, es)
+ totalPower += p
+ }
+ }
+ // normalize power values
+ for i := range ethereumSigners {
+ ethereumSigners[i].Power = sdk.NewUint(ethereumSigners[i].Power).MulUint64(math.MaxUint32).QuoUint64(totalPower).Uint64()
+ }
+
+ return ethereumSigners
+}
+
+// GetSignerSetTxs returns all the signer set txs from the store
+func (k Keeper) GetSignerSetTxs(ctx sdk.Context) (out []*types.SignerSetTx) {
+ k.IterateOutgoingTxsByType(ctx, types.SignerSetTxPrefixByte, func(_ []byte, otx types.OutgoingTx) bool {
+ sstx, _ := otx.(*types.SignerSetTx)
+ out = append(out, sstx)
+ return false
+ })
+ return
+}
+
+/////////////////////////////
+// PARAMETERS //
+/////////////////////////////
+
+// GetParams returns the parameters from the store
+func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
+ k.paramSpace.GetParamSet(ctx, ¶ms)
+ return
+}
+
+// setParams sets the parameters in the store
+func (k Keeper) setParams(ctx sdk.Context, ps types.Params) {
+ k.paramSpace.SetParamSet(ctx, &ps)
+}
+
+// getBridgeContractAddress returns the bridge contract address on ETH
+func (k Keeper) getBridgeContractAddress(ctx sdk.Context) string {
+ var a string
+ k.paramSpace.Get(ctx, types.ParamsStoreKeyBridgeContractAddress, &a)
+ return a
+}
+
+// getBridgeChainID returns the chain id of the ETH chain we are running against
+func (k Keeper) getBridgeChainID(ctx sdk.Context) uint64 {
+ var a uint64
+ k.paramSpace.Get(ctx, types.ParamsStoreKeyBridgeContractChainID, &a)
+ return a
+}
+
+// getGravityID returns the GravityID the GravityID is essentially a salt value
+// for bridge signatures, provided each chain running Gravity has a unique ID
+// it won't be possible to play back signatures from one bridge onto another
+// even if they share a validator set.
+//
+// The lifecycle of the GravityID is that it is set in the Genesis file
+// read from the live chain for the contract deployment, once a Gravity contract
+// is deployed the GravityID CAN NOT BE CHANGED. Meaning that it can't just be the
+// same as the chain id since the chain id may be changed many times with each
+// successive chain in charge of the same bridge
+func (k Keeper) getGravityID(ctx sdk.Context) string {
+ var a string
+ k.paramSpace.Get(ctx, types.ParamsStoreKeyGravityID, &a)
+ return a
+}
+
+// getDelegateKeys iterates both the EthAddress and Orchestrator address indexes to produce
+// a vector of MsgDelegateKeys entries containing all the delgate keys for state
+// export / import. This may seem at first glance to be excessively complicated, why not combine
+// the EthAddress and Orchestrator address indexes and simply iterate one thing? The answer is that
+// even though we set the Eth and Orchestrator address in the same place we use them differently we
+// always go from Orchestrator address to Validator address and from validator address to Ethereum address
+// we want to keep looking up the validator address for various reasons, so a direct Orchestrator to Ethereum
+// address mapping will mean having to keep two of the same data around just to provide lookups.
+//
+// For the time being this will serve
+func (k Keeper) getDelegateKeys(ctx sdk.Context) (out []*types.MsgDelegateKeys) {
+ store := ctx.KVStore(k.storeKey)
+ iter := prefix.NewStore(store, []byte{types.ValidatorEthereumAddressKey}).Iterator(nil, nil)
+ for ; iter.Valid(); iter.Next() {
+ out = append(out, &types.MsgDelegateKeys{
+ ValidatorAddress: sdk.ValAddress(iter.Key()).String(),
+ EthereumAddress: common.BytesToAddress(iter.Value()).Hex(),
+ })
+ }
+ iter.Close()
+
+ for _, msg := range out {
+ msg.OrchestratorAddress = k.GetEthereumOrchestratorAddress(ctx, common.HexToAddress(msg.EthereumAddress)).String()
+ }
+
+ // we iterated over a map, so now we have to sort to ensure the
+ // output here is deterministic, eth address chosen for no particular
+ // reason
+ sort.Slice(out[:], func(i, j int) bool {
+ return out[i].EthereumAddress < out[j].EthereumAddress
+ })
+
+ return out
+}
+
+// GetUnbondingvalidators returns UnbondingValidators.
+// Adding here in gravity keeper as cdc is available inside endblocker.
+func (k Keeper) GetUnbondingvalidators(unbondingVals []byte) stakingtypes.ValAddresses {
+ unbondingValidators := stakingtypes.ValAddresses{}
+ k.cdc.MustUnmarshal(unbondingVals, &unbondingValidators)
+ return unbondingValidators
+}
+
+/////////////////
+// OUTGOING TX //
+/////////////////
+
+// GetOutgoingTx todo: outgoingTx prefix byte
+func (k Keeper) GetOutgoingTx(ctx sdk.Context, storeIndex []byte) (out types.OutgoingTx) {
+ if err := k.cdc.UnmarshalInterface(ctx.KVStore(k.storeKey).Get(types.MakeOutgoingTxKey(storeIndex)), &out); err != nil {
+ panic(err)
+ }
+ return out
+}
+
+func (k Keeper) SetOutgoingTx(ctx sdk.Context, outgoing types.OutgoingTx) {
+ any, err := types.PackOutgoingTx(outgoing)
+ if err != nil {
+ panic(err)
+ }
+ ctx.KVStore(k.storeKey).Set(
+ types.MakeOutgoingTxKey(outgoing.GetStoreIndex()),
+ k.cdc.MustMarshal(any),
+ )
+}
+
+// DeleteOutgoingTx deletes a given outgoingtx
+func (k Keeper) DeleteOutgoingTx(ctx sdk.Context, storeIndex []byte) {
+ ctx.KVStore(k.storeKey).Delete(types.MakeOutgoingTxKey(storeIndex))
+}
+
+func (k Keeper) PaginateOutgoingTxsByType(ctx sdk.Context, pageReq *query.PageRequest, prefixByte byte, cb func(key []byte, outgoing types.OutgoingTx) bool) (*query.PageResponse, error) {
+ prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.MakeOutgoingTxKey([]byte{prefixByte}))
+
+ return query.FilteredPaginate(prefixStore, pageReq, func(key []byte, value []byte, accumulate bool) (bool, error) {
+ if !accumulate {
+ return false, nil
+ }
+
+ var any cdctypes.Any
+ k.cdc.MustUnmarshal(value, &any)
+ var otx types.OutgoingTx
+ if err := k.cdc.UnpackAny(&any, &otx); err != nil {
+ panic(err)
+ }
+ if accumulate {
+ return cb(key, otx), nil
+ }
+
+ return false, nil
+ })
+}
+
+// IterateOutgoingTxsByType iterates over a specific type of outgoing transaction denoted by the chosen prefix byte
+func (k Keeper) IterateOutgoingTxsByType(ctx sdk.Context, prefixByte byte, cb func(key []byte, outgoing types.OutgoingTx) (stop bool)) {
+ prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.MakeOutgoingTxKey([]byte{prefixByte}))
+ iter := prefixStore.ReverseIterator(nil, nil)
+ defer iter.Close()
+ for ; iter.Valid(); iter.Next() {
+ var any cdctypes.Any
+ k.cdc.MustUnmarshal(iter.Value(), &any)
+ var otx types.OutgoingTx
+ if err := k.cdc.UnpackAny(&any, &otx); err != nil {
+ panic(err)
+ }
+ if cb(iter.Key(), otx) {
+ break
+ }
+ }
+}
+
+// iterateOutgoingTxs iterates over a specific type of outgoing transaction denoted by the chosen prefix byte
+func (k Keeper) iterateOutgoingTxs(ctx sdk.Context, cb func(key []byte, outgoing types.OutgoingTx) bool) {
+ prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{types.OutgoingTxKey})
+ iter := prefixStore.ReverseIterator(nil, nil)
+ defer iter.Close()
+ for ; iter.Valid(); iter.Next() {
+ var any cdctypes.Any
+ k.cdc.MustUnmarshal(iter.Value(), &any)
+ var otx types.OutgoingTx
+ if err := k.cdc.UnpackAny(&any, &otx); err != nil {
+ panic(err)
+ }
+ if cb(iter.Key(), otx) {
+ break
+ }
+ }
+}
+
+// GetLastObservedSignerSetTx retrieves the last observed validator set from the store
+func (k Keeper) GetLastObservedSignerSetTx(ctx sdk.Context) *types.SignerSetTx {
+ key := []byte{types.LastObservedSignerSetKey}
+ if val := ctx.KVStore(k.storeKey).Get(key); val != nil {
+ var out types.SignerSetTx
+ k.cdc.MustUnmarshal(val, &out)
+ return &out
+ }
+ return nil
+}
+
+// setLastObservedSignerSetTx updates the last observed validator set in the stor e
+func (k Keeper) setLastObservedSignerSetTx(ctx sdk.Context, signerSet types.SignerSetTx) {
+ key := []byte{types.LastObservedSignerSetKey}
+ ctx.KVStore(k.storeKey).Set(key, k.cdc.MustMarshal(&signerSet))
+}
+
+// CreateContractCallTx xxx
+func (k Keeper) CreateContractCallTx(ctx sdk.Context, invalidationNonce uint64, invalidationScope tmbytes.HexBytes,
+ payload []byte, tokens []types.ERC20Token, fees []types.ERC20Token) *types.ContractCallTx {
+ params := k.GetParams(ctx)
+
+ newContractCallTx := &types.ContractCallTx{
+ InvalidationNonce: invalidationNonce,
+ InvalidationScope: invalidationScope,
+ Address: k.getBridgeContractAddress(ctx),
+ Payload: payload,
+ Timeout: params.TargetEthTxTimeout,
+ Tokens: tokens,
+ Fees: fees,
+ Height: uint64(ctx.BlockHeight()),
+ }
+
+ var tokenString []string
+ for _, token := range tokens {
+ tokenString = append(tokenString, token.String())
+ }
+
+ var feeString []string
+ for _, fee := range fees {
+ feeString = append(feeString, fee.String())
+ }
+
+ ctx.EventManager().EmitEvent(
+ sdk.NewEvent(
+ types.EventTypeMultisigUpdateRequest,
+ sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
+ sdk.NewAttribute(types.AttributeKeyContract, k.getBridgeContractAddress(ctx)),
+ sdk.NewAttribute(types.AttributeKeyBridgeChainID, strconv.Itoa(int(k.getBridgeChainID(ctx)))),
+ sdk.NewAttribute(types.AttributeKeyContractCallInvalidationNonce, fmt.Sprint(invalidationNonce)),
+ sdk.NewAttribute(types.AttributeKeyContractCallInvalidationScope, fmt.Sprint(invalidationScope)),
+ sdk.NewAttribute(types.AttributeKeyContractCallPayload, string(payload)),
+ sdk.NewAttribute(types.AttributeKeyContractCallTokens, strings.Join(tokenString, "|")),
+ sdk.NewAttribute(types.AttributeKeyContractCallFees, strings.Join(feeString, "|")),
+ sdk.NewAttribute(types.AttributeKeyEthTxTimeout, strconv.FormatUint(params.TargetEthTxTimeout, 10)),
+ ),
+ )
+ k.SetOutgoingTx(ctx, newContractCallTx)
+ k.Logger(ctx).Info(
+ "ContractCallTx created",
+ "invalidation_nonce", newContractCallTx.InvalidationNonce,
+ "invalidation_scope", newContractCallTx.InvalidationScope,
+ // todo: fill out all fields
+ )
+ return newContractCallTx
+}
diff --git a/module/x/gravity/keeper/keeper_test.go b/module/x/gravity/keeper/keeper_test.go
new file mode 100644
index 0000000..eb98034
--- /dev/null
+++ b/module/x/gravity/keeper/keeper_test.go
@@ -0,0 +1,509 @@
+package keeper
+
+import (
+ "bytes"
+ "testing"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+func TestCurrentValsetNormalization(t *testing.T) {
+ specs := map[string]struct {
+ srcPowers []uint64
+ expPowers []uint64
+ }{
+ "one": {
+ srcPowers: []uint64{100},
+ expPowers: []uint64{4294967295},
+ },
+ "two": {
+ srcPowers: []uint64{100, 1},
+ expPowers: []uint64{4252442866, 42524428},
+ },
+ }
+ input := CreateTestEnv(t)
+ ctx := input.Context
+ for msg, spec := range specs {
+ spec := spec
+ t.Run(msg, func(t *testing.T) {
+ operators := make([]MockStakingValidatorData, len(spec.srcPowers))
+ for i, v := range spec.srcPowers {
+ cAddr := bytes.Repeat([]byte{byte(i)}, 20)
+ operators[i] = MockStakingValidatorData{
+ // any unique addr
+ Operator: cAddr,
+ Power: int64(v),
+ }
+ input.GravityKeeper.setValidatorEthereumAddress(ctx, cAddr, common.HexToAddress("0xf71402f886b45c134743F4c00750823Bbf5Fd045"))
+ }
+ input.GravityKeeper.StakingKeeper = NewStakingKeeperWeightedMock(operators...)
+ r := input.GravityKeeper.CreateSignerSetTx(ctx)
+ assert.Equal(t, spec.expPowers, r.Signers.GetPowers())
+ })
+ }
+}
+
+func TestAttestationIterator(t *testing.T) {
+ input := CreateTestEnv(t)
+ ctx := input.Context
+ // add some attestations to the store
+
+ att1 := &types.EthereumEventVoteRecord{
+ Accepted: true,
+ Votes: []string{},
+ }
+ dep1 := &types.SendToCosmosEvent{
+ EventNonce: 1,
+ TokenContract: TokenContractAddrs[0],
+ Amount: sdk.NewInt(100),
+ EthereumSender: EthAddrs[0].String(),
+ CosmosReceiver: AccAddrs[0].String(),
+ }
+ att2 := &types.EthereumEventVoteRecord{
+ Accepted: true,
+ Votes: []string{},
+ }
+ dep2 := &types.SendToCosmosEvent{
+ EventNonce: 2,
+ TokenContract: TokenContractAddrs[0],
+ Amount: sdk.NewInt(100),
+ EthereumSender: EthAddrs[0].String(),
+ CosmosReceiver: AccAddrs[0].String(),
+ }
+ input.GravityKeeper.setEthereumEventVoteRecord(ctx, dep1.EventNonce, dep1.Hash(), att1)
+ input.GravityKeeper.setEthereumEventVoteRecord(ctx, dep2.EventNonce, dep2.Hash(), att2)
+
+ var atts []*types.EthereumEventVoteRecord
+ input.GravityKeeper.iterateEthereumEventVoteRecords(ctx, func(_ []byte, att *types.EthereumEventVoteRecord) bool {
+ atts = append(atts, att)
+ return false
+ })
+
+ require.Len(t, atts, 2)
+}
+
+func TestDelegateKeys(t *testing.T) {
+ input := CreateTestEnv(t)
+ ctx := input.Context
+ k := input.GravityKeeper
+ var (
+ ethAddrs = []common.Address{
+ common.HexToAddress("0x3146D2d6Eed46Afa423969f5dDC3152DfC359b09"),
+ common.HexToAddress("0x610277F0208D342C576b991daFdCb36E36515e76"),
+ common.HexToAddress("0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4"),
+ common.HexToAddress("0xb2A7F3E84F8FdcA1da46c810AEa110dd96BAE6bF"),
+ }
+ valAddrs = []string{
+ "cosmosvaloper1jpz0ahls2chajf78nkqczdwwuqcu97w6z3plt4",
+ "cosmosvaloper15n79nty2fj37ant3p2gj4wju4ls6eu6tjwmdt0",
+ "cosmosvaloper16dnkc6ac6ruuyr6l372fc3p77jgjpet6fka0cq",
+ "cosmosvaloper1vrptwhl3ht2txmzy28j9msqkcvmn8gjz507pgu",
+ }
+ orchAddrs = []string{
+ "cosmos1g0etv93428tvxqftnmj25jn06mz6dtdasj5nz7",
+ "cosmos1rhfs24tlw4na04v35tzmjncy785kkw9j27d5kx",
+ "cosmos10upq3tmt04zf55f6hw67m0uyrda3mp722q70rw",
+ "cosmos1nt2uwjh5peg9vz2wfh2m3jjwqnu9kpjlhgpmen",
+ }
+ )
+ for i := range ethAddrs {
+ // set some addresses
+ val, err1 := sdk.ValAddressFromBech32(valAddrs[i])
+ orch, err2 := sdk.AccAddressFromBech32(orchAddrs[i])
+ require.NoError(t, err1)
+ require.NoError(t, err2)
+
+ k.SetOrchestratorValidatorAddress(ctx, val, orch)
+ k.setValidatorEthereumAddress(ctx, val, ethAddrs[i])
+ k.setEthereumOrchestratorAddress(ctx, ethAddrs[i], orch)
+ }
+ addresses := k.getDelegateKeys(ctx)
+ for i := range addresses {
+ res := addresses[i]
+ assert.Equal(t, valAddrs[i], res.ValidatorAddress)
+ assert.Equal(t, orchAddrs[i], res.OrchestratorAddress)
+ assert.Equal(t, ethAddrs[i].Hex(), res.EthereumAddress)
+ }
+}
+
+func TestStoreEventVoteRecord(t *testing.T) {
+ input := CreateTestEnv(t)
+ gk := input.GravityKeeper
+ ctx := input.Context
+ stce := &types.SendToCosmosEvent{
+ EventNonce: 1,
+ TokenContract: EthAddrs[0].Hex(),
+ EthereumSender: EthAddrs[0].Hex(),
+ CosmosReceiver: AccAddrs[0].String(),
+ EthereumHeight: 10,
+ Amount: sdk.NewInt(1000000),
+ }
+ stcea, err := types.PackEvent(stce)
+ require.NoError(t, err)
+
+ evr := &types.EthereumEventVoteRecord{
+ Event: stcea,
+ Votes: []string{
+ ValAddrs[0].String(),
+ ValAddrs[1].String(),
+ ValAddrs[2].String(),
+ },
+ Accepted: false,
+ }
+
+ cctxe := &types.ContractCallExecutedEvent{
+ EventNonce: 2,
+ InvalidationScope: []byte{0x1, 0x2},
+ InvalidationNonce: 1,
+ EthereumHeight: 11,
+ }
+
+ cctxea, err := types.PackEvent(cctxe)
+ require.NoError(t, err)
+
+ evr2 := &types.EthereumEventVoteRecord{
+ Event: cctxea,
+ Votes: []string{
+ ValAddrs[2].String(),
+ ValAddrs[3].String(),
+ ValAddrs[4].String(),
+ },
+ }
+
+ gk.setEthereumEventVoteRecord(ctx, stce.GetEventNonce(), stce.Hash(), evr)
+ gk.setEthereumEventVoteRecord(ctx, cctxe.GetEventNonce(), cctxe.Hash(), evr2)
+
+ stored := gk.GetEthereumEventVoteRecord(ctx, stce.GetEventNonce(), stce.Hash())
+ require.NotNil(t, stored)
+
+ stored1 := gk.GetEthereumEventVoteRecord(ctx, cctxe.GetEventNonce(), cctxe.Hash())
+ require.NotNil(t, stored1)
+
+ // var storedEvent, storedEvent1 types.EthereumEvent
+ storedEvent, err := types.UnpackEvent(stored.Event)
+ require.NoError(t, err)
+ storedEvent1, err := types.UnpackEvent(stored1.Event)
+ require.NoError(t, err)
+
+ require.EqualValues(t, storedEvent.GetEventNonce(), 1)
+ require.EqualValues(t, storedEvent.Hash(), stce.Hash())
+
+ require.EqualValues(t, storedEvent1.GetEventNonce(), 2)
+ require.EqualValues(t, storedEvent1.Hash(), cctxe.Hash())
+
+ mapping := gk.GetEthereumEventVoteRecordMapping(ctx)
+ require.EqualValues(t, 3, len(mapping[1][0].Votes))
+ require.EqualValues(t, 3, len(mapping[2][0].Votes))
+
+ eve1, err := types.UnpackEvent(mapping[1][0].Event)
+ require.NoError(t, err)
+ eve2, err := types.UnpackEvent(mapping[2][0].Event)
+ require.NoError(t, err)
+ require.EqualValues(t, 1, eve1.GetEventNonce())
+ require.EqualValues(t, 2, eve2.GetEventNonce())
+ require.EqualValues(t, stce.Hash(), eve1.Hash())
+ require.EqualValues(t, cctxe.Hash(), eve2.Hash())
+}
+
+func TestLastSlashedValsetNonce(t *testing.T) {
+ input := CreateTestEnv(t)
+ k := input.GravityKeeper
+ ctx := input.Context
+
+ i := 1
+ for ; i < 10; i++ {
+ ctx = ctx.WithBlockHeight(int64(i))
+ _ = k.CreateSignerSetTx(ctx)
+ }
+
+ latestValsetNonce := k.GetLatestSignerSetTxNonce(ctx)
+ assert.Equal(t, uint64(i-1), latestValsetNonce)
+
+ // lastSlashedValsetNonce should be zero initially.
+ lastSlashedValsetNonce := k.GetLastSlashedOutgoingTxBlockHeight(ctx)
+ assert.Equal(t, uint64(0), lastSlashedValsetNonce)
+ unslashedValsets := k.GetUnSlashedOutgoingTxs(ctx, uint64(12))
+ assert.Equal(t, 9, len(unslashedValsets))
+
+ // check if last Slashed Valset nonce is set properly or not
+ k.SetLastSlashedOutgoingTxBlockHeight(ctx, uint64(3))
+ lastSlashedValsetNonce = k.GetLastSlashedOutgoingTxBlockHeight(ctx)
+ assert.Equal(t, uint64(3), lastSlashedValsetNonce)
+
+ // when maxHeight < lastSlashedValsetNonce, len(unslashedValsets) should be zero
+ unslashedValsets = k.GetUnSlashedOutgoingTxs(ctx, uint64(2))
+ assert.Equal(t, 0, len(unslashedValsets))
+
+ // when maxHeight == lastSlashedValsetNonce, len(unslashedValsets) should be zero
+ unslashedValsets = k.GetUnSlashedOutgoingTxs(ctx, uint64(3))
+ assert.Equal(t, 0, len(unslashedValsets))
+
+ // when maxHeight > lastSlashedValsetNonce && maxHeight <= latestValsetNonce
+ unslashedValsets = k.GetUnSlashedOutgoingTxs(ctx, uint64(6))
+ assert.Equal(t, 2, len(unslashedValsets))
+
+ // when maxHeight > latestValsetNonce
+ unslashedValsets = k.GetUnSlashedOutgoingTxs(ctx, uint64(15))
+ assert.Equal(t, 6, len(unslashedValsets))
+}
+
+// ---
+
+func TestKeeper_GetLatestSignerSetTx(t *testing.T) {
+ t.Run("read before there's one in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ got := gk.GetLatestSignerSetTx(ctx)
+ require.Nil(t, got)
+ })
+
+ t.Run("read after there's one in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ { // setup
+ gk.SetOutgoingTx(ctx, &types.SignerSetTx{
+ Nonce: gk.incrementLatestSignerSetTxNonce(ctx),
+ Height: 1,
+ Signers: nil,
+ })
+ }
+
+ { // validate
+ got := gk.GetLatestSignerSetTx(env.Context)
+ require.NotNil(t, got)
+ require.EqualValues(t, got.Height, gk.GetLatestSignerSetTxNonce(ctx))
+ }
+ })
+}
+
+func TestKeeper_GetSignerSetTxs(t *testing.T) {
+ t.Run("read before there's any in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ got := gk.GetSignerSetTxs(ctx)
+ require.Nil(t, got)
+ })
+
+ t.Run("read after there's one in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ { // setup
+ gk.SetOutgoingTx(ctx, &types.SignerSetTx{
+ Nonce: gk.incrementLatestSignerSetTxNonce(ctx),
+ Height: 1,
+ Signers: nil,
+ })
+ }
+
+ { // validate
+ got := gk.GetSignerSetTxs(ctx)
+ require.NotNil(t, got)
+ require.Len(t, got, 1)
+ }
+ })
+}
+
+func TestKeeper_GetLastObservedSignerSetTx(t *testing.T) {
+ t.Run("read before there's any in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ got := gk.GetLastObservedSignerSetTx(ctx)
+ require.Nil(t, got)
+ })
+
+ t.Run("read after there's one in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ { // setup
+ gk.setLastObservedSignerSetTx(ctx, types.SignerSetTx{
+ Nonce: 1,
+ Height: 1,
+ Signers: nil,
+ })
+ }
+
+ { // validate
+ got := gk.GetLastObservedSignerSetTx(ctx)
+ require.NotNil(t, got)
+ }
+ })
+}
+
+func TestKeeper_GetLastUnbondingBlockHeight(t *testing.T) {
+ t.Run("read before there's any in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ got := gk.GetLastUnbondingBlockHeight(ctx)
+ require.Zero(t, got)
+ })
+
+ t.Run("read after there's one in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ { // setup
+ gk.setLastUnbondingBlockHeight(ctx, 10)
+ }
+
+ { // validate
+ got := gk.GetLastUnbondingBlockHeight(ctx)
+ require.EqualValues(t, 10, got)
+ }
+ })
+}
+
+func TestKeeper_GetEthereumSignatures(t *testing.T) {
+ t.Run("read before there's anything in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ storeIndexes := [][]byte{
+ types.MakeSignerSetTxKey(1),
+ types.MakeBatchTxKey(common.HexToAddress(""), 1), // weird that empty address is okay
+ types.MakeContractCallTxKey(nil, 0),
+ }
+ for _, storeIndex := range storeIndexes {
+ got := gk.GetEthereumSignatures(ctx, storeIndex)
+ require.Empty(t, got)
+ }
+ })
+
+ t.Run("read after there's one signer-set-tx-confirmation in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ ethAddr := common.HexToAddress("0x3146D2d6Eed46Afa423969f5dDC3152DfC359b09")
+ valAddr, err := sdk.ValAddressFromBech32("cosmosvaloper1jpz0ahls2chajf78nkqczdwwuqcu97w6z3plt4")
+ require.NoError(t, err)
+
+ const signerSetNonce = 10
+
+ { // setup
+ signerSetTxConfirmation := &types.SignerSetTxConfirmation{
+ SignerSetNonce: signerSetNonce,
+ EthereumSigner: ethAddr.Hex(),
+ Signature: []byte("fake-signature"),
+ }
+ key := gk.SetEthereumSignature(ctx, signerSetTxConfirmation, valAddr)
+ require.NotEmpty(t, key)
+ }
+
+ { // validate
+ storeIndex := types.MakeSignerSetTxKey(signerSetNonce)
+
+ { // getEthereumSignature
+ got := gk.getEthereumSignature(ctx, storeIndex, valAddr)
+ require.Equal(t, []byte("fake-signature"), got)
+ }
+ { // GetEthereumSignatures
+ got := gk.GetEthereumSignatures(ctx, storeIndex)
+ require.Len(t, got, 1)
+ }
+ }
+ })
+
+ t.Run("read after there's one batch-tx-confirmation in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ ethAddr := common.HexToAddress("0x3146D2d6Eed46Afa423969f5dDC3152DfC359b09")
+ valAddr, err := sdk.ValAddressFromBech32("cosmosvaloper1jpz0ahls2chajf78nkqczdwwuqcu97w6z3plt4")
+ require.NoError(t, err)
+
+ const (
+ batchNonce = 10
+ tokenContract = "0x1111111111111111111111111111111111111111"
+ )
+
+ { // setup
+ batchTxConfirmation := &types.BatchTxConfirmation{
+ TokenContract: tokenContract,
+ BatchNonce: batchNonce,
+ EthereumSigner: ethAddr.Hex(),
+ Signature: []byte("fake-signature"),
+ }
+ key := gk.SetEthereumSignature(ctx, batchTxConfirmation, valAddr)
+ require.NotEmpty(t, key)
+ }
+
+ { // validate
+ storeIndex := types.MakeBatchTxKey(common.HexToAddress(tokenContract), batchNonce)
+
+ { // getEthereumSignature
+ got := gk.getEthereumSignature(ctx, storeIndex, valAddr)
+ require.Equal(t, []byte("fake-signature"), got)
+ }
+ { // GetEthereumSignatures
+ got := gk.GetEthereumSignatures(ctx, storeIndex)
+ require.Len(t, got, 1)
+ }
+ }
+ })
+
+ t.Run("read after there's one contract-call-tx-confirmation in state", func(t *testing.T) {
+ env := CreateTestEnv(t)
+ ctx := env.Context
+ gk := env.GravityKeeper
+
+ ethAddr := common.HexToAddress("0x3146D2d6Eed46Afa423969f5dDC3152DfC359b09")
+
+ valAddr, err := sdk.ValAddressFromBech32("cosmosvaloper1jpz0ahls2chajf78nkqczdwwuqcu97w6z3plt4")
+ require.NoError(t, err)
+
+ const (
+ invalidationScope = "some-invalidation-scope"
+ invalidationNonce = 10
+ )
+
+ { // setup
+ contractCallConfirmation := &types.ContractCallTxConfirmation{
+ InvalidationScope: []byte(invalidationScope),
+ InvalidationNonce: invalidationNonce,
+ EthereumSigner: ethAddr.Hex(),
+ Signature: []byte("fake-signature"),
+ }
+ key := gk.SetEthereumSignature(ctx, contractCallConfirmation, valAddr)
+ require.NotEmpty(t, key)
+ }
+
+ { // validate
+ storeIndex := types.MakeContractCallTxKey([]byte(invalidationScope), invalidationNonce)
+
+ { // getEthereumSignature
+ got := gk.getEthereumSignature(ctx, storeIndex, valAddr)
+ require.Equal(t, []byte("fake-signature"), got)
+ }
+ { // GetEthereumSignatures
+ got := gk.GetEthereumSignatures(ctx, storeIndex)
+ require.Len(t, got, 1)
+ }
+ }
+ })
+}
+
+// TODO(levi) review/ensure coverage for:
+// PaginateOutgoingTxsByType
+// GetUnbondingvalidators(unbondingVals []byte) stakingtypes.ValAddresses
diff --git a/module/x/gravity/keeper/msg_server.go b/module/x/gravity/keeper/msg_server.go
new file mode 100644
index 0000000..849a0ae
--- /dev/null
+++ b/module/x/gravity/keeper/msg_server.go
@@ -0,0 +1,305 @@
+package keeper
+
+import (
+ "context"
+ "encoding/hex"
+ "fmt"
+ "strconv"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+type msgServer struct {
+ Keeper
+}
+
+// NewMsgServerImpl returns an implementation of the gov MsgServer interface
+// for the provided Keeper.
+func NewMsgServerImpl(keeper Keeper) types.MsgServer {
+ return &msgServer{Keeper: keeper}
+}
+
+var _ types.MsgServer = msgServer{}
+
+func (k msgServer) SetDelegateKeys(c context.Context, msg *types.MsgDelegateKeys) (*types.MsgDelegateKeysResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+
+ valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
+ if err != nil {
+ return nil, err
+ }
+
+ orchAddr, err := sdk.AccAddressFromBech32(msg.OrchestratorAddress)
+ if err != nil {
+ return nil, err
+ }
+
+ ethAddr := common.HexToAddress(msg.EthereumAddress)
+
+ // ensure that the validator exists
+ if k.Keeper.StakingKeeper.Validator(ctx, valAddr) == nil {
+ return nil, sdkerrors.Wrap(stakingtypes.ErrNoValidatorFound, valAddr.String())
+ }
+
+ // check if the Ethereum address is currently not used
+ validators := k.getValidatorsByEthereumAddress(ctx, ethAddr)
+ if len(validators) > 0 {
+ return nil, sdkerrors.Wrapf(types.ErrDelegateKeys, "ethereum address %s in use", ethAddr)
+ }
+
+ // check if the orchestrator address is currently not used
+ ethAddrs := k.getEthereumAddressesByOrchestrator(ctx, orchAddr)
+ if len(ethAddrs) > 0 {
+ return nil, sdkerrors.Wrapf(types.ErrDelegateKeys, "orchestrator address %s in use", orchAddr)
+ }
+
+ valAccAddr := sdk.AccAddress(valAddr)
+ valAccSeq, err := k.accountKeeper.GetSequence(ctx, valAccAddr)
+ if err != nil {
+ return nil, sdkerrors.Wrapf(types.ErrDelegateKeys, "failed to get sequence for validator account %s", valAccAddr)
+ }
+
+ var nonce uint64
+ if valAccSeq > 0 {
+ nonce = valAccSeq - 1
+ }
+
+ signMsgBz := k.cdc.MustMarshal(&types.DelegateKeysSignMsg{
+ ValidatorAddress: valAddr.String(),
+ // We decrement since we process the message after the ante-handler which
+ // increments the nonce.
+ Nonce: nonce,
+ })
+
+ hash := crypto.Keccak256Hash(signMsgBz).Bytes()
+
+ if err = types.ValidateEthereumSignature(hash, msg.EthSignature, ethAddr); err != nil {
+ return nil, sdkerrors.Wrapf(
+ types.ErrDelegateKeys,
+ "failed to validate delegate keys signature for Ethereum address %X; %s",
+ ethAddr, err,
+ )
+ }
+
+ k.SetOrchestratorValidatorAddress(ctx, valAddr, orchAddr)
+ k.setValidatorEthereumAddress(ctx, valAddr, ethAddr)
+ k.setEthereumOrchestratorAddress(ctx, ethAddr, orchAddr)
+
+ ctx.EventManager().EmitEvent(
+ sdk.NewEvent(
+ sdk.EventTypeMessage,
+ sdk.NewAttribute(sdk.AttributeKeyModule, msg.Type()),
+ sdk.NewAttribute(types.AttributeKeySetOrchestratorAddr, orchAddr.String()),
+ sdk.NewAttribute(types.AttributeKeySetEthereumAddr, ethAddr.Hex()),
+ sdk.NewAttribute(types.AttributeKeyValidatorAddr, valAddr.String()),
+ ),
+ )
+
+ return &types.MsgDelegateKeysResponse{}, nil
+
+}
+
+// SubmitEthereumTxConfirmation handles MsgSubmitEthereumTxConfirmation
+func (k msgServer) SubmitEthereumTxConfirmation(c context.Context, msg *types.MsgSubmitEthereumTxConfirmation) (*types.MsgSubmitEthereumTxConfirmationResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+
+ confirmation, err := types.UnpackConfirmation(msg.Confirmation)
+ if err != nil {
+ return nil, err
+ }
+
+ val, err := k.getSignerValidator(ctx, msg.Signer)
+ if err != nil {
+ return nil, err
+ }
+
+ otx := k.GetOutgoingTx(ctx, confirmation.GetStoreIndex())
+ if otx == nil {
+ return nil, sdkerrors.Wrap(types.ErrInvalid, "couldn't find outgoing tx")
+ }
+
+ gravityID := k.getGravityID(ctx)
+ checkpoint := otx.GetCheckpoint([]byte(gravityID))
+
+ ethAddress := k.GetValidatorEthereumAddress(ctx, val)
+ if ethAddress != confirmation.GetSigner() {
+ return nil, sdkerrors.Wrap(types.ErrInvalid, "eth address does not match signer eth address")
+ }
+
+ if err = types.ValidateEthereumSignature(checkpoint, confirmation.GetSignature(), ethAddress); err != nil {
+ return nil, sdkerrors.Wrap(types.ErrInvalid, fmt.Sprintf(
+ "signature verification failed ethAddress %s gravityID %s checkpoint %s typeURL %s signature %s err %s",
+ ethAddress.Hex(),
+ gravityID,
+ hex.EncodeToString(checkpoint),
+ msg.Confirmation.TypeUrl,
+ hex.EncodeToString(confirmation.GetSignature()),
+ err,
+ ))
+ }
+
+ // TODO: should validators be able to overwrite their signatures?
+ if k.getEthereumSignature(ctx, confirmation.GetStoreIndex(), val) != nil {
+ return nil, sdkerrors.Wrap(types.ErrInvalid, "signature duplicate")
+ }
+
+ key := k.SetEthereumSignature(ctx, confirmation, val)
+
+ ctx.EventManager().EmitEvent(
+ sdk.NewEvent(
+ sdk.EventTypeMessage,
+ sdk.NewAttribute(sdk.AttributeKeyModule, msg.Type()),
+ sdk.NewAttribute(types.AttributeKeyEthereumSignatureKey, string(key)),
+ ),
+ )
+
+ return &types.MsgSubmitEthereumTxConfirmationResponse{}, nil
+}
+
+// func (k Keeper) ValidateEthereumSignature
+
+// SubmitEthereumEvent handles MsgSubmitEthereumEvent
+func (k msgServer) SubmitEthereumEvent(c context.Context, msg *types.MsgSubmitEthereumEvent) (*types.MsgSubmitEthereumEventResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+
+ event, err := types.UnpackEvent(msg.Event)
+ if err != nil {
+ return nil, err
+ }
+
+ // return an error if the validator isn't in the active set
+ val, err := k.getSignerValidator(ctx, msg.Signer)
+ if err != nil {
+ return nil, err
+ }
+
+ // Add the claim to the store
+ _, err = k.recordEventVote(ctx, event, val)
+ if err != nil {
+ return nil, sdkerrors.Wrap(err, "create event vote record")
+ }
+
+ // Emit the handle message event
+ ctx.EventManager().EmitEvent(
+ sdk.NewEvent(
+ sdk.EventTypeMessage,
+ sdk.NewAttribute(sdk.AttributeKeyModule, fmt.Sprintf("%T", event)),
+ // TODO: maybe return something better here? is this the right string representation?
+ sdk.NewAttribute(types.AttributeKeyEthereumEventVoteRecordID, string(types.MakeEthereumEventVoteRecordKey(event.GetEventNonce(), event.Hash()))),
+ ),
+ )
+
+ return &types.MsgSubmitEthereumEventResponse{}, nil
+}
+
+// SendToEthereum handles MsgSendToEthereum
+func (k msgServer) SendToEthereum(c context.Context, msg *types.MsgSendToEthereum) (*types.MsgSendToEthereumResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+ sender, err := sdk.AccAddressFromBech32(msg.Sender)
+ if err != nil {
+ return nil, err
+ }
+
+ txID, err := k.createSendToEthereum(ctx, sender, msg.EthereumRecipient, msg.Amount, msg.BridgeFee)
+ if err != nil {
+ return nil, err
+ }
+
+ ctx.EventManager().EmitEvents([]sdk.Event{
+ sdk.NewEvent(
+ types.EventTypeBridgeWithdrawalReceived,
+ sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
+ sdk.NewAttribute(types.AttributeKeyContract, k.getBridgeContractAddress(ctx)),
+ sdk.NewAttribute(types.AttributeKeyBridgeChainID, strconv.Itoa(int(k.getBridgeChainID(ctx)))),
+ sdk.NewAttribute(types.AttributeKeyOutgoingTXID, strconv.Itoa(int(txID))),
+ sdk.NewAttribute(types.AttributeKeyNonce, fmt.Sprint(txID)),
+ ),
+ sdk.NewEvent(
+ sdk.EventTypeMessage,
+ sdk.NewAttribute(sdk.AttributeKeyModule, msg.Type()),
+ sdk.NewAttribute(types.AttributeKeyOutgoingTXID, fmt.Sprint(txID)),
+ ),
+ })
+
+ return &types.MsgSendToEthereumResponse{Id: txID}, nil
+}
+
+// RequestBatchTx handles MsgRequestBatchTx
+func (k msgServer) RequestBatchTx(c context.Context, msg *types.MsgRequestBatchTx) (*types.MsgRequestBatchTxResponse, error) {
+ // TODO: limit this to only orchestrators and validators?
+ ctx := sdk.UnwrapSDKContext(c)
+
+ // Check if the denom is a gravity coin, if not, check if there is a deployed ERC20 representing it.
+ // If not, error out
+ _, tokenContract, err := k.DenomToERC20Lookup(ctx, msg.Denom)
+ if err != nil {
+ return nil, err
+ }
+
+ batchID := k.BuildBatchTx(ctx, tokenContract, BatchTxSize)
+
+ ctx.EventManager().EmitEvent(
+ sdk.NewEvent(
+ sdk.EventTypeMessage,
+ sdk.NewAttribute(sdk.AttributeKeyModule, msg.Type()),
+ sdk.NewAttribute(types.AttributeKeyContract, tokenContract.Hex()),
+ sdk.NewAttribute(types.AttributeKeyBatchNonce, fmt.Sprint(batchID.BatchNonce)),
+ ),
+ )
+
+ return &types.MsgRequestBatchTxResponse{}, nil
+}
+
+func (k msgServer) CancelSendToEthereum(c context.Context, msg *types.MsgCancelSendToEthereum) (*types.MsgCancelSendToEthereumResponse, error) {
+ ctx := sdk.UnwrapSDKContext(c)
+
+ err := k.Keeper.cancelSendToEthereum(ctx, msg.Id, msg.Sender)
+ if err != nil {
+ return nil, err
+ }
+
+ ctx.EventManager().EmitEvents([]sdk.Event{
+ sdk.NewEvent(
+ types.EventTypeBridgeWithdrawCanceled,
+ sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
+ sdk.NewAttribute(types.AttributeKeyContract, k.getBridgeContractAddress(ctx)),
+ sdk.NewAttribute(types.AttributeKeyBridgeChainID, strconv.Itoa(int(k.getBridgeChainID(ctx)))),
+ ),
+ sdk.NewEvent(
+ sdk.EventTypeMessage,
+ sdk.NewAttribute(sdk.AttributeKeyModule, msg.Type()),
+ sdk.NewAttribute(types.AttributeKeyOutgoingTXID, fmt.Sprint(msg.Id)),
+ ),
+ })
+
+ return &types.MsgCancelSendToEthereumResponse{}, nil
+}
+
+// getSignerValidator takes an sdk.AccAddress that represents either a validator or orchestrator address and returns
+// the assoicated validator address
+func (k Keeper) getSignerValidator(ctx sdk.Context, signerString string) (sdk.ValAddress, error) {
+ signer, err := sdk.AccAddressFromBech32(signerString)
+ if err != nil {
+ return nil, sdkerrors.Wrap(types.ErrInvalid, "signer address")
+ }
+ var validatorI stakingtypes.ValidatorI
+ if validator := k.GetOrchestratorValidatorAddress(ctx, signer); validator == nil {
+ validatorI = k.StakingKeeper.Validator(ctx, sdk.ValAddress(signer))
+ } else {
+ validatorI = k.StakingKeeper.Validator(ctx, validator)
+ }
+
+ if validatorI == nil {
+ return nil, sdkerrors.Wrap(types.ErrInvalid, "not orchestrator or validator")
+ } else if !validatorI.IsBonded() {
+ return nil, sdkerrors.Wrap(types.ErrInvalid, fmt.Sprintf("validator is not bonded: %s", validatorI.GetOperator()))
+ }
+
+ return validatorI.GetOperator(), nil
+}
diff --git a/module/x/gravity/keeper/msg_server_test.go b/module/x/gravity/keeper/msg_server_test.go
new file mode 100644
index 0000000..fc08957
--- /dev/null
+++ b/module/x/gravity/keeper/msg_server_test.go
@@ -0,0 +1,401 @@
+package keeper
+
+import (
+ "bytes"
+ "crypto/ecdsa"
+ "fmt"
+ "testing"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/crypto"
+ ethCrypto "github.com/ethereum/go-ethereum/crypto"
+ "github.com/stretchr/testify/require"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+func TestMsgServer_SubmitEthereumSignature(t *testing.T) {
+ ethPrivKey, err := ethCrypto.GenerateKey()
+ require.NoError(t, err)
+
+ var (
+ env = CreateTestEnv(t)
+ ctx = env.Context
+ gk = env.GravityKeeper
+
+ orcAddr1, _ = sdk.AccAddressFromBech32("cosmos1dg55rtevlfxh46w88yjpdd08sqhh5cc3xhkcej")
+ valAddr1 = sdk.ValAddress(orcAddr1)
+ ethAddr1 = crypto.PubkeyToAddress(ethPrivKey.PublicKey)
+
+ orcAddr2, _ = sdk.AccAddressFromBech32("cosmos164knshrzuuurf05qxf3q5ewpfnwzl4gj4m4dfy")
+ valAddr2 = sdk.ValAddress(orcAddr2)
+
+ orcAddr3, _ = sdk.AccAddressFromBech32("cosmos193fw83ynn76328pty4yl7473vg9x86alq2cft7")
+ valAddr3 = sdk.ValAddress(orcAddr3)
+ )
+
+ { // setup for getSignerValidator
+ gk.StakingKeeper = NewStakingKeeperMock(valAddr1, valAddr2, valAddr3)
+ gk.SetOrchestratorValidatorAddress(ctx, valAddr1, orcAddr1)
+ gk.SetOrchestratorValidatorAddress(ctx, valAddr2, orcAddr2)
+ gk.SetOrchestratorValidatorAddress(ctx, valAddr3, orcAddr3)
+ }
+
+ // setup for GetValidatorEthereumAddress
+ gk.setValidatorEthereumAddress(ctx, valAddr1, ethAddr1)
+
+ // setup for GetOutgoingTx
+ signerSetTx := gk.CreateSignerSetTx(ctx)
+
+ // setup for ValidateEthereumSignature
+ gravityId := gk.getGravityID(ctx)
+ checkpoint := signerSetTx.GetCheckpoint([]byte(gravityId))
+ signature, err := types.NewEthereumSignature(checkpoint, ethPrivKey)
+ require.NoError(t, err)
+
+ signerSetTxConfirmation := &types.SignerSetTxConfirmation{
+ SignerSetNonce: signerSetTx.Nonce,
+ EthereumSigner: ethAddr1.Hex(),
+ Signature: signature,
+ }
+
+ confirmation, err := types.PackConfirmation(signerSetTxConfirmation)
+ require.NoError(t, err)
+
+ msgServer := NewMsgServerImpl(gk)
+
+ msg := &types.MsgSubmitEthereumTxConfirmation{
+ Confirmation: confirmation,
+ Signer: orcAddr1.String(),
+ }
+
+ _, err = msgServer.SubmitEthereumTxConfirmation(sdk.WrapSDKContext(ctx), msg)
+ require.NoError(t, err)
+}
+
+func TestMsgServer_SendToEthereum(t *testing.T) {
+ ethPrivKey, err := ethCrypto.GenerateKey()
+ require.NoError(t, err)
+
+ var (
+ env = CreateTestEnv(t)
+ ctx = env.Context
+ gk = env.GravityKeeper
+
+ orcAddr1, _ = sdk.AccAddressFromBech32("cosmos1dg55rtevlfxh46w88yjpdd08sqhh5cc3xhkcej")
+ valAddr1 = sdk.ValAddress(orcAddr1)
+ ethAddr1 = crypto.PubkeyToAddress(ethPrivKey.PublicKey)
+
+ orcAddr2, _ = sdk.AccAddressFromBech32("cosmos164knshrzuuurf05qxf3q5ewpfnwzl4gj4m4dfy")
+ valAddr2 = sdk.ValAddress(orcAddr2)
+
+ orcAddr3, _ = sdk.AccAddressFromBech32("cosmos193fw83ynn76328pty4yl7473vg9x86alq2cft7")
+ valAddr3 = sdk.ValAddress(orcAddr3)
+
+ testDenom = "stake"
+
+ balance = sdk.Coin{
+ Denom: testDenom,
+ Amount: sdk.NewInt(10000),
+ }
+ amount = sdk.Coin{
+ Denom: testDenom,
+ Amount: sdk.NewInt(1000),
+ }
+ fee = sdk.Coin{
+ Denom: testDenom,
+ Amount: sdk.NewInt(10),
+ }
+ )
+
+ { // setup for getSignerValidator
+ gk.StakingKeeper = NewStakingKeeperMock(valAddr1, valAddr2, valAddr3)
+ gk.SetOrchestratorValidatorAddress(ctx, valAddr1, orcAddr1)
+ }
+
+ { // add balance to bank
+ err = env.AddBalanceToBank(ctx, orcAddr1, sdk.Coins{balance})
+ require.NoError(t, err)
+ }
+
+ // create denom in keeper
+ gk.setCosmosOriginatedDenomToERC20(ctx, testDenom, "testcontractstring")
+
+ // setup for GetValidatorEthereumAddress
+ gk.setValidatorEthereumAddress(ctx, valAddr1, ethAddr1)
+
+ msgServer := NewMsgServerImpl(gk)
+
+ msg := &types.MsgSendToEthereum{
+ Sender: orcAddr1.String(),
+ EthereumRecipient: ethAddr1.String(),
+ Amount: amount,
+ BridgeFee: fee,
+ }
+
+ _, err = msgServer.SendToEthereum(sdk.WrapSDKContext(ctx), msg)
+ require.NoError(t, err)
+}
+
+func TestMsgServer_CancelSendToEthereum(t *testing.T) {
+ ethPrivKey, err := ethCrypto.GenerateKey()
+ require.NoError(t, err)
+
+ var (
+ env = CreateTestEnv(t)
+ ctx = env.Context
+ gk = env.GravityKeeper
+
+ orcAddr1, _ = sdk.AccAddressFromBech32("cosmos1dg55rtevlfxh46w88yjpdd08sqhh5cc3xhkcej")
+ valAddr1 = sdk.ValAddress(orcAddr1)
+ ethAddr1 = crypto.PubkeyToAddress(ethPrivKey.PublicKey)
+
+ orcAddr2, _ = sdk.AccAddressFromBech32("cosmos164knshrzuuurf05qxf3q5ewpfnwzl4gj4m4dfy")
+ valAddr2 = sdk.ValAddress(orcAddr2)
+
+ orcAddr3, _ = sdk.AccAddressFromBech32("cosmos193fw83ynn76328pty4yl7473vg9x86alq2cft7")
+ valAddr3 = sdk.ValAddress(orcAddr3)
+
+ testDenom = "stake"
+
+ balance = sdk.Coin{
+ Denom: testDenom,
+ Amount: sdk.NewInt(10000),
+ }
+ amount = sdk.Coin{
+ Denom: testDenom,
+ Amount: sdk.NewInt(1000),
+ }
+ fee = sdk.Coin{
+ Denom: testDenom,
+ Amount: sdk.NewInt(10),
+ }
+ )
+
+ { // setup for getSignerValidator
+ gk.StakingKeeper = NewStakingKeeperMock(valAddr1, valAddr2, valAddr3)
+ gk.SetOrchestratorValidatorAddress(ctx, valAddr1, orcAddr1)
+ }
+
+ { // add balance to bank
+ err = env.AddBalanceToBank(ctx, orcAddr1, sdk.Coins{balance})
+ require.NoError(t, err)
+ }
+
+ // create denom in keeper
+ gk.setCosmosOriginatedDenomToERC20(ctx, testDenom, "testcontractstring")
+
+ // setup for GetValidatorEthereumAddress
+ gk.setValidatorEthereumAddress(ctx, valAddr1, ethAddr1)
+
+ msgServer := NewMsgServerImpl(gk)
+
+ msg := &types.MsgSendToEthereum{
+ Sender: orcAddr1.String(),
+ EthereumRecipient: ethAddr1.String(),
+ Amount: amount,
+ BridgeFee: fee,
+ }
+
+ response, err := msgServer.SendToEthereum(sdk.WrapSDKContext(ctx), msg)
+ require.NoError(t, err)
+
+ cancelMsg := &types.MsgCancelSendToEthereum{
+ Id: response.Id,
+ Sender: orcAddr1.String(),
+ }
+ _, err = msgServer.CancelSendToEthereum(sdk.WrapSDKContext(ctx), cancelMsg)
+ require.NoError(t, err)
+}
+
+func TestMsgServer_RequestBatchTx(t *testing.T) {
+ var (
+ env = CreateTestEnv(t)
+ ctx = env.Context
+ gk = env.GravityKeeper
+
+ orcAddr1, _ = sdk.AccAddressFromBech32("cosmos1dg55rtevlfxh46w88yjpdd08sqhh5cc3xhkcej")
+ valAddr1 = sdk.ValAddress(orcAddr1)
+ //ethAddr1 = crypto.PubkeyToAddress(ethPrivKey.PublicKey)
+
+ orcAddr2, _ = sdk.AccAddressFromBech32("cosmos164knshrzuuurf05qxf3q5ewpfnwzl4gj4m4dfy")
+ valAddr2 = sdk.ValAddress(orcAddr2)
+
+ orcAddr3, _ = sdk.AccAddressFromBech32("cosmos193fw83ynn76328pty4yl7473vg9x86alq2cft7")
+ valAddr3 = sdk.ValAddress(orcAddr3)
+
+ testDenom = "stake"
+ )
+
+ { // setup for getSignerValidator
+ gk.StakingKeeper = NewStakingKeeperMock(valAddr1, valAddr2, valAddr3)
+ gk.SetOrchestratorValidatorAddress(ctx, valAddr1, orcAddr1)
+ }
+
+ // create denom in keeper
+ gk.setCosmosOriginatedDenomToERC20(ctx, testDenom, "testcontractstring")
+
+ msgServer := NewMsgServerImpl(gk)
+
+ msg := &types.MsgRequestBatchTx{
+ Signer: orcAddr1.String(),
+ Denom: testDenom,
+ }
+
+ _, err := msgServer.RequestBatchTx(sdk.WrapSDKContext(ctx), msg)
+ require.NoError(t, err)
+}
+
+func TestMsgServer_SubmitEthereumEvent(t *testing.T) {
+ ethPrivKey, err := ethCrypto.GenerateKey()
+ require.NoError(t, err)
+
+ var (
+ env = CreateTestEnv(t)
+ ctx = env.Context
+ gk = env.GravityKeeper
+
+ orcAddr1, _ = sdk.AccAddressFromBech32("cosmos1dg55rtevlfxh46w88yjpdd08sqhh5cc3xhkcej")
+ valAddr1 = sdk.ValAddress(orcAddr1)
+ ethAddr1 = crypto.PubkeyToAddress(ethPrivKey.PublicKey)
+
+ orcAddr2, _ = sdk.AccAddressFromBech32("cosmos164knshrzuuurf05qxf3q5ewpfnwzl4gj4m4dfy")
+ valAddr2 = sdk.ValAddress(orcAddr2)
+
+ orcAddr3, _ = sdk.AccAddressFromBech32("cosmos193fw83ynn76328pty4yl7473vg9x86alq2cft7")
+ valAddr3 = sdk.ValAddress(orcAddr3)
+ )
+
+ { // setup for getSignerValidator
+ gk.StakingKeeper = NewStakingKeeperMock(valAddr1, valAddr2, valAddr3)
+ gk.SetOrchestratorValidatorAddress(ctx, valAddr1, orcAddr1)
+ gk.SetOrchestratorValidatorAddress(ctx, valAddr2, orcAddr2)
+ gk.SetOrchestratorValidatorAddress(ctx, valAddr3, orcAddr3)
+ }
+
+ // setup for GetValidatorEthereumAddress
+ gk.setValidatorEthereumAddress(ctx, valAddr1, ethAddr1)
+
+ sendToCosmosEvent := &types.SendToCosmosEvent{
+ EventNonce: 1,
+ TokenContract: "test-token-contract-string",
+ Amount: sdk.NewInt(1000),
+ EthereumSender: ethAddr1.String(),
+ CosmosReceiver: orcAddr1.String(),
+ EthereumHeight: 200,
+ }
+
+ event, err := types.PackEvent(sendToCosmosEvent)
+ require.NoError(t, err)
+
+ msgServer := NewMsgServerImpl(gk)
+
+ msg := &types.MsgSubmitEthereumEvent{
+ Event: event,
+ Signer: orcAddr1.String(),
+ }
+
+ _, err = msgServer.SubmitEthereumEvent(sdk.WrapSDKContext(ctx), msg)
+ require.NoError(t, err)
+}
+
+func TestMsgServer_SetDelegateKeys(t *testing.T) {
+ ethPrivKey, err := ethCrypto.GenerateKey()
+ require.NoError(t, err)
+
+ var (
+ env = CreateTestEnv(t)
+ ctx = env.Context
+ gk = env.GravityKeeper
+ orcAddr1, _ = sdk.AccAddressFromBech32("cosmos1dg55rtevlfxh46w88yjpdd08sqhh5cc3xhkcej")
+ valAddr1 = sdk.ValAddress(orcAddr1)
+ ethAddr1 = crypto.PubkeyToAddress(ethPrivKey.PublicKey)
+ )
+
+ // setup for getSignerValidator
+ gk.StakingKeeper = NewStakingKeeperMock(valAddr1)
+
+ // Set the sequence to 1 because the antehandler will do this in the full
+ // chain.
+ acc := env.AccountKeeper.NewAccountWithAddress(ctx, orcAddr1)
+ acc.SetSequence(1)
+ env.AccountKeeper.SetAccount(ctx, acc)
+
+ msgServer := NewMsgServerImpl(gk)
+
+ ethMsg := types.DelegateKeysSignMsg{
+ ValidatorAddress: valAddr1.String(),
+ Nonce: 0,
+ }
+ signMsgBz := env.Marshaler.MustMarshal(ðMsg)
+ hash := crypto.Keccak256Hash(signMsgBz).Bytes()
+
+ sig, err := types.NewEthereumSignature(hash, ethPrivKey)
+ require.NoError(t, err)
+
+ msg := &types.MsgDelegateKeys{
+ ValidatorAddress: valAddr1.String(),
+ OrchestratorAddress: orcAddr1.String(),
+ EthereumAddress: ethAddr1.String(),
+ EthSignature: sig,
+ }
+
+ _, err = msgServer.SetDelegateKeys(sdk.WrapSDKContext(ctx), msg)
+ require.NoError(t, err)
+}
+
+func TestEthVerify(t *testing.T) {
+ // Replace privKeyHexStr and addrHexStr with your own private key and address
+ // HEX values.
+ privKeyHexStr := "0xee63225c8a0928168d362147cd19859de6459e972ffcf9294a69382b4ad99720"
+ addrHexStr := "0xA093773C30Ad5c3e83B20E66CB4e6136aEa098B7"
+
+ // ==========================================================================
+ // setup
+ // ==========================================================================
+ privKeyBz, err := hexutil.Decode(privKeyHexStr)
+ require.NoError(t, err)
+
+ privKey, err := crypto.ToECDSA(privKeyBz)
+ require.NoError(t, err)
+ require.NotNil(t, privKey)
+
+ require.True(t, bytes.Equal(privKeyBz, crypto.FromECDSA(privKey)))
+ require.Equal(t, privKeyHexStr, hexutil.Encode(crypto.FromECDSA(privKey)))
+
+ publicKey := privKey.Public()
+ publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
+ require.True(t, ok)
+
+ address := crypto.PubkeyToAddress(*publicKeyECDSA)
+ require.Equal(t, addrHexStr, address.Hex())
+
+ // ==========================================================================
+ // signature verification
+ // ==========================================================================
+ cdc := MakeTestMarshaler()
+
+ valAddr := "cosmosvaloper16k7rf90uvt4tgslqh280wvdzxp5q9ah6nxxupc"
+ signMsgBz, err := cdc.Marshal(&types.DelegateKeysSignMsg{
+ ValidatorAddress: valAddr,
+ Nonce: 0,
+ })
+
+ require.NoError(t, err)
+
+ fmt.Println("MESSAGE BYTES TO SIGN:", hexutil.Encode(signMsgBz))
+ hash := crypto.Keccak256Hash(signMsgBz).Bytes()
+
+ sig, err := types.NewEthereumSignature(hash, privKey)
+ sig[64] += 27 // change the V value
+ require.NoError(t, err)
+
+ err = types.ValidateEthereumSignature(hash, sig, address)
+ require.NoError(t, err)
+
+ // replace gorcSig with what the following command produces:
+ // $ gorc sign-delegate-keys cosmosvaloper1dmly9yyhd5lyhyl8qhs7wtcd4xt7gyxlesgvmc 0
+ gorcSig := "0xbda7037e448ca07ac91f5f386b72df37b6bbacf102b2c8f5acb58b5e053d68d96875ce9e442433bea55ac083230f492670ca2c07a8303c332dca06b1c0758c661b"
+ require.Equal(t, hexutil.Encode(sig), gorcSig)
+}
diff --git a/module/x/gravity/keeper/pool.go b/module/x/gravity/keeper/pool.go
new file mode 100644
index 0000000..18be9c6
--- /dev/null
+++ b/module/x/gravity/keeper/pool.go
@@ -0,0 +1,157 @@
+package keeper
+
+import (
+ "encoding/binary"
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/cosmos/cosmos-sdk/store/prefix"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+// createSendToEthereum
+// - checks a counterpart denominator exists for the given voucher type
+// - burns the voucher for transfer amount and fees
+// - persists an OutgoingTx
+// - adds the TX to the `available` TX pool via a second index
+func (k Keeper) createSendToEthereum(ctx sdk.Context, sender sdk.AccAddress, counterpartReceiver string, amount sdk.Coin, fee sdk.Coin) (uint64, error) {
+ totalAmount := amount.Add(fee)
+ totalInVouchers := sdk.Coins{totalAmount}
+
+ // If the coin is a gravity voucher, burn the coins. If not, check if there is a deployed ERC20 contract representing it.
+ // If there is, lock the coins.
+
+ isCosmosOriginated, tokenContract, err := k.DenomToERC20Lookup(ctx, totalAmount.Denom)
+ if err != nil {
+ return 0, err
+ }
+
+ if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, totalInVouchers); err != nil {
+ return 0, err
+ }
+
+ // If it is no a cosmos-originated asset we burn
+ if !isCosmosOriginated {
+ if err := k.bankKeeper.BurnCoins(ctx, types.ModuleName, totalInVouchers); err != nil {
+ panic(err)
+ }
+ }
+
+ // get next tx id from keeper
+ nextID := k.incrementLastSendToEthereumIDKey(ctx)
+
+ // construct outgoing tx, as part of this process we represent
+ // the token as an ERC20 token since it is preparing to go to ETH
+ // rather than the denom that is the input to this function.
+
+ // set the outgoing tx in the pool index
+ k.setUnbatchedSendToEthereum(ctx, &types.SendToEthereum{
+ Id: nextID,
+ Sender: sender.String(),
+ EthereumRecipient: counterpartReceiver,
+ Erc20Token: types.NewSDKIntERC20Token(amount.Amount, tokenContract),
+ Erc20Fee: types.NewSDKIntERC20Token(fee.Amount, tokenContract),
+ })
+
+ return nextID, nil
+}
+
+// cancelSendToEthereum
+// - checks that the provided tx actually exists
+// - deletes the unbatched tx from the pool
+// - issues the tokens back to the sender
+func (k Keeper) cancelSendToEthereum(ctx sdk.Context, id uint64, s string) error {
+ sender, _ := sdk.AccAddressFromBech32(s)
+
+ var send *types.SendToEthereum
+ for _, ste := range k.getUnbatchedSendToEthereums(ctx) {
+ if ste.Id == id {
+ send = ste
+ }
+ }
+ if send == nil {
+ // NOTE: this case will also be hit if the transaction is in a batch
+ return sdkerrors.Wrap(types.ErrInvalid, "id not found in send to ethereum pool")
+ }
+
+ if sender.String() != send.Sender {
+ return fmt.Errorf("can't cancel a message you didn't send")
+ }
+
+ totalToRefund := send.Erc20Token.GravityCoin()
+ totalToRefund.Amount = totalToRefund.Amount.Add(send.Erc20Fee.Amount)
+ totalToRefundCoins := sdk.NewCoins(totalToRefund)
+ isCosmosOriginated, _ := k.ERC20ToDenomLookup(ctx, send.Erc20Token.Contract)
+
+ // If it is not cosmos-originated the coins are minted
+ if !isCosmosOriginated {
+ if err := k.bankKeeper.MintCoins(ctx, types.ModuleName, totalToRefundCoins); err != nil {
+ return sdkerrors.Wrapf(err, "mint vouchers coins: %s", totalToRefundCoins)
+ }
+ }
+
+ if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sender, totalToRefundCoins); err != nil {
+ return sdkerrors.Wrap(err, "sending coins from module account")
+ }
+
+ k.deleteUnbatchedSendToEthereum(ctx, send.Id, send.Erc20Fee)
+ return nil
+}
+
+func (k Keeper) setUnbatchedSendToEthereum(ctx sdk.Context, ste *types.SendToEthereum) {
+ ctx.KVStore(k.storeKey).Set(types.MakeSendToEthereumKey(ste.Id, ste.Erc20Fee), k.cdc.MustMarshal(ste))
+}
+
+func (k Keeper) deleteUnbatchedSendToEthereum(ctx sdk.Context, id uint64, fee types.ERC20Token) {
+ ctx.KVStore(k.storeKey).Delete(types.MakeSendToEthereumKey(id, fee))
+}
+
+func (k Keeper) iterateUnbatchedSendToEthereumsByContract(ctx sdk.Context, contract common.Address, cb func(*types.SendToEthereum) bool) {
+ iter := prefix.NewStore(ctx.KVStore(k.storeKey), append([]byte{types.SendToEthereumKey}, contract.Bytes()...)).ReverseIterator(nil, nil)
+ defer iter.Close()
+ for ; iter.Valid(); iter.Next() {
+ var ste types.SendToEthereum
+ k.cdc.MustUnmarshal(iter.Value(), &ste)
+ if cb(&ste) {
+ break
+ }
+ }
+}
+
+func (k Keeper) IterateUnbatchedSendToEthereums(ctx sdk.Context, cb func(*types.SendToEthereum) bool) {
+ iter := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{types.SendToEthereumKey}).ReverseIterator(nil, nil)
+ defer iter.Close()
+ for ; iter.Valid(); iter.Next() {
+ var ste types.SendToEthereum
+ k.cdc.MustUnmarshal(iter.Value(), &ste)
+ if cb(&ste) {
+ break
+ }
+ }
+}
+
+func (k Keeper) getUnbatchedSendToEthereums(ctx sdk.Context) []*types.SendToEthereum {
+ var out []*types.SendToEthereum
+ k.IterateUnbatchedSendToEthereums(ctx, func(ste *types.SendToEthereum) bool {
+ out = append(out, ste)
+ return false
+ })
+ return out
+}
+
+func (k Keeper) incrementLastSendToEthereumIDKey(ctx sdk.Context) uint64 {
+ store := ctx.KVStore(k.storeKey)
+ bz := store.Get([]byte{types.LastSendToEthereumIDKey})
+ var id uint64 = 0
+ if bz != nil {
+ id = binary.BigEndian.Uint64(bz)
+ }
+ newId := id + 1
+ bz = sdk.Uint64ToBigEndian(newId)
+ store.Set([]byte{types.LastSendToEthereumIDKey}, bz)
+ return newId
+}
diff --git a/module/x/gravity/keeper/pool_test.go b/module/x/gravity/keeper/pool_test.go
new file mode 100644
index 0000000..154e455
--- /dev/null
+++ b/module/x/gravity/keeper/pool_test.go
@@ -0,0 +1,53 @@
+package keeper
+
+import (
+ "testing"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/require"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+func TestAddToOutgoingPool(t *testing.T) {
+ input := CreateTestEnv(t)
+ ctx := input.Context
+ var (
+ mySender, _ = sdk.AccAddressFromBech32("cosmos1ahx7f8wyertuus9r20284ej0asrs085case3kn")
+ myReceiver = common.HexToAddress("0xd041c41EA1bf0F006ADBb6d2c9ef9D425dE5eaD7")
+ myTokenContractAddr = common.HexToAddress("0x429881672B9AE42b8EbA0E26cD9C73711b891Ca5")
+ )
+ // mint some voucher first
+ allVouchers := sdk.Coins{types.NewERC20Token(99999, myTokenContractAddr.Hex()).GravityCoin()}
+ err := input.BankKeeper.MintCoins(ctx, types.ModuleName, allVouchers)
+ require.NoError(t, err)
+
+ // set senders balance
+ input.AccountKeeper.NewAccountWithAddress(ctx, mySender)
+ require.NoError(t, fundAccount(ctx, input.BankKeeper, mySender, allVouchers))
+
+ // when
+ input.AddSendToEthTxsToPool(t, ctx, myTokenContractAddr, mySender, myReceiver, 2, 3, 2, 1)
+
+ // then
+ var got []*types.SendToEthereum
+ input.GravityKeeper.IterateUnbatchedSendToEthereums(ctx, func(tx *types.SendToEthereum) bool {
+ got = append(got, tx)
+ return false
+ })
+
+ exp := []*types.SendToEthereum{
+ types.NewSendToEthereumTx(2, myTokenContractAddr, mySender, myReceiver, 101, 3),
+ types.NewSendToEthereumTx(3, myTokenContractAddr, mySender, myReceiver, 102, 2),
+ types.NewSendToEthereumTx(1, myTokenContractAddr, mySender, myReceiver, 100, 2),
+ types.NewSendToEthereumTx(4, myTokenContractAddr, mySender, myReceiver, 103, 1),
+ }
+
+ require.Equal(t, exp, got)
+ require.EqualValues(t, exp[0], got[0])
+ require.EqualValues(t, exp[1], got[1])
+ require.EqualValues(t, exp[2], got[2])
+ require.EqualValues(t, exp[3], got[3])
+ require.Len(t, got, 4)
+}
diff --git a/module/x/gravity/keeper/test_common.go b/module/x/gravity/keeper/test_common.go
new file mode 100644
index 0000000..2ac4ea8
--- /dev/null
+++ b/module/x/gravity/keeper/test_common.go
@@ -0,0 +1,724 @@
+package keeper
+
+import (
+ "bytes"
+ "testing"
+ "time"
+
+ "github.com/cosmos/cosmos-sdk/baseapp"
+ "github.com/cosmos/cosmos-sdk/codec"
+ codectypes "github.com/cosmos/cosmos-sdk/codec/types"
+ ccodec "github.com/cosmos/cosmos-sdk/crypto/codec"
+ "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
+ "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
+ ccrypto "github.com/cosmos/cosmos-sdk/crypto/types"
+ "github.com/cosmos/cosmos-sdk/std"
+ "github.com/cosmos/cosmos-sdk/store"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/cosmos/cosmos-sdk/types/module"
+ "github.com/cosmos/cosmos-sdk/x/auth"
+ authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
+ authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
+ "github.com/cosmos/cosmos-sdk/x/auth/vesting"
+ "github.com/cosmos/cosmos-sdk/x/bank"
+ bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
+ banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
+ "github.com/cosmos/cosmos-sdk/x/capability"
+ "github.com/cosmos/cosmos-sdk/x/crisis"
+ "github.com/cosmos/cosmos-sdk/x/distribution"
+ distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client"
+ distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
+ distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
+ "github.com/cosmos/cosmos-sdk/x/evidence"
+ "github.com/cosmos/cosmos-sdk/x/genutil"
+ "github.com/cosmos/cosmos-sdk/x/gov"
+ govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
+ govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
+ "github.com/cosmos/cosmos-sdk/x/mint"
+ "github.com/cosmos/cosmos-sdk/x/params"
+ paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
+ paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
+ paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
+ paramsproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
+ "github.com/cosmos/cosmos-sdk/x/slashing"
+ slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
+ slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
+ "github.com/cosmos/cosmos-sdk/x/staking"
+ stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+ "github.com/cosmos/cosmos-sdk/x/upgrade"
+ upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
+ gethcommon "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/libs/log"
+ tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
+ dbm "github.com/tendermint/tm-db"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+var (
+ // ModuleBasics is a mock module basic manager for testing
+ ModuleBasics = module.NewBasicManager(
+ auth.AppModuleBasic{},
+ genutil.AppModuleBasic{},
+ bank.AppModuleBasic{},
+ capability.AppModuleBasic{},
+ staking.AppModuleBasic{},
+ mint.AppModuleBasic{},
+ distribution.AppModuleBasic{},
+ gov.NewAppModuleBasic(
+ paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler,
+ ),
+ params.AppModuleBasic{},
+ crisis.AppModuleBasic{},
+ slashing.AppModuleBasic{},
+ upgrade.AppModuleBasic{},
+ evidence.AppModuleBasic{},
+ vesting.AppModuleBasic{},
+ )
+
+ // Ensure that StakingKeeperMock implements required interface
+ _ types.StakingKeeper = &StakingKeeperMock{}
+)
+
+var (
+ // ConsPrivKeys generate ed25519 ConsPrivKeys to be used for validator operator keys
+ ConsPrivKeys = []ccrypto.PrivKey{
+ ed25519.GenPrivKey(),
+ ed25519.GenPrivKey(),
+ ed25519.GenPrivKey(),
+ ed25519.GenPrivKey(),
+ ed25519.GenPrivKey(),
+ }
+
+ // ConsPubKeys holds the consensus public keys to be used for validator operator keys
+ ConsPubKeys = []ccrypto.PubKey{
+ ConsPrivKeys[0].PubKey(),
+ ConsPrivKeys[1].PubKey(),
+ ConsPrivKeys[2].PubKey(),
+ ConsPrivKeys[3].PubKey(),
+ ConsPrivKeys[4].PubKey(),
+ }
+
+ // AccPrivKeys generate secp256k1 pubkeys to be used for account pub keys
+ AccPrivKeys = []ccrypto.PrivKey{
+ secp256k1.GenPrivKey(),
+ secp256k1.GenPrivKey(),
+ secp256k1.GenPrivKey(),
+ secp256k1.GenPrivKey(),
+ secp256k1.GenPrivKey(),
+ }
+
+ // AccPubKeys holds the pub keys for the account keys
+ AccPubKeys = []ccrypto.PubKey{
+ AccPrivKeys[0].PubKey(),
+ AccPrivKeys[1].PubKey(),
+ AccPrivKeys[2].PubKey(),
+ AccPrivKeys[3].PubKey(),
+ AccPrivKeys[4].PubKey(),
+ }
+
+ // AccAddrs holds the sdk.AccAddresses
+ AccAddrs = []sdk.AccAddress{
+ sdk.AccAddress(AccPubKeys[0].Address()),
+ sdk.AccAddress(AccPubKeys[1].Address()),
+ sdk.AccAddress(AccPubKeys[2].Address()),
+ sdk.AccAddress(AccPubKeys[3].Address()),
+ sdk.AccAddress(AccPubKeys[4].Address()),
+ }
+
+ // ValAddrs holds the sdk.ValAddresses
+ ValAddrs = []sdk.ValAddress{
+ sdk.ValAddress(AccPubKeys[0].Address()),
+ sdk.ValAddress(AccPubKeys[1].Address()),
+ sdk.ValAddress(AccPubKeys[2].Address()),
+ sdk.ValAddress(AccPubKeys[3].Address()),
+ sdk.ValAddress(AccPubKeys[4].Address()),
+ }
+
+ // TODO: generate the eth priv keys here and
+ // derive the address from them.
+
+ // EthAddrs holds etheruem addresses
+ EthAddrs = []gethcommon.Address{
+ gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(1)}, 20)),
+ gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(2)}, 20)),
+ gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(3)}, 20)),
+ gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(4)}, 20)),
+ gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(5)}, 20)),
+ }
+
+ // TokenContractAddrs holds example token contract addresses
+ TokenContractAddrs = []string{
+ "0x6b175474e89094c44da98b954eedeac495271d0f", // DAI
+ "0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e", // YFI
+ "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", // UNI
+ "0xc00e94cb662c3520282e6f5717214004a7f26888", // COMP
+ "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f", // SNX
+ }
+
+ // InitTokens holds the number of tokens to initialize an account with
+ InitTokens = sdk.TokensFromConsensusPower(110, sdk.DefaultPowerReduction)
+
+ // InitCoins holds the number of coins to initialize an account with
+ InitCoins = sdk.NewCoins(sdk.NewCoin(TestingStakeParams.BondDenom, InitTokens))
+
+ // StakingAmount holds the staking power to start a validator with
+ StakingAmount = sdk.TokensFromConsensusPower(10, sdk.DefaultPowerReduction)
+
+ // StakingCoins holds the staking coins to start a validator with
+ StakingCoins = sdk.NewCoins(sdk.NewCoin(TestingStakeParams.BondDenom, StakingAmount))
+
+ // TestingStakeParams is a set of staking params for testing
+ TestingStakeParams = stakingtypes.Params{
+ UnbondingTime: 100,
+ MaxValidators: 10,
+ MaxEntries: 10,
+ HistoricalEntries: 10000,
+ BondDenom: "stake",
+ }
+
+ // TestingGravityParams is a set of gravity params for testing
+ TestingGravityParams = types.Params{
+ GravityId: "testgravityid",
+ ContractSourceHash: "62328f7bc12efb28f86111d08c29b39285680a906ea0e524e0209d6f6657b713",
+ BridgeEthereumAddress: "0x8858eeb3dfffa017d4bce9801d340d36cf895ccf",
+ BridgeChainId: 11,
+ SignedBatchesWindow: 10,
+ SignedSignerSetTxsWindow: 10,
+ UnbondSlashingSignerSetTxsWindow: 15,
+ EthereumSignaturesWindow: 10,
+ TargetEthTxTimeout: 60001,
+ AverageBlockTime: 5000,
+ AverageEthereumBlockTime: 15000,
+ SlashFractionSignerSetTx: sdk.NewDecWithPrec(1, 2),
+ SlashFractionBatch: sdk.NewDecWithPrec(1, 2),
+ SlashFractionEthereumSignature: sdk.NewDecWithPrec(1, 2),
+ SlashFractionConflictingEthereumSignature: sdk.NewDecWithPrec(1, 2),
+ }
+)
+
+// TestInput stores the various keepers required to test gravity
+type TestInput struct {
+ GravityKeeper Keeper
+ AccountKeeper authkeeper.AccountKeeper
+ StakingKeeper stakingkeeper.Keeper
+ SlashingKeeper slashingkeeper.Keeper
+ DistKeeper distrkeeper.Keeper
+ BankKeeper bankkeeper.BaseKeeper
+ GovKeeper govkeeper.Keeper
+ Context sdk.Context
+ Marshaler codec.Codec
+ LegacyAmino *codec.LegacyAmino
+}
+
+func (input TestInput) AddSendToEthTxsToPool(t *testing.T, ctx sdk.Context, tokenContract gethcommon.Address, sender sdk.AccAddress, receiver gethcommon.Address, ids ...uint64) {
+ for i, id := range ids {
+ amount := types.NewERC20Token(uint64(i+100), tokenContract.Hex()).GravityCoin()
+ fee := types.NewERC20Token(id, tokenContract.Hex()).GravityCoin()
+ _, err := input.GravityKeeper.createSendToEthereum(ctx, sender, receiver.Hex(), amount, fee)
+ require.NoError(t, err)
+ }
+}
+
+func (input TestInput) AddBalanceToBank(ctx sdk.Context, addr sdk.AccAddress, balances sdk.Coins) error {
+ return fundAccount(ctx, input.BankKeeper, addr, balances)
+}
+
+// SetupFiveValChain does all the initialization for a 5 Validator chain using the keys here
+func SetupFiveValChain(t *testing.T) (TestInput, sdk.Context) {
+ t.Helper()
+ input := CreateTestEnv(t)
+
+ // Set the params for our modules
+ input.StakingKeeper.SetParams(input.Context, TestingStakeParams)
+
+ // Initialize each of the validators
+ sh := staking.NewHandler(input.StakingKeeper)
+ for i := range []int{0, 1, 2, 3, 4} {
+
+ // Initialize the account for the key
+ acc := input.AccountKeeper.NewAccount(
+ input.Context,
+ authtypes.NewBaseAccount(AccAddrs[i], AccPubKeys[i], uint64(i), 0),
+ )
+
+ // Set the balance for the account
+ require.NoError(t, fundAccount(input.Context, input.BankKeeper, acc.GetAddress(), InitCoins))
+
+ // Set the account in state
+ input.AccountKeeper.SetAccount(input.Context, acc)
+
+ // Create a validator for that account using some of the tokens in the account
+ // and the staking handler
+ _, err := sh(
+ input.Context,
+ NewTestMsgCreateValidator(ValAddrs[i], ConsPubKeys[i], StakingAmount),
+ )
+
+ // Return error if one exists
+ require.NoError(t, err)
+ }
+
+ // Run the staking endblocker to ensure valset is correct in state
+ staking.EndBlocker(input.Context, input.StakingKeeper)
+
+ // Register eth addresses for each validator
+ for i, addr := range ValAddrs {
+ input.GravityKeeper.setValidatorEthereumAddress(input.Context, addr, EthAddrs[i])
+ input.GravityKeeper.SetOrchestratorValidatorAddress(input.Context, addr, AccAddrs[i])
+ input.GravityKeeper.setEthereumOrchestratorAddress(input.Context, EthAddrs[i], AccAddrs[i])
+ }
+
+ // Return the test input
+ return input, input.Context
+}
+
+// CreateTestEnv creates the keeper testing environment for gravity
+func CreateTestEnv(t *testing.T) TestInput {
+ t.Helper()
+
+ // Initialize store keys
+ gravityKey := sdk.NewKVStoreKey(types.StoreKey)
+ keyAcc := sdk.NewKVStoreKey(authtypes.StoreKey)
+ keyStaking := sdk.NewKVStoreKey(stakingtypes.StoreKey)
+ keyBank := sdk.NewKVStoreKey(banktypes.StoreKey)
+ keyDistro := sdk.NewKVStoreKey(distrtypes.StoreKey)
+ keyParams := sdk.NewKVStoreKey(paramstypes.StoreKey)
+ tkeyParams := sdk.NewTransientStoreKey(paramstypes.TStoreKey)
+ keyGov := sdk.NewKVStoreKey(govtypes.StoreKey)
+ keySlashing := sdk.NewKVStoreKey(slashingtypes.StoreKey)
+
+ // Initialize memory database and mount stores on it
+ db := dbm.NewMemDB()
+ ms := store.NewCommitMultiStore(db)
+ ms.MountStoreWithDB(gravityKey, sdk.StoreTypeIAVL, db)
+ ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
+ ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
+ ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db)
+ ms.MountStoreWithDB(keyBank, sdk.StoreTypeIAVL, db)
+ ms.MountStoreWithDB(keyDistro, sdk.StoreTypeIAVL, db)
+ ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
+ ms.MountStoreWithDB(keyGov, sdk.StoreTypeIAVL, db)
+ ms.MountStoreWithDB(keySlashing, sdk.StoreTypeIAVL, db)
+ err := ms.LoadLatestVersion()
+ require.Nil(t, err)
+
+ // Create sdk.Context
+ ctx := sdk.NewContext(ms, tmproto.Header{
+ Height: 1234567,
+ Time: time.Date(2020, time.April, 22, 12, 0, 0, 0, time.UTC),
+ }, false, log.TestingLogger())
+
+ cdc := MakeTestCodec()
+ marshaler := MakeTestMarshaler()
+
+ paramsKeeper := paramskeeper.NewKeeper(marshaler, cdc, keyParams, tkeyParams)
+ paramsKeeper.Subspace(authtypes.ModuleName)
+ paramsKeeper.Subspace(banktypes.ModuleName)
+ paramsKeeper.Subspace(stakingtypes.ModuleName)
+ paramsKeeper.Subspace(distrtypes.ModuleName)
+ paramsKeeper.Subspace(govtypes.ModuleName)
+ paramsKeeper.Subspace(types.DefaultParamspace)
+ paramsKeeper.Subspace(slashingtypes.ModuleName)
+
+ // this is also used to initialize module accounts for all the map keys
+ maccPerms := map[string][]string{
+ authtypes.FeeCollectorName: nil,
+ distrtypes.ModuleName: nil,
+ stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
+ stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
+ govtypes.ModuleName: {authtypes.Burner},
+ types.ModuleName: {authtypes.Minter, authtypes.Burner},
+ }
+
+ accountKeeper := authkeeper.NewAccountKeeper(
+ marshaler,
+ keyAcc, // target store
+ getSubspace(paramsKeeper, authtypes.ModuleName),
+ authtypes.ProtoBaseAccount, // prototype
+ maccPerms,
+ )
+
+ blockedAddr := make(map[string]bool, len(maccPerms))
+ for acc := range maccPerms {
+ blockedAddr[authtypes.NewModuleAddress(acc).String()] = true
+ }
+
+ bankKeeper := bankkeeper.NewBaseKeeper(
+ marshaler,
+ keyBank,
+ accountKeeper,
+ getSubspace(paramsKeeper, banktypes.ModuleName),
+ blockedAddr,
+ )
+ bankKeeper.SetParams(ctx, banktypes.Params{DefaultSendEnabled: true})
+
+ stakingKeeper := stakingkeeper.NewKeeper(marshaler, keyStaking, accountKeeper, bankKeeper, getSubspace(paramsKeeper, stakingtypes.ModuleName))
+ stakingKeeper.SetParams(ctx, TestingStakeParams)
+
+ distKeeper := distrkeeper.NewKeeper(marshaler, keyDistro, getSubspace(paramsKeeper, distrtypes.ModuleName), accountKeeper, bankKeeper, stakingKeeper, authtypes.FeeCollectorName, nil)
+ distKeeper.SetParams(ctx, distrtypes.DefaultParams())
+
+ // set genesis items required for distribution
+ distKeeper.SetFeePool(ctx, distrtypes.InitialFeePool())
+
+ // total supply to track this
+ totalSupply := sdk.NewCoins(sdk.NewInt64Coin("stake", 100000000))
+
+ // set up initial accounts
+ for name, perms := range maccPerms {
+ mod := authtypes.NewEmptyModuleAccount(name, perms...)
+ if name == stakingtypes.NotBondedPoolName {
+ require.NoError(t, fundModAccount(ctx, bankKeeper, mod.GetName(), totalSupply))
+ } else if name == distrtypes.ModuleName {
+ // some big pot to pay out
+ amt := sdk.NewCoins(sdk.NewInt64Coin("stake", 500000))
+ require.NoError(t, fundModAccount(ctx, bankKeeper, mod.GetName(), amt))
+ }
+
+ accountKeeper.SetModuleAccount(ctx, mod)
+ }
+
+ stakeAddr := authtypes.NewModuleAddress(stakingtypes.BondedPoolName)
+ moduleAcct := accountKeeper.GetAccount(ctx, stakeAddr)
+ require.NotNil(t, moduleAcct)
+
+ router := baseapp.NewRouter()
+ router.AddRoute(bank.AppModule{}.Route())
+ router.AddRoute(staking.AppModule{}.Route())
+ router.AddRoute(distribution.AppModule{}.Route())
+
+ // Load default wasm config
+
+ govRouter := govtypes.NewRouter().
+ AddRoute(paramsproposal.RouterKey, params.NewParamChangeProposalHandler(paramsKeeper)).
+ AddRoute(govtypes.RouterKey, govtypes.ProposalHandler)
+
+ govKeeper := govkeeper.NewKeeper(
+ marshaler, keyGov, getSubspace(paramsKeeper, govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable()), accountKeeper, bankKeeper, stakingKeeper, govRouter,
+ )
+
+ govKeeper.SetProposalID(ctx, govtypes.DefaultStartingProposalID)
+ govKeeper.SetDepositParams(ctx, govtypes.DefaultDepositParams())
+ govKeeper.SetVotingParams(ctx, govtypes.DefaultVotingParams())
+ govKeeper.SetTallyParams(ctx, govtypes.DefaultTallyParams())
+
+ slashingKeeper := slashingkeeper.NewKeeper(
+ marshaler,
+ keySlashing,
+ &stakingKeeper,
+ getSubspace(paramsKeeper, slashingtypes.ModuleName).WithKeyTable(slashingtypes.ParamKeyTable()),
+ )
+
+ k := NewKeeper(
+ marshaler,
+ gravityKey,
+ getSubspace(paramsKeeper, types.DefaultParamspace),
+ accountKeeper,
+ stakingKeeper,
+ bankKeeper,
+ slashingKeeper,
+ sdk.DefaultPowerReduction,
+ )
+
+ stakingKeeper = *stakingKeeper.SetHooks(
+ stakingtypes.NewMultiStakingHooks(
+ distKeeper.Hooks(),
+ slashingKeeper.Hooks(),
+ k.Hooks(),
+ ),
+ )
+
+ k.setParams(ctx, TestingGravityParams)
+
+ return TestInput{
+ GravityKeeper: k,
+ AccountKeeper: accountKeeper,
+ BankKeeper: bankKeeper,
+ StakingKeeper: stakingKeeper,
+ SlashingKeeper: slashingKeeper,
+ DistKeeper: distKeeper,
+ GovKeeper: govKeeper,
+ Context: ctx,
+ Marshaler: marshaler,
+ LegacyAmino: cdc,
+ }
+}
+
+// getSubspace returns a param subspace for a given module name.
+func getSubspace(k paramskeeper.Keeper, moduleName string) paramstypes.Subspace {
+ subspace, _ := k.GetSubspace(moduleName)
+ return subspace
+}
+
+// MakeTestCodec creates a legacy amino codec for testing
+func MakeTestCodec() *codec.LegacyAmino {
+ var cdc = codec.NewLegacyAmino()
+ auth.AppModuleBasic{}.RegisterLegacyAminoCodec(cdc)
+ bank.AppModuleBasic{}.RegisterLegacyAminoCodec(cdc)
+ staking.AppModuleBasic{}.RegisterLegacyAminoCodec(cdc)
+ distribution.AppModuleBasic{}.RegisterLegacyAminoCodec(cdc)
+ sdk.RegisterLegacyAminoCodec(cdc)
+ ccodec.RegisterCrypto(cdc)
+ params.AppModuleBasic{}.RegisterLegacyAminoCodec(cdc)
+ //types.RegisterCodec(cdc)
+ return cdc
+}
+
+// MakeTestMarshaler creates a proto codec for use in testing
+func MakeTestMarshaler() codec.Codec {
+ interfaceRegistry := codectypes.NewInterfaceRegistry()
+ std.RegisterInterfaces(interfaceRegistry)
+ ModuleBasics.RegisterInterfaces(interfaceRegistry)
+ types.RegisterInterfaces(interfaceRegistry)
+ return codec.NewProtoCodec(interfaceRegistry)
+}
+
+// MintVouchersFromAir creates new gravity vouchers given erc20tokens
+func MintVouchersFromAir(t *testing.T, ctx sdk.Context, k Keeper, dest sdk.AccAddress, amount types.ERC20Token) sdk.Coin {
+ coin := amount.GravityCoin()
+ vouchers := sdk.Coins{coin}
+ err := k.bankKeeper.MintCoins(ctx, types.ModuleName, vouchers)
+ require.NoError(t, err)
+ err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, dest, vouchers)
+ require.NoError(t, err)
+ return coin
+}
+
+// NewStakingKeeperMock creates a new mock staking keeper
+func NewStakingKeeperMock(operators ...sdk.ValAddress) *StakingKeeperMock {
+ r := &StakingKeeperMock{
+ BondedValidators: make([]stakingtypes.Validator, 0),
+ ValidatorPower: make(map[string]int64),
+ }
+ const defaultTestPower = 100
+ for _, a := range operators {
+
+ r.BondedValidators = append(r.BondedValidators, stakingtypes.Validator{
+ ConsensusPubkey: codectypes.UnsafePackAny(ed25519.GenPrivKey().PubKey()),
+ OperatorAddress: a.String(),
+ Status: stakingtypes.Bonded,
+ })
+ r.ValidatorPower[a.String()] = defaultTestPower
+ }
+ return r
+}
+
+// MockStakingValidatorData creates mock validator data
+type MockStakingValidatorData struct {
+ Operator sdk.ValAddress
+ Power int64
+}
+
+// NewStakingKeeperWeightedMock creates a new mock staking keeper with some mock validator data
+func NewStakingKeeperWeightedMock(t ...MockStakingValidatorData) *StakingKeeperMock {
+ r := &StakingKeeperMock{
+ BondedValidators: make([]stakingtypes.Validator, len(t)),
+ ValidatorPower: make(map[string]int64, len(t)),
+ }
+
+ for i, a := range t {
+ pk, err := codectypes.NewAnyWithValue(ed25519.GenPrivKey().PubKey())
+ if err != nil {
+ panic(err)
+ }
+ r.BondedValidators[i] = stakingtypes.Validator{
+ ConsensusPubkey: pk,
+ OperatorAddress: a.Operator.String(),
+ Status: stakingtypes.Bonded,
+ }
+ r.ValidatorPower[a.Operator.String()] = a.Power
+ }
+ return r
+}
+
+// StakingKeeperMock is a mock staking keeper for use in the tests
+type StakingKeeperMock struct {
+ BondedValidators []stakingtypes.Validator
+ ValidatorPower map[string]int64
+}
+
+// GetBondedValidatorsByPower implements the interface for staking keeper required by gravity
+func (s *StakingKeeperMock) GetBondedValidatorsByPower(ctx sdk.Context) []stakingtypes.Validator {
+ return s.BondedValidators
+}
+
+// GetLastValidatorPower implements the interface for staking keeper required by gravity
+func (s *StakingKeeperMock) GetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress) int64 {
+ v, ok := s.ValidatorPower[operator.String()]
+ if !ok {
+ panic("unknown address")
+ }
+ return v
+}
+
+// GetLastTotalPower implements the interface for staking keeper required by gravity
+func (s *StakingKeeperMock) GetLastTotalPower(ctx sdk.Context) (power sdk.Int) {
+ var total int64
+ for _, v := range s.ValidatorPower {
+ total += v
+ }
+ return sdk.NewInt(total)
+}
+
+// IterateValidators staisfies the interface
+func (s *StakingKeeperMock) IterateValidators(ctx sdk.Context, cb func(index int64, validator stakingtypes.ValidatorI) (stop bool)) {
+ for i, val := range s.BondedValidators {
+ stop := cb(int64(i), val)
+ if stop {
+ break
+ }
+ }
+}
+
+// IterateBondedValidatorsByPower staisfies the interface
+func (s *StakingKeeperMock) IterateBondedValidatorsByPower(ctx sdk.Context, cb func(index int64, validator stakingtypes.ValidatorI) (stop bool)) {
+ for i, val := range s.BondedValidators {
+ stop := cb(int64(i), val)
+ if stop {
+ break
+ }
+ }
+}
+
+// IterateLastValidators staisfies the interface
+func (s *StakingKeeperMock) IterateLastValidators(ctx sdk.Context, cb func(index int64, validator stakingtypes.ValidatorI) (stop bool)) {
+ for i, val := range s.BondedValidators {
+ stop := cb(int64(i), val)
+ if stop {
+ break
+ }
+ }
+}
+
+// Validator staisfies the interface
+func (s *StakingKeeperMock) Validator(ctx sdk.Context, addr sdk.ValAddress) stakingtypes.ValidatorI {
+ for _, val := range s.BondedValidators {
+ if val.GetOperator().Equals(addr) {
+ return val
+ }
+ }
+ return nil
+}
+
+// ValidatorByConsAddr staisfies the interface
+func (s *StakingKeeperMock) ValidatorByConsAddr(ctx sdk.Context, addr sdk.ConsAddress) stakingtypes.ValidatorI {
+ for _, val := range s.BondedValidators {
+ cons, err := val.GetConsAddr()
+ if err != nil {
+ panic(err)
+ }
+ if cons.Equals(addr) {
+ return val
+ }
+ }
+ return nil
+}
+
+func (s *StakingKeeperMock) GetParams(ctx sdk.Context) stakingtypes.Params {
+ return stakingtypes.DefaultParams()
+}
+
+func (s *StakingKeeperMock) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) {
+ panic("unexpected call")
+}
+
+func (s *StakingKeeperMock) ValidatorQueueIterator(ctx sdk.Context, endTime time.Time, endHeight int64) sdk.Iterator {
+ store := ctx.KVStore(sdk.NewKVStoreKey("staking"))
+ return store.Iterator(stakingtypes.ValidatorQueueKey, sdk.InclusiveEndBytes(stakingtypes.GetValidatorQueueKey(endTime, endHeight)))
+
+}
+
+// Slash staisfies the interface
+func (s *StakingKeeperMock) Slash(sdk.Context, sdk.ConsAddress, int64, int64, sdk.Dec) {}
+
+// Jail staisfies the interface
+func (s *StakingKeeperMock) Jail(sdk.Context, sdk.ConsAddress) {}
+
+// AlwaysPanicStakingMock is a mock staking keeper that panics on usage
+type AlwaysPanicStakingMock struct{}
+
+// GetLastTotalPower implements the interface for staking keeper required by gravity
+func (s AlwaysPanicStakingMock) GetLastTotalPower(ctx sdk.Context) (power sdk.Int) {
+ panic("unexpected call")
+}
+
+// GetBondedValidatorsByPower implements the interface for staking keeper required by gravity
+func (s AlwaysPanicStakingMock) GetBondedValidatorsByPower(ctx sdk.Context) []stakingtypes.Validator {
+ panic("unexpected call")
+}
+
+// GetLastValidatorPower implements the interface for staking keeper required by gravity
+func (s AlwaysPanicStakingMock) GetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress) int64 {
+ panic("unexpected call")
+}
+
+// IterateValidators staisfies the interface
+func (s AlwaysPanicStakingMock) IterateValidators(sdk.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool)) {
+ panic("unexpected call")
+}
+
+// IterateBondedValidatorsByPower staisfies the interface
+func (s AlwaysPanicStakingMock) IterateBondedValidatorsByPower(sdk.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool)) {
+ panic("unexpected call")
+}
+
+// IterateLastValidators staisfies the interface
+func (s AlwaysPanicStakingMock) IterateLastValidators(sdk.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool)) {
+ panic("unexpected call")
+}
+
+// Validator staisfies the interface
+func (s AlwaysPanicStakingMock) Validator(sdk.Context, sdk.ValAddress) stakingtypes.ValidatorI {
+ panic("unexpected call")
+}
+
+// ValidatorByConsAddr staisfies the interface
+func (s AlwaysPanicStakingMock) ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI {
+ panic("unexpected call")
+}
+
+// Slash staisfies the interface
+func (s AlwaysPanicStakingMock) Slash(sdk.Context, sdk.ConsAddress, int64, int64, sdk.Dec) {
+ panic("unexpected call")
+}
+
+// Jail staisfies the interface
+func (s AlwaysPanicStakingMock) Jail(sdk.Context, sdk.ConsAddress) {
+ panic("unexpected call")
+}
+
+func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey ccrypto.PubKey, amt sdk.Int) *stakingtypes.MsgCreateValidator {
+ commission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
+ out, err := stakingtypes.NewMsgCreateValidator(
+ address, pubKey, sdk.NewCoin("stake", amt),
+ stakingtypes.Description{}, commission, sdk.OneInt(),
+ )
+ if err != nil {
+ panic(err)
+ }
+ return out
+}
+
+func NewTestMsgUnDelegateValidator(address sdk.ValAddress, amt sdk.Int) *stakingtypes.MsgUndelegate {
+ msg := stakingtypes.NewMsgUndelegate(sdk.AccAddress(address), address, sdk.NewCoin("stake", amt))
+ return msg
+}
+
+func fundAccount(ctx sdk.Context, bankKeeper types.BankKeeper, addr sdk.AccAddress, amounts sdk.Coins) error {
+ if err := bankKeeper.MintCoins(ctx, types.ModuleName, amounts); err != nil {
+ return err
+ }
+
+ return bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, amounts)
+}
+
+func fundModAccount(ctx sdk.Context, bankKeeper types.BankKeeper, recipientMod string, amounts sdk.Coins) error {
+ if err := bankKeeper.MintCoins(ctx, types.ModuleName, amounts); err != nil {
+ return err
+ }
+
+ return bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, recipientMod, amounts)
+}
diff --git a/module/x/gravity/module.go b/module/x/gravity/module.go
new file mode 100644
index 0000000..90ef6b0
--- /dev/null
+++ b/module/x/gravity/module.go
@@ -0,0 +1,199 @@
+package gravity
+
+import (
+ "encoding/json"
+ "fmt"
+ "math/rand"
+
+ "github.com/gorilla/mux"
+ "github.com/grpc-ecosystem/grpc-gateway/runtime"
+ "github.com/spf13/cobra"
+
+ "github.com/cosmos/cosmos-sdk/client"
+ "github.com/cosmos/cosmos-sdk/codec"
+ codectypes "github.com/cosmos/cosmos-sdk/codec/types"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/cosmos/cosmos-sdk/types/module"
+ simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
+ bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
+ abci "github.com/tendermint/tendermint/abci/types"
+
+ "github.com/cosmos/gravity-bridge/module/x/gravity/client/cli"
+ // "github.com/cosmos/gravity-bridge/module/x/gravity/client/rest"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/keeper"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+// type check to ensure the interface is properly implemented
+var (
+ _ module.AppModule = AppModule{}
+ _ module.AppModuleBasic = AppModuleBasic{}
+)
+
+// AppModuleBasic object for module implementation
+type AppModuleBasic struct{}
+
+// Name implements app module basic
+func (AppModuleBasic) Name() string {
+ return types.ModuleName
+}
+
+// RegisterLegacyAminoCodec implements app module basic
+func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {}
+
+// DefaultGenesis implements app module basic
+func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
+ return cdc.MustMarshalJSON(types.DefaultGenesisState())
+}
+
+// ValidateGenesis implements app module basic
+func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error {
+ var data types.GenesisState
+ if err := cdc.UnmarshalJSON(bz, &data); err != nil {
+ return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
+ }
+
+ return data.ValidateBasic()
+}
+
+// RegisterRESTRoutes implements app module basic
+func (AppModuleBasic) RegisterRESTRoutes(ctx client.Context, rtr *mux.Router) {
+ // rest.RegisterRoutes(ctx, rtr, types.StoreKey)
+}
+
+// GetQueryCmd implements app module basic
+func (AppModuleBasic) GetQueryCmd() *cobra.Command {
+ return cli.GetQueryCmd()
+}
+
+// GetTxCmd implements app module basic
+func (AppModuleBasic) GetTxCmd() *cobra.Command {
+ return cli.GetTxCmd(types.StoreKey)
+}
+
+// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the distribution module.
+// also implements app modeul basic
+func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {}
+
+// RegisterInterfaces implements app bmodule basic
+func (b AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
+ types.RegisterInterfaces(registry)
+}
+
+//____________________________________________________________________________
+
+// AppModule object for module implementation
+type AppModule struct {
+ AppModuleBasic
+ keeper keeper.Keeper
+ bankKeeper bankkeeper.Keeper
+}
+
+// NewAppModule creates a new AppModule Object
+func NewAppModule(k keeper.Keeper, bankKeeper bankkeeper.Keeper) AppModule {
+ return AppModule{
+ AppModuleBasic: AppModuleBasic{},
+ keeper: k,
+ bankKeeper: bankKeeper,
+ }
+}
+
+// Name implements app module
+func (AppModule) Name() string {
+ return types.ModuleName
+}
+
+// ConsensusVersion implements AppModule/ConsensusVersion.
+func (AppModule) ConsensusVersion() uint64 {
+ return 1
+}
+
+// RegisterInvariants implements app module
+func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
+ // TODO: make some invariants in the gravity module to ensure that
+ // coins aren't being fraudlently minted etc...
+}
+
+// Route implements app module
+func (am AppModule) Route() sdk.Route {
+ return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper))
+}
+
+// QuerierRoute implements app module
+func (am AppModule) QuerierRoute() string {
+ return types.QuerierRoute
+}
+
+// LegacyQuerierHandler returns the distribution module sdk.Querier.
+func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
+ return nil
+}
+
+// RegisterServices registers module services.
+func (am AppModule) RegisterServices(cfg module.Configurator) {
+ types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
+ types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
+}
+
+// InitGenesis initializes the genesis state for this module and implements app module.
+func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
+ var genesisState types.GenesisState
+ cdc.MustUnmarshalJSON(data, &genesisState)
+ keeper.InitGenesis(ctx, am.keeper, genesisState)
+ return []abci.ValidatorUpdate{}
+}
+
+// ExportGenesis exports the current genesis state to a json.RawMessage
+func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
+ gs := keeper.ExportGenesis(ctx, am.keeper)
+ return cdc.MustMarshalJSON(&gs)
+}
+
+// BeginBlock implements app module
+func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
+ BeginBlocker(ctx, am.keeper)
+}
+
+// EndBlock implements app module
+func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
+ EndBlocker(ctx, am.keeper)
+ return []abci.ValidatorUpdate{}
+}
+
+//____________________________________________________________________________
+
+// AppModuleSimulation functions
+
+// GenerateGenesisState creates a randomized GenState of the distribution module.
+func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
+ // TODO: implement gravity simulation stuffs
+ // simulation.RandomizedGenState(simState)
+}
+
+// ProposalContents returns all the distribution content functions used to
+// simulate governance proposals.
+func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
+ // TODO: implement gravity simulation stuffs
+ return nil
+}
+
+// RandomizedParams creates randomized distribution param changes for the simulator.
+func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange {
+ // TODO: implement gravity simulation stuffs
+ return nil
+}
+
+// RegisterStoreDecoder registers a decoder for distribution module's types
+func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
+ // TODO: implement gravity simulation stuffs
+ // sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc)
+}
+
+// WeightedOperations returns the all the gov module operations with their respective weights.
+func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
+ // TODO: implement gravity simulation stuffs
+ // return simulation.WeightedOperations(
+ // simState.AppParams, simState.Cdc, am.accountKeeper, am.bankKeeper, am.keeper, am.stakingKeeper,
+ // )
+ return nil
+}
diff --git a/module/x/gravity/spec/01_definitions.md b/module/x/gravity/spec/01_definitions.md
new file mode 100644
index 0000000..6124682
--- /dev/null
+++ b/module/x/gravity/spec/01_definitions.md
@@ -0,0 +1,60 @@
+
+
+
+# Definitions
+
+This section outlines terminology used throughout the spec and code.
+
+### Operator
+
+This is a person (or people) who control a Cosmos SDK validator node. This is also called `valoper` or "Validator Operator" in the Cosmos SDK staking section
+
+### Counter Chain
+
+A chain that utilizes an EVM. Some examples of this are Polygon, Ethereum, and Ethereum Classic.
+
+### Relayer
+
+This is a type of node that submits updates to the Gravity contract on the counter chain and vice versa. It earns fees from the transactions in a batch.
+
+### Gravity Tx Pool
+
+Is a transaction pool that exists in the chain store of Cosmos -> Ethereum transactions waiting to be placed into a transaction batch
+
+### Transaction Batch
+
+A transaction batch is a set of Ethereum transactions to be sent from the Gravity Ethereum contract at the same time. This helps reduce the costs of submitting a batch. Batches have a maximum size (currently around 100 transactions) and are only involved in the Cosmos -> Ethereum flow
+
+### Gravity Batch Pool
+
+Is a transaction pool like structure that exists in the chains to store, separate from the `Gravity Tx Pool` it stores transactions that have been placed in batches that are in the process of being signed or being submitted by the `Orchestrator Set`
+
+### Observed
+
+Events on Ethereum are considered `Observed` when the `Eth Signers` of 66% of the active Cosmos validator set during a given block has submitted an oracle message attesting to seeing the event.
+
+### Validator Set Delta
+
+This is a term for the difference between the validator set currently in the Gravity Ethereum contract and the actual validator set on the Cosmos chain. Since the validator set may change every single block there is essentially guaranteed to be some nonzero `Validator set delta` at any given time.
+
+### Claim
+
+An Ethereum event signed and submitted to cosmos by a single `Orchestrator` instance.
+
+### Attestation
+
+Aggregate of claims that eventually becomes `observed` by all orchestrators.
+
+### Voucher
+
+Represents a bridged ETH token on the Cosmos side. Their denom is has a `gravity` prefix and a hash that is build from contract address and contract token. The denom is considered unique within the system.
+
+### Counterpart
+
+A `Voucher` which is the locked opposing chain token in the contract
+
+### Logic Calls
+
+A logic call refers to a created action for a smart contract interaction on the opposing chain.
diff --git a/module/x/gravity/spec/02_state.md b/module/x/gravity/spec/02_state.md
new file mode 100644
index 0000000..cd64d3a
--- /dev/null
+++ b/module/x/gravity/spec/02_state.md
@@ -0,0 +1,151 @@
+
+
+# State
+
+## Params
+
+Params is a module-wide configuration structure that stores system parameters
+and defines overall functioning of the staking module.
+
+- Params: `Paramsspace("gravity") -> legacy_amino(params)`
+
++++
+
+
+### BatchTx
+
+Stored in two possible ways, first with a height and second without (unsafe). Unsafe is used for testing and export and import of state.
+
+| key | Value | Type | Encoding |
+|--------------|-------|--------|------------------------|
+| `[]byte{0xa} + common.HexToAddress(tokenContract).Bytes() + nonce (big endian encoded)` | A batch of outgoing transactions | `types.BatchTx` | Protobuf encoded |
+
+### ValidatorSet
+
+This is the validator set of the bridge.
+
+Stored in two possible ways, first with a height and second without (unsafe). Unsafe is used for testing and export and import of state.
+
+| key | Value | Type | Encoding |
+|--------------|-------|--------|------------------------|
+| `[]byte{0x2} + nonce (big endian encoded)` | Validator set | `types.Valset` | Protobuf encoded |
+
+### ValsetNonce
+
+The latest validator set nonce, this value is updated on every write.
+
+| key | Value | Type | Encoding |
+|--------------|-------|--------|------------------------|
+| `[]byte{0xf6}` | Nonce | `uint64` | encoded via big endian |
+
+### SlashedValeSetNonce
+
+The latest validator set slash nonce. This is used to track which validator set needs to be slashed and which already has been.
+
+| Key | Value | Type | Encoding |
+|----------------|-------|--------|------------------------|
+| `[]byte{0xf5}` | Nonce | uint64 | encoded via big endian |
+
+### Validator Set Confirmation
+
+When a validator signs over a validator set this is considered a `valSetConfirmation`, these are saved via the current nonce and the orchestrator address.
+
+
+| Key | Value | Type | Encoding |
+|---------------------------------------------|------------------------|--------------------------|------------------|
+| `[]byte{0x3} + (nonce + []byte(AccAddress)` | Validator Confirmation | `types.MsgSubmitEthereumTxConfirmation` | Protobuf encoded |
+
+### ConfirmBatch
+
+When a validator confirms a batch it is added to the confirm batch store. It is stored using the orchestrator, token contract and nonce as the key.
+
+| Key | Value | Type | Encoding |
+|---------------------------------------------------------------------|------------------------------|-------------------------|------------------|
+| `[]byte{0xe1} + common.HexToAddress(tokenContract).Bytes() + nonce + []byte(AccAddress)` | Validator Batch Confirmation | `types.MsgConfirmBatch` | Protobuf encoded |
+
+### OrchestratorValidator
+
+When a validator would like to delegate their voting power to another key. The value is stored using the orchestrator address as the key
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0xe8} + []byte(AccAddress)` | Orchestrator address assigned by a validator | `[]byte` | Protobuf encoded |
+
+### EthAddress
+
+A validator has an associated counter chain address.
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0x1} + []byte(ValAddress)` | Ethereum address assigned by a validator | `[]byte` | Protobuf encoded |
+
+
+### ContractCallTx
+
+When a user requests a logic call to be executed on an opposing chain it is stored in a store within the gravity module.
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0xde} + []byte(invalidationId) + nonce (big endian encoded)` | A user created logic call to be sent to the counter chain | `types.ContractCallTx` | Protobuf encoded |
+
+### ConfirmLogicCall
+
+When a logic call is executed validators confirm the execution.
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+|`[]byte{0xae} + []byte(invalidationId) + nonce (big endian encoded) + []byte(AccAddress)` | Confirmation of execution of the logic call | `types.MsgConfirmLogicCall` | Protobuf encoded |
+
+### OutgoingTx
+
+Sets an outgoing transactions into the applications transaction pool to be included into a batch.
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0x6} + id (big endian encoded)` | User created transaction to be included in a batch | `types.OutgoingTx` | Protobuf encoded |
+
+### IDS
+
+### SlashedBlockHeight
+
+Represents the latest slashed block height. There is always only a singe value stored.
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0xf7}` | Latest height a batch slashing occurred | `uint64` | Big endian encoded |
+
+### TokenContract & Denom
+
+A denom that is originally from a counter chain will be from a contract. The toke contract and denom are stored in two ways. First, the denom is used as the key and the value is the token contract. Second, the contract is used as the key, the value is the denom the token contract represents.
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0xf3} + []byte(denom)` | Token contract address | `[]byte` | stored in byte format |
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0xf4} + common.HexToAddress(tokenContract).Bytes()` | Latest height a batch slashing occurred | `[]byte` | stored in byte format |
+
+### LastEventNonce
+
+The last observed event nonce. This is set when `TryAttestation()` is called. There is always only a single value held in this store.
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0xf2}` | Last observed event nonce| `uint64` | Big endian encoded |
+
+### LastObservedEthereumHeight
+
+This is the last observed height on ethereum. There will always only be a single value stored in this store.
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0xf9}` | Last observed Ethereum Height| `uint64` | Protobuf encoded |
+
+### Attestation
+
+| Key | Value | Type | Encoding |
+|-------------------------------------|----------------------------------------------|----------|------------------|
+| `[]byte{0x5} + evenNonce (big endian encoded) + []byte(claimHash)` | Attestation of occurred events/claims| `types.Attestation` | Protobuf encoded |
diff --git a/module/x/gravity/spec/03_state_transitions.md b/module/x/gravity/spec/03_state_transitions.md
new file mode 100644
index 0000000..e173181
--- /dev/null
+++ b/module/x/gravity/spec/03_state_transitions.md
@@ -0,0 +1,7 @@
+
+
+# State Transitions
+
+This document describes the state transition operations pertaining to:
diff --git a/module/x/gravity/spec/04_messages.md b/module/x/gravity/spec/04_messages.md
new file mode 100644
index 0000000..c8f04fc
--- /dev/null
+++ b/module/x/gravity/spec/04_messages.md
@@ -0,0 +1,164 @@
+
+
+# Messages
+
+In this section we describe the processing of the gravity messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state_transitions.md) section.
+
+### MsgDelegateKeys
+
+Allows validators to delegate their voting responsibilities to a given key. This Key can be used to authenticate oracle claims.
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L38-L40
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L56-60
+
+This message is expected to fail if:
+
+- The validator address is incorrect.
+ - The address is empty (`""`)
+ - Not a length of 20
+ - Bech32 decoding fails
+- The orchestrator address is incorrect.
+ - The address is empty (`""`)
+ - Not a length of 20
+ - Bech32 decoding fails
+- The ethereum address is incorrect.
+ - The address is empty (`""`)
+ - Not a length of 42
+ - Does not start with 0x
+- The validator is not present in the validator set.
+
+### MsgSubmitEthereumTxConfirmation
+
+When the gravity daemon witnesses a complete validator set within the gravity module, the validator submits a signature of a message containing the entire validator set.
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L79-84
+
+This message is expected to fail if:
+
+- If the validator set is not present.
+- The signature is encoded incorrectly.
+- Signature verification of the ethereum key fails.
+- If the signature submitted has already been submitted previously.
+- The validator address is incorrect.
+ - The address is empty (`""`)
+ - Not a length of 20
+ - Bech32 decoding fails
+
+
+### MsgSendToEthereum
+
+When a user wants to bridge an asset to an EVM. If the token has originated from the cosmos chain it will be held in a module account. If the token is originally from ethereum it will be burned on the cosmos side.
+
+> Note: this message will later be removed when it is included in a batch.
+
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L100-109
+
+This message will fail if:
+
+- The sender address is incorrect.
+ - The address is empty (`""`)
+ - Not a length of 20
+ - Bech32 decoding fails
+- The denom is not supported.
+- If the token is cosmos originated
+ - The sending of the token to the module account fails
+- If the token is non-cosmos-originated.
+ - If sending to the module account fails
+ - If burning of the token fails
+
+### MsgRequestBatchTx
+
+When enough transactions have been added into a batch, a user or validator can call send this message in order to send a batch of transactions across the bridge.
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L122-125
+
+This message will fail if:
+
+- The denom is not supported.
+- Failure to build a batch of transactions.
+- If the orchestrator address is not present in the validator set
+
+### MsgConfirmBatch
+
+When a `MsgRequestBatchTx` is observed, validators need to sign batch request to signify this is not a maliciously created batch and to avoid getting slashed.
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L137-143
+
+This message will fail if:
+
+- The batch does not exist
+- If checkpoint generation fails
+- If a none validator address or delegated address
+- If the counter chain address is empty or incorrect.
+- If counter chain address fails signature validation
+- If the signature was already presented in a previous message
+
+### MsgConfirmLogicCall
+
+When a logic call request has been made, it needs to be confirmed by the bridge validators. Each validator has to submit a confirmation of the logic call being executed.
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L155-161
+
+This message will fail if:
+
+- The id encoding is incorrect
+- The outgoing logic call which is confirmed can not be found
+- Invalid checkpoint generation
+- Signature decoding failed
+- The address calling this function is not a validator or its delegated key
+- The counter chain address is incorrect or empty
+- Counter party signature verification failed
+- A duplicate signature is observed
+
+### MsgDepositClaim
+
+When a message to deposit funds into the gravity contract is created a event will be omitted and observed a message will be submitted confirming the deposit.
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L170-181
+
+This message will fail if:
+
+- The validator is unknown
+- The validator is not in the active set
+- If the creation of attestation fails
+
+### MsgWithdrawClaim
+
+When a user requests a withdrawal from the gravity contract a event will omitted by the counter party chain. This event will be observed by a bridge validator and submitted to the gravity module.
+
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L187-193
+
+This message will fail if:
+
+- The validator is unknown
+- The validator is not in the active set
+- If the creation of attestation fails
+
+### MsgERC20DeployedClaim
+
+This message allows the cosmos chain to learn information about the denom from the counter party chain.
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L200-209
+
+This message will fail if:
+
+- The validator is unknown
+- The validator is not in the active set
+- If the creation of attestation fails
+
+### MsgLogicCallExecutedClaim
+
+This informs the chain that a logic call has been executed. This message is submitted by bridge validators when they observe a event containing details around the logic call.
+
++++ https://github.com/althea-net/cosmos-gravity-bridge/blob/main/module/proto/gravity/v1/msgs.proto#L215-221
+
+This message will fail if:
+
+- The validator submitting the claim is unknown
+- The validator is not in the active set
+- Creation of attestation has failed.
diff --git a/module/x/gravity/spec/05_end_block.md b/module/x/gravity/spec/05_end_block.md
new file mode 100644
index 0000000..f86075d
--- /dev/null
+++ b/module/x/gravity/spec/05_end_block.md
@@ -0,0 +1,38 @@
+
+
+# End-Block
+
+Each abci end block call, the operations to update queues and validator set
+changes are specified to execute.
+
+## Slashing
+
+Slashing groups multiple types of slashing (validator set, batch and claim slashing). We will cover how these work in the following sections.
+
+### Validator Slashing
+
+A validator is slashed for not signing over a validatorset. The Cosmos-SDK allows active validator sets to change from block to block, for this reason we need to store multiple validator sets within a single unbonding period. This allows validators to not be slashed.
+
+A validator will be slashed or missing a single confirmation signing.
+
+### Batch Slashing
+
+A validator is slashed for not signing over a batch request. A validator will be slashed for missing
+
+## Attestation
+
+Iterates through all attestations currently being voted on. Once an attestation nonce one higher than the previous one, we stop searching for an attestation and call `TryAttestation`. Once an attestation at a specific nonce has enough votes all the other attestations will be skipped and the `lastObservedEventNonce` incremented.
+
+## Cleanup
+
+Cleanup loops through batches and logic calls in order to clean up the timed out transactions.
+
+### Batches
+
+When a batch of transactions are created they have a specified height of the opposing chain for when the batch becomes invalid. When this happens we must remove them from the store. At the end of every block, we loop through the store of logic calls checking the the timeout heights.
+
+### Logic Calls
+
+When a logic call is created it consists of a timeout height. This height is used to know when the logic call becomes invalid. At the end of every block, we loop through the store of logic calls checking the the timeout heights.
diff --git a/module/x/gravity/spec/06_events.md b/module/x/gravity/spec/06_events.md
new file mode 100644
index 0000000..527225c
--- /dev/null
+++ b/module/x/gravity/spec/06_events.md
@@ -0,0 +1,134 @@
+
+
+# Events
+
+The gravity module emits the following events:
+
+## EndBlocker
+
+| Type | Attribute Key | Attribute Value |
+|------------------------------|-------------------------------|---------------------------------|
+| outgoing_logic_call_canceled | module | gravity |
+| outgoing_logic_call_canceled | logic_call_invalidation_id | {logic_call_invalidation_id} |
+| outgoing_logic_call_canceled | logic_call_invalidation_nonce | {logic_call_invalidation_nonce} |
+
+| Type | Attribute Key | Attribute Value |
+|-------------------------|-----------------|-------------------|
+| multisig_update_request | module | gravity |
+| multisig_update_request | bridge_contract | {bridge_contract} |
+| multisig_update_request | bridge_chain_id | {bridge_chain_id} |
+| multisig_update_request | multisig_id | {multisig_id} |
+| multisig_update_request | nonce | {nonce} |
+
+| Type | Attribute Key | Attribute Value |
+|------------------------------|-----------------|-------------------|
+| outgoing_logic_call_canceled | module | gravity |
+| outgoing_logic_call_canceled | bridge_contract | {bridge_contract} |
+| outgoing_logic_call_canceled | bridge_chain_id | {bridge_chain_id} |
+| outgoing_logic_call_canceled | batch_id | {batch_id} |
+| outgoing_logic_call_canceled | nonce | {nonce} |
+
+| Type | Attribute Key | Attribute Value |
+|-------------|------------------|--------------------|
+| observation | module | gravity |
+| observation | attestation_type | {attestation_type} |
+| observation | bridge_contract | {bridge_contract} |
+| observation | bridge_chain_id | {bridge_chain_id} |
+| observation | attestation_id | {attestation_id} |
+| observation | attestation_id | {attestation_id} |
+| observation | nonce | {nonce} |
+
+## Service Messages
+
+### Msg/ValsetConfirm
+
+| Type | Attribute Key | Attribute Value |
+|---------|----------------------|--------------------|
+| message | module | valset_confirm |
+| message | set_operator_address | {operator_address} |
+
+### Msg/SendToEth
+
+| Type | Attribute Key | Attribute Value |
+|---------|----------------|-----------------|
+| message | module | send_to_eth |
+| message | outgoing_tx_id | {tx_id} |
+
+| Type | Attribute Key | Attribute Value |
+|---------------------|-----------------|-------------------|
+| withdrawal_received | module | gravity |
+| withdrawal_received | bridge_contract | {bridge_contract} |
+| withdrawal_received | bridge_chain_id | {bridge_chain_id} |
+| withdrawal_received | outgoing_tx_id | {outgoing_tx_id} |
+| withdrawal_received | nonce | {nonce} |
+
+### Msg/RequestBatch
+
+| Type | Attribute Key | Attribute Value |
+|---------|---------------|-----------------|
+| message | module | request_batch |
+| message | batch_nonce | {batch_tx_id} |
+
+| Type | Attribute Key | Attribute Value |
+|----------------|-----------------|-------------------|
+| outgoing_batch | module | gravity |
+| outgoing_batch | bridge_contract | {bridge_contract} |
+| outgoing_batch | bridge_chain_id | {bridge_chain_id} |
+| outgoing_batch | outgoing_tx_id | {outgoing_tx_id} |
+| outgoing_batch | nonce | {nonce} |
+
+### Msg/ConfirmBatch
+
+| Type | Attribute Key | Attribute Value |
+|---------|-------------------|---------------------|
+| message | module | confirm_batch |
+| message | batch_confirm_key | {batch_confirm_key} |
+
+### Msg/SetOrchestratorAddress
+
+| Type | Attribute Key | Attribute Value |
+|---------|----------------------|----------------------|
+| message | module | set_operator_address |
+| message | set_operator_address | {operator_address} |
+
+### MsgConfirmLogicCall
+
+| Type | Attribute Key | Attribute Value |
+|---------|---------------|-----------------|
+| message | module | confirm_logic |
+
+### Msg/ERC20DeployedClaim
+
+| Type | Attribute Key | Attribute Value |
+|---------|----------------|----------------------|
+| message | module | ERC20_deployed_claim |
+| message | attestation_id | {attestation_key} |
+
+### Msg/ConfirmLogicCall
+
+| Type | Attribute Key | Attribute Value |
+|---------|---------------|-----------------|
+| message | module | confirm_logic |
+
+### Msg/LogicCallExecutedClaim
+
+| Type | Attribute Key | Attribute Value |
+|---------|----------------|---------------------------|
+| message | module | Logic_Call_Executed_Claim |
+| message | attestation_id | {attestation_key} |
+
+### Msg/DepositClaim
+
+| Type | Attribute Key | Attribute Value |
+|---------|----------------|-------------------|
+| message | module | deposit_claim |
+| message | attestation_id | {attestation_key} |
+
+### Msg/WithdrawClaim
+
+| Type | Attribute Key | Attribute Value |
+|---------|----------------|-------------------|
+| message | module | withdraw_claim |
+| message | attestation_id | {attestation_key} |
diff --git a/module/x/gravity/spec/07_params.md b/module/x/gravity/spec/07_params.md
new file mode 100644
index 0000000..2727976
--- /dev/null
+++ b/module/x/gravity/spec/07_params.md
@@ -0,0 +1,26 @@
+
+
+# Parameters
+
+The gravity module contains the following parameters:
+
+| Key | Type | Example |
+|-------------------------------|--------------|----------------|
+| gravityId | string | "gravity" |
+| ContractSourceHash | string | "special hash" |
+| BridgeEthereumAddress | string | "0x1" |
+| BridgeChainId | uint64 | 4 |
+| SignedValsetsWindow | uint64 | 10_000 |
+| SignedBatchesWindow | uint64 | 10_000 |
+| SignedClaimsWindow | uint64 | 10_000 |
+| TargetEthTxTimeout | uint64 | 43_200_000 |
+| AverageBlockTime | uint64 | 5_000 |
+| AverageEthereumBlockTime | uint64 | 15_000 |
+| SlashFractionValset | sdkTypes.Dec | - |
+| SlashFractionBatch | sdkTypes.Dec | - |
+| SlashFractionClaim | sdkTypes.Dec | - |
+| SlashFractionConflictingClaim | sdkTypes.Dec | - |
+| UnbondSlashingValsetsWindow | uint64 | 3 |
+| UnbondSlashingBatchWindow | uint64 | 3 |
diff --git a/module/x/gravity/spec/README.md b/module/x/gravity/spec/README.md
new file mode 100644
index 0000000..b27cff1
--- /dev/null
+++ b/module/x/gravity/spec/README.md
@@ -0,0 +1,12 @@
+
+
+# `gravity`
+
+## Abstract
+
+## Contents
diff --git a/module/x/gravity/types/abi_json.go b/module/x/gravity/types/abi_json.go
new file mode 100644
index 0000000..5b1cf7f
--- /dev/null
+++ b/module/x/gravity/types/abi_json.go
@@ -0,0 +1,74 @@
+package types
+
+// The go-ethereum ABI encoder *only* encodes function calls and then it only encodes
+// function calls for which you provide an ABI json just like you would get out of the
+// solidity compiler with your compiled contract.
+// You are supposed to compile your contract, use abigen to generate an ABI , import
+// this generated go module and then use for that for all testing and development.
+// This abstraction layer is more trouble than it's worth, because we don't want to
+// encode a function call at all, but instead we want to emulate a Solidity encode operation
+// which has no equal available from go-ethereum.
+//
+// In order to work around this absurd series of problems we have to manually write the below
+// 'function specification' that will encode the same arguments into a function call. We can then
+// truncate the first several bytes where the call name is encoded to finally get the equal of the
+
+const (
+ // BatchTxCheckpointABIJSON checks the ETH ABI for compatability of the OutgoingBatchTx message
+ BatchTxCheckpointABIJSON = `[{
+ "name": "submitBatch",
+ "stateMutability": "pure",
+ "type": "function",
+ "inputs": [
+ { "internalType": "bytes32", "name": "_gravityId", "type": "bytes32" },
+ { "internalType": "bytes32", "name": "_methodName", "type": "bytes32" },
+ { "internalType": "uint256[]", "name": "_amounts", "type": "uint256[]" },
+ { "internalType": "address[]", "name": "_destinations", "type": "address[]" },
+ { "internalType": "uint256[]", "name": "_fees", "type": "uint256[]" },
+ { "internalType": "uint256", "name": "_batchNonce", "type": "uint256" },
+ { "internalType": "address", "name": "_tokenContract", "type": "address" },
+ { "internalType": "uint256", "name": "_batchTimeout", "type": "uint256" }
+ ],
+ "outputs": [
+ { "internalType": "bytes32", "name": "", "type": "bytes32" }
+ ]
+ }]`
+
+ // SignerSetTxCheckpointABIJSON checks the ETH ABI for compatability of the signer set update message
+ SignerSetTxCheckpointABIJSON = `[{
+ "name": "checkpoint",
+ "stateMutability": "pure",
+ "type": "function",
+ "inputs": [
+ { "internalType": "bytes32", "name": "_gravityId", "type": "bytes32" },
+ { "internalType": "bytes32", "name": "_checkpoint", "type": "bytes32" },
+ { "internalType": "uint256", "name": "_valsetNonce", "type": "uint256" },
+ { "internalType": "address[]", "name": "_validators", "type": "address[]" },
+ { "internalType": "uint256[]", "name": "_powers", "type": "uint256[]" }
+ ],
+ "outputs": [
+ { "internalType": "bytes32", "name": "", "type": "bytes32" }
+ ]
+ }]`
+
+ // ContractCallTxABIJSON checks the ETH ABI for compatability of the logic call message
+ ContractCallTxABIJSON = `[{
+ "name": "checkpoint",
+ "outputs": [],
+ "stateMutability": "pure",
+ "type": "function",
+ "inputs": [
+ { "internalType": "bytes32", "name": "_gravityId", "type": "bytes32" },
+ { "internalType": "bytes32", "name": "_methodName", "type": "bytes32" },
+ { "internalType": "uint256[]", "name": "_transferAmounts", "type": "uint256[]" },
+ { "internalType": "address[]", "name": "_transferTokenContracts", "type": "address[]" },
+ { "internalType": "uint256[]", "name": "_feeAmounts", "type": "uint256[]" },
+ { "internalType": "address[]", "name": "_feeTokenContracts", "type": "address[]" },
+ { "internalType": "address", "name": "_logicContractAddress", "type": "address" },
+ { "internalType": "bytes", "name": "_payload", "type": "bytes" },
+ { "internalType": "uint256", "name": "_timeout", "type": "uint256" },
+ { "internalType": "bytes32", "name": "_invalidationId", "type": "bytes32" },
+ { "internalType": "uint256", "name": "_invalidationNonce", "type": "uint256" }
+ ]
+ }]`
+)
diff --git a/module/x/gravity/types/checkpoint_test.go b/module/x/gravity/types/checkpoint_test.go
new file mode 100644
index 0000000..b178ec9
--- /dev/null
+++ b/module/x/gravity/types/checkpoint_test.go
@@ -0,0 +1,86 @@
+package types
+
+import (
+ "encoding/hex"
+ "testing"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+
+ gethcommon "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestBatchTxCheckpoint(t *testing.T) {
+ senderAddr, err := sdk.AccAddressFromHex("527FBEE652609AB150F0AEE9D61A2F76CFC4A73E")
+ require.NoError(t, err)
+ var (
+ erc20Addr = gethcommon.HexToAddress("0x835973768750b3ED2D5c3EF5AdcD5eDb44d12aD4")
+ )
+
+ src := BatchTx{
+ BatchNonce: 1,
+ Timeout: 2111,
+ Transactions: []*SendToEthereum{
+ {
+ Id: 0x1,
+ Sender: senderAddr.String(),
+ EthereumRecipient: "0x9FC9C2DfBA3b6cF204C37a5F690619772b926e39",
+ Erc20Token: NewSDKIntERC20Token(sdk.NewInt(0x1), erc20Addr),
+ Erc20Fee: NewSDKIntERC20Token(sdk.NewInt(0x1), erc20Addr),
+ },
+ },
+ TokenContract: erc20Addr.Hex(),
+ }
+
+ // TODO: get from params
+ ourHash := src.GetCheckpoint([]byte("foo"))
+
+ // hash from bridge contract
+ goldHash := "0xa3a7ee0a363b8ad2514e7ee8f110d7449c0d88f3b0913c28c1751e6e0079a9b2"[2:]
+ // The function used to compute the "gold hash" above is in /solidity/test/updateValsetAndSubmitBatch.ts
+ // Be aware that every time that you run the above .ts file, it will use a different tokenContractAddress and thus compute
+ // a different hash.
+ assert.Equal(t, goldHash, hex.EncodeToString(ourHash))
+}
+
+func TestContractCallTxCheckpoint(t *testing.T) {
+ payload, err := hex.DecodeString("0x74657374696e675061796c6f6164000000000000000000000000000000000000"[2:])
+ require.NoError(t, err)
+ invalidationId, err := hex.DecodeString("0x696e76616c69646174696f6e4964000000000000000000000000000000000000"[2:])
+ require.NoError(t, err)
+
+ token := []ERC20Token{NewSDKIntERC20Token(sdk.NewIntFromUint64(1), gethcommon.HexToAddress("0xC26eFfa98B8A2632141562Ae7E34953Cfe5B4888"))}
+ call := ContractCallTx{
+ Tokens: token,
+ Fees: token,
+ Address: "0x17c1736CcF692F653c433d7aa2aB45148C016F68",
+ Payload: payload,
+ Timeout: 4766922941000,
+ InvalidationScope: invalidationId,
+ InvalidationNonce: 1,
+ }
+
+ ourHash := call.GetCheckpoint([]byte("foo"))
+
+ // hash from bridge contract
+ goldHash := "0x1de95c9ace999f8ec70c6dc8d045942da2612950567c4861aca959c0650194da"[2:]
+ // The function used to compute the "gold hash" above is in /solidity/test/updateValsetAndSubmitBatch.ts
+ // Be aware that every time that you run the above .ts file, it will use a different tokenContractAddress and thus compute
+ // a different hash.
+ assert.Equal(t, goldHash, hex.EncodeToString(ourHash))
+}
+
+func TestValsetCheckpoint(t *testing.T) {
+ src := NewSignerSetTx(0xc, 0xc, EthereumSigners{{
+ Power: 0xffffffff,
+ EthereumAddress: gethcommon.Address{0xb4, 0x62, 0x86, 0x4e, 0x39, 0x5d, 0x88, 0xd6, 0xbc, 0x7c, 0x5d, 0xd5, 0xf3, 0xf5, 0xeb, 0x4c, 0xc2, 0x59, 0x92, 0x55}.String(),
+ }})
+
+ // TODO: this is hardcoded to foo, replace
+ ourHash := src.GetCheckpoint([]byte("foo"))
+
+ // hash from bridge contract
+ goldHash := "0xf024ab7404464494d3919e5a7f0d8ac40804fb9bd39ad5d16cdb3e66aa219b64"[2:]
+ assert.Equal(t, goldHash, hex.EncodeToString(ourHash))
+}
diff --git a/module/x/gravity/types/codec.go b/module/x/gravity/types/codec.go
new file mode 100644
index 0000000..4f85167
--- /dev/null
+++ b/module/x/gravity/types/codec.go
@@ -0,0 +1,161 @@
+package types
+
+import (
+ "github.com/gogo/protobuf/proto"
+
+ "github.com/cosmos/cosmos-sdk/codec"
+ "github.com/cosmos/cosmos-sdk/codec/types"
+ cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/cosmos/cosmos-sdk/types/msgservice"
+)
+
+// RegisterLegacyAminoCodec registers the vesting interfaces and concrete types on the
+// provided LegacyAmino codec. These types are used for Amino JSON serialization
+func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
+ cdc.RegisterConcrete(&MsgDelegateKeys{}, "gravity-bridge/", nil)
+}
+
+var (
+ amino = codec.NewLegacyAmino()
+
+ // ModuleCdc references the global x/bank module codec. Note, the codec should
+ // ONLY be used in certain instances of tests and for JSON encoding as Amino is
+ // still used for that purpose.
+ //
+ // The actual codec used for serialization should be provided to x/staking and
+ // defined at the application level.
+ ModuleCdc = codec.NewAminoCodec(amino)
+)
+
+func init() {
+ RegisterLegacyAminoCodec(amino)
+ cryptocodec.RegisterCrypto(amino)
+ amino.Seal()
+}
+
+// RegisterInterfaces registers the interfaces for the proto stuff
+func RegisterInterfaces(registry types.InterfaceRegistry) {
+ registry.RegisterImplementations((*sdk.Msg)(nil),
+ &MsgSendToEthereum{},
+ &MsgCancelSendToEthereum{},
+ &MsgRequestBatchTx{},
+ &MsgSubmitEthereumEvent{},
+ &MsgSubmitEthereumTxConfirmation{},
+ &MsgDelegateKeys{},
+ )
+
+ registry.RegisterInterface(
+ "gravity.v1.EthereumEvent",
+ (*EthereumEvent)(nil),
+ &SendToCosmosEvent{},
+ &BatchExecutedEvent{},
+ &ERC20DeployedEvent{},
+ &ContractCallExecutedEvent{},
+ &SignerSetTxExecutedEvent{},
+ )
+
+ registry.RegisterInterface(
+ "gravity.v1.EthereumSignature",
+ (*EthereumTxConfirmation)(nil),
+ &BatchTxConfirmation{},
+ &ContractCallTxConfirmation{},
+ &SignerSetTxConfirmation{},
+ )
+
+ registry.RegisterInterface(
+ "gravity.v1.OutgoingTx",
+ (*OutgoingTx)(nil),
+ &SignerSetTx{},
+ &BatchTx{},
+ &ContractCallTx{},
+ )
+
+ msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
+}
+
+func PackEvent(event EthereumEvent) (*types.Any, error) {
+ msg, ok := event.(proto.Message)
+ if !ok {
+ return nil, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", event)
+ }
+
+ anyEvent, err := types.NewAnyWithValue(msg)
+ if err != nil {
+ return nil, sdkerrors.Wrap(sdkerrors.ErrPackAny, err.Error())
+ }
+
+ return anyEvent, nil
+}
+
+// UnpackEvent unpacks an Any into an EthereumEvent. It returns an error if the
+// event can't be unpacked.
+func UnpackEvent(any *types.Any) (EthereumEvent, error) {
+ if any == nil {
+ return nil, sdkerrors.Wrap(sdkerrors.ErrUnpackAny, "protobuf Any message cannot be nil")
+ }
+
+ event, ok := any.GetCachedValue().(EthereumEvent)
+ if !ok {
+ return nil, sdkerrors.Wrapf(sdkerrors.ErrUnpackAny, "cannot unpack Any into EthereumEvent %T", any)
+ }
+
+ return event, nil
+}
+
+func PackConfirmation(confirmation EthereumTxConfirmation) (*types.Any, error) {
+ msg, ok := confirmation.(proto.Message)
+ if !ok {
+ return nil, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", confirmation)
+ }
+
+ anyEvent, err := types.NewAnyWithValue(msg)
+ if err != nil {
+ return nil, sdkerrors.Wrap(sdkerrors.ErrPackAny, err.Error())
+ }
+
+ return anyEvent, nil
+}
+
+// UnpackConfirmation unpacks an Any into a Confirm interface. It returns an error if the
+// confirm can't be unpacked.
+func UnpackConfirmation(any *types.Any) (EthereumTxConfirmation, error) {
+ if any == nil {
+ return nil, sdkerrors.Wrap(sdkerrors.ErrUnpackAny, "protobuf Any message cannot be nil")
+ }
+
+ confirm, ok := any.GetCachedValue().(EthereumTxConfirmation)
+ if !ok {
+ return nil, sdkerrors.Wrapf(sdkerrors.ErrUnpackAny, "cannot unpack Any into EthereumSignature %T", any)
+ }
+
+ return confirm, nil
+}
+
+func PackOutgoingTx(outgoing OutgoingTx) (*types.Any, error) {
+ msg, ok := outgoing.(proto.Message)
+ if !ok {
+ return nil, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", outgoing)
+ }
+
+ anyEvent, err := types.NewAnyWithValue(msg)
+ if err != nil {
+ return nil, sdkerrors.Wrap(sdkerrors.ErrPackAny, err.Error())
+ }
+
+ return anyEvent, nil
+}
+
+func UnpackOutgoingTx(any *types.Any) (OutgoingTx, error) {
+ if any == nil {
+ return nil, sdkerrors.Wrap(sdkerrors.ErrUnpackAny, "protobuf Any message cannot be nil")
+ }
+
+ confirm, ok := any.GetCachedValue().(OutgoingTx)
+ if !ok {
+ return nil, sdkerrors.Wrapf(sdkerrors.ErrUnpackAny, "cannot unpack Any into OutgoingTx %T", any)
+ }
+
+ return confirm, nil
+}
diff --git a/module/x/gravity/types/errors.go b/module/x/gravity/types/errors.go
new file mode 100644
index 0000000..c04f8ff
--- /dev/null
+++ b/module/x/gravity/types/errors.go
@@ -0,0 +1,13 @@
+package types
+
+import (
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+)
+
+var (
+ ErrInvalid = sdkerrors.Register(ModuleName, 3, "invalid")
+ ErrSupplyOverflow = sdkerrors.Register(ModuleName, 4, "malicious ERC20 with invalid supply sent over bridge")
+ ErrDelegateKeys = sdkerrors.Register(ModuleName, 5, "failed to delegate keys")
+ ErrEmptyEthSig = sdkerrors.Register(ModuleName, 6, "empty Ethereum signature")
+ ErrInvalidERC20Event = sdkerrors.Register(ModuleName, 7, "invalid ERC20 deployed event")
+)
diff --git a/module/x/gravity/types/ethereum.go b/module/x/gravity/types/ethereum.go
new file mode 100644
index 0000000..1d4d6c0
--- /dev/null
+++ b/module/x/gravity/types/ethereum.go
@@ -0,0 +1,99 @@
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "strings"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/ethereum/go-ethereum/common"
+)
+
+const (
+ // GravityDenomPrefix indicates the prefix for all assests minted by this module
+ GravityDenomPrefix = ModuleName
+
+ // GravityDenomSeparator is the separator for gravity denoms
+ GravityDenomSeparator = ""
+
+ // EthereumContractAddressLen is the length of contract address strings
+ EthereumContractAddressLen = 42
+
+ // GravityDenomLen is the length of the denoms generated by the gravity module
+ GravityDenomLen = len(GravityDenomPrefix) + len(GravityDenomSeparator) + EthereumContractAddressLen
+)
+
+// EthereumAddrLessThan migrates the Ethereum address less than function
+func EthereumAddrLessThan(e, o string) bool {
+ return bytes.Compare([]byte(e)[:], []byte(o)[:]) == -1
+}
+
+// ValidateEthereumAddress validates the ethereum address strings
+// func ValidateEthereumAddress(a string) error {
+// if a == "" {
+// return fmt.Errorf("empty")
+// }
+// if !regexp.MustCompile("^0x[0-9a-fA-F]{40}$").MatchString(a) {
+// return fmt.Errorf("address(%s) doesn't pass regex", a)
+// }
+// if len(a) != EthereumContractAddressLen {
+// return fmt.Errorf("address(%s) of the wrong length exp(%d) actual(%d)", a, len(a), EthereumContractAddressLen)
+// }
+// return nil
+// }
+
+/////////////////////////
+// ERC20Token //
+/////////////////////////
+
+// NewERC20Token returns a new instance of an ERC20
+func NewERC20Token(amount uint64, contract string) ERC20Token {
+ return ERC20Token{
+ Amount: sdk.NewIntFromUint64(amount),
+ Contract: contract,
+ }
+}
+
+func NewSDKIntERC20Token(amount sdk.Int, contract common.Address) ERC20Token {
+ return ERC20Token{
+ Amount: amount,
+ Contract: contract.Hex(),
+ }
+}
+
+// GravityCoin returns the gravity representation of the ERC20
+func (e ERC20Token) GravityCoin() sdk.Coin {
+ return sdk.Coin{Amount: e.Amount, Denom: strings.Join([]string{GravityDenomPrefix, e.Contract}, GravityDenomSeparator)}
+}
+
+func GravityDenomToERC20(denom string) (string, error) {
+ fullPrefix := GravityDenomPrefix + GravityDenomSeparator
+ if !strings.HasPrefix(denom, fullPrefix) {
+ return "", fmt.Errorf("denom prefix(%s) not equal to expected(%s)", denom, fullPrefix)
+ }
+ contract := strings.TrimPrefix(denom, fullPrefix)
+ switch {
+ case !common.IsHexAddress(contract):
+ return "", fmt.Errorf("error validating ethereum contract address")
+ case len(denom) != GravityDenomLen:
+ return "", fmt.Errorf("len(denom)(%d) not equal to GravityDenomLen(%d)", len(denom), GravityDenomLen)
+ default:
+ return contract, nil
+ }
+}
+
+func NewSendToEthereumTx(id uint64, tokenContract common.Address, sender sdk.AccAddress, recipient common.Address, amount, feeAmount uint64) *SendToEthereum {
+ return &SendToEthereum{
+ Id: id,
+ Erc20Fee: NewERC20Token(feeAmount, tokenContract.Hex()),
+ Sender: sender.String(),
+ EthereumRecipient: recipient.Hex(),
+ Erc20Token: NewERC20Token(amount, tokenContract.Hex()),
+ }
+}
+
+// Id: 2,
+// Erc20Fee: types.NewERC20Token(3, myTokenContractAddr),
+// Sender: mySender.String(),
+// EthereumRecipient: myReceiver,
+// Erc20Token: types.NewERC20Token(101, myTokenContractAddr),
diff --git a/module/x/gravity/types/ethereum_event.go b/module/x/gravity/types/ethereum_event.go
new file mode 100644
index 0000000..aeb2d59
--- /dev/null
+++ b/module/x/gravity/types/ethereum_event.go
@@ -0,0 +1,175 @@
+package types
+
+import (
+ "bytes"
+ "crypto/sha256"
+ "fmt"
+
+ "github.com/cosmos/cosmos-sdk/codec/types"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/ethereum/go-ethereum/common"
+ tmbytes "github.com/tendermint/tendermint/libs/bytes"
+)
+
+var (
+ _ EthereumEvent = &SendToCosmosEvent{}
+ _ EthereumEvent = &BatchExecutedEvent{}
+ _ EthereumEvent = &ContractCallExecutedEvent{}
+ _ EthereumEvent = &ERC20DeployedEvent{}
+ _ EthereumEvent = &SignerSetTxExecutedEvent{}
+)
+
+// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
+func (m *EthereumEventVoteRecord) UnpackInterfaces(unpacker types.AnyUnpacker) error {
+ var event EthereumEvent
+ return unpacker.UnpackAny(m.Event, &event)
+}
+
+//////////
+// Hash //
+//////////
+
+func (stce *SendToCosmosEvent) Hash() tmbytes.HexBytes {
+ rcv, _ := sdk.AccAddressFromBech32(stce.CosmosReceiver)
+ path := bytes.Join(
+ [][]byte{
+ sdk.Uint64ToBigEndian(stce.EventNonce),
+ common.HexToAddress(stce.TokenContract).Bytes(),
+ stce.Amount.BigInt().Bytes(),
+ common.Hex2Bytes(stce.EthereumSender),
+ rcv.Bytes(),
+ sdk.Uint64ToBigEndian(stce.EthereumHeight),
+ },
+ []byte{},
+ )
+ hash := sha256.Sum256([]byte(path))
+ return hash[:]
+}
+
+func (bee *BatchExecutedEvent) Hash() tmbytes.HexBytes {
+ path := bytes.Join(
+ [][]byte{
+ common.HexToAddress(bee.TokenContract).Bytes(),
+ sdk.Uint64ToBigEndian(bee.EventNonce),
+ sdk.Uint64ToBigEndian(bee.BatchNonce),
+ sdk.Uint64ToBigEndian(bee.EthereumHeight),
+ },
+ []byte{},
+ )
+ hash := sha256.Sum256([]byte(path))
+ return hash[:]
+}
+
+func (ccee *ContractCallExecutedEvent) Hash() tmbytes.HexBytes {
+ path := bytes.Join(
+ [][]byte{
+ sdk.Uint64ToBigEndian(ccee.EventNonce),
+ ccee.InvalidationScope,
+ sdk.Uint64ToBigEndian(ccee.InvalidationNonce),
+ sdk.Uint64ToBigEndian(ccee.EthereumHeight),
+ },
+ []byte{},
+ )
+ hash := sha256.Sum256([]byte(path))
+ return hash[:]
+}
+
+func (e20de *ERC20DeployedEvent) Hash() tmbytes.HexBytes {
+ path := bytes.Join(
+ [][]byte{
+ sdk.Uint64ToBigEndian(e20de.EventNonce),
+ []byte(e20de.CosmosDenom),
+ common.HexToAddress(e20de.TokenContract).Bytes(),
+ []byte(e20de.Erc20Name),
+ []byte(e20de.Erc20Symbol),
+ sdk.Uint64ToBigEndian(e20de.Erc20Decimals),
+ sdk.Uint64ToBigEndian(e20de.EthereumHeight),
+ },
+ []byte{},
+ )
+ hash := sha256.Sum256([]byte(path))
+ return hash[:]
+}
+
+func (sse *SignerSetTxExecutedEvent) Hash() tmbytes.HexBytes {
+ path := bytes.Join(
+ [][]byte{
+ sdk.Uint64ToBigEndian(sse.EventNonce),
+ sdk.Uint64ToBigEndian(sse.SignerSetTxNonce),
+ sdk.Uint64ToBigEndian(sse.EthereumHeight),
+ EthereumSigners(sse.Members).Hash(),
+ },
+ []byte{},
+ )
+ hash := sha256.Sum256(([]byte(path)))
+ return hash[:]
+}
+
+//////////////
+// Validate //
+//////////////
+
+func (stce *SendToCosmosEvent) Validate() error {
+ if stce.EventNonce == 0 {
+ return fmt.Errorf("event nonce cannot be 0")
+ }
+ if !common.IsHexAddress(stce.TokenContract) {
+ return sdkerrors.Wrap(ErrInvalid, "ethereum contract address")
+ }
+ if stce.Amount.IsNegative() {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "amount must be positive")
+ }
+ if !common.IsHexAddress(stce.EthereumSender) {
+ return sdkerrors.Wrap(ErrInvalid, "ethereum sender")
+ }
+ if _, err := sdk.AccAddressFromBech32(stce.CosmosReceiver); err != nil {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, stce.CosmosReceiver)
+ }
+ return nil
+}
+
+func (bee *BatchExecutedEvent) Validate() error {
+ if bee.EventNonce == 0 {
+ return fmt.Errorf("event nonce cannot be 0")
+ }
+ if !common.IsHexAddress(bee.TokenContract) {
+ return sdkerrors.Wrap(ErrInvalid, "ethereum contract address")
+ }
+ return nil
+}
+
+func (ccee *ContractCallExecutedEvent) Validate() error {
+ if ccee.EventNonce == 0 {
+ return fmt.Errorf("event nonce cannot be 0")
+ }
+ return nil
+}
+
+func (e20de *ERC20DeployedEvent) Validate() error {
+ if e20de.EventNonce == 0 {
+ return fmt.Errorf("event nonce cannot be 0")
+ }
+ if !common.IsHexAddress(e20de.TokenContract) {
+ return sdkerrors.Wrap(ErrInvalid, "ethereum contract address")
+ }
+ if err := sdk.ValidateDenom(e20de.CosmosDenom); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (sse *SignerSetTxExecutedEvent) Validate() error {
+ if sse.EventNonce == 0 {
+ return fmt.Errorf("event nonce cannot be 0")
+ }
+ if sse.Members == nil {
+ return fmt.Errorf("members cannot be nil")
+ }
+ for i, member := range sse.Members {
+ if err := member.ValidateBasic(); err != nil {
+ return fmt.Errorf("ethereum signer %d error: %w", i, err)
+ }
+ }
+ return nil
+}
diff --git a/module/x/gravity/types/ethereum_signature.go b/module/x/gravity/types/ethereum_signature.go
new file mode 100644
index 0000000..02cd268
--- /dev/null
+++ b/module/x/gravity/types/ethereum_signature.go
@@ -0,0 +1,95 @@
+package types
+
+import (
+ "fmt"
+
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/ethereum/go-ethereum/common"
+)
+
+var (
+ _ EthereumTxConfirmation = &SignerSetTxConfirmation{}
+ _ EthereumTxConfirmation = &ContractCallTxConfirmation{}
+ _ EthereumTxConfirmation = &BatchTxConfirmation{}
+)
+
+///////////////
+// GetSigner //
+///////////////
+
+func (u *SignerSetTxConfirmation) GetSigner() common.Address {
+ return common.HexToAddress(u.EthereumSigner)
+}
+
+func (u *ContractCallTxConfirmation) GetSigner() common.Address {
+ return common.HexToAddress(u.EthereumSigner)
+}
+
+func (u *BatchTxConfirmation) GetSigner() common.Address {
+ return common.HexToAddress(u.EthereumSigner)
+}
+
+///////////////////
+// GetStoreIndex //
+///////////////////
+
+func (sstx *SignerSetTxConfirmation) GetStoreIndex() []byte {
+ return MakeSignerSetTxKey(sstx.SignerSetNonce)
+}
+
+func (btx *BatchTxConfirmation) GetStoreIndex() []byte {
+ return MakeBatchTxKey(common.HexToAddress(btx.TokenContract), btx.BatchNonce)
+}
+
+func (cctx *ContractCallTxConfirmation) GetStoreIndex() []byte {
+ return MakeContractCallTxKey(cctx.InvalidationScope, cctx.InvalidationNonce)
+}
+
+//////////////
+// Validate //
+//////////////
+
+func (u *SignerSetTxConfirmation) Validate() error {
+ if u.SignerSetNonce == 0 {
+ return fmt.Errorf("nonce must be set")
+ }
+ if !common.IsHexAddress(u.EthereumSigner) {
+ return sdkerrors.Wrap(ErrInvalid, "ethereum signer must be address")
+ }
+ if u.Signature == nil {
+ return fmt.Errorf("signature must be set")
+ }
+ return nil
+}
+
+func (u *ContractCallTxConfirmation) Validate() error {
+ if u.InvalidationNonce == 0 {
+ return fmt.Errorf("invalidation nonce must be set")
+ }
+ if u.InvalidationScope == nil {
+ return fmt.Errorf("invalidation scope must be set")
+ }
+ if !common.IsHexAddress(u.EthereumSigner) {
+ return sdkerrors.Wrap(ErrInvalid, "ethereum signer must be address")
+ }
+ if u.Signature == nil {
+ return fmt.Errorf("signature must be set")
+ }
+ return nil
+}
+
+func (u *BatchTxConfirmation) Validate() error {
+ if u.BatchNonce == 0 {
+ return fmt.Errorf("nonce must be set")
+ }
+ if !common.IsHexAddress(u.TokenContract) {
+ return fmt.Errorf("token contract address must be valid ethereum address")
+ }
+ if !common.IsHexAddress(u.EthereumSigner) {
+ return sdkerrors.Wrap(ErrInvalid, "ethereum signer must be address")
+ }
+ if u.Signature == nil {
+ return fmt.Errorf("signature must be set")
+ }
+ return nil
+}
diff --git a/module/x/gravity/types/ethereum_signer.go b/module/x/gravity/types/ethereum_signer.go
new file mode 100644
index 0000000..efe7b90
--- /dev/null
+++ b/module/x/gravity/types/ethereum_signer.go
@@ -0,0 +1,68 @@
+package types
+
+import (
+ "crypto/ecdsa"
+
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+const (
+ signaturePrefix = "\x19Ethereum Signed Message:\n32"
+)
+
+// NewEthereumSignature creates a new signuature over a given byte array
+func NewEthereumSignature(hash []byte, privateKey *ecdsa.PrivateKey) ([]byte, error) {
+ if privateKey == nil {
+ return nil, sdkerrors.Wrap(ErrInvalid, "did not pass in private key")
+ }
+ protectedHash := crypto.Keccak256Hash(append([]byte(signaturePrefix), hash...))
+ return crypto.Sign(protectedHash.Bytes(), privateKey)
+}
+
+// ValidateEthereumSignature takes a message, an associated signature and public key and
+// returns an error if the signature isn't valid
+func ValidateEthereumSignature(hash []byte, signature []byte, ethAddress common.Address) error {
+
+ /// signature to public key: invalid signature length: invalid
+ /// signature not matching: invalid: invalid
+ if len(signature) < 65 {
+ return sdkerrors.Wrapf(ErrInvalid, "signature too short signature %x", signature)
+ }
+
+ // Copy to avoid mutating signature slice by accident
+ var sigCopy = make([]byte, len(signature))
+ copy(sigCopy, signature)
+
+ // To verify signature
+ // - use crypto.SigToPub to get the public key
+ // - use crypto.PubkeyToAddress to get the address
+ // - compare this to the address given.
+
+ // for backwards compatibility reasons the V value of an Ethereum sig is presented
+ // as 27 or 28, internally though it should be a 0-3 value due to changed formats.
+ // It seems that go-ethereum expects this to be done before sigs actually reach it's
+ // internal validation functions. In order to comply with this requirement we check
+ // the sig an dif it's in standard format we correct it. If it's in go-ethereum's expected
+ // format already we make no changes.
+ //
+ // We could attempt to break or otherwise exit early on obviously invalid values for this
+ // byte, but that's a task best left to go-ethereum
+ if sigCopy[64] == 27 || sigCopy[64] == 28 {
+ sigCopy[64] -= 27
+ }
+
+ hash = append([]uint8(signaturePrefix), hash...)
+
+ pubkey, err := crypto.SigToPub(crypto.Keccak256Hash(hash).Bytes(), sigCopy)
+ if err != nil {
+ return sdkerrors.Wrapf(err, "signature to public key sig %x hash %x", sigCopy, hash)
+ }
+
+ if addr := crypto.PubkeyToAddress(*pubkey); addr != ethAddress {
+ return sdkerrors.Wrapf(ErrInvalid, "signature not matching addr %x sig %x hash %x", addr, signature, hash)
+ }
+
+ return nil
+}
diff --git a/module/x/gravity/types/ethereum_signer_test.go b/module/x/gravity/types/ethereum_signer_test.go
new file mode 100644
index 0000000..a66a667
--- /dev/null
+++ b/module/x/gravity/types/ethereum_signer_test.go
@@ -0,0 +1,91 @@
+package types
+
+import (
+ "encoding/hex"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestSignerSetConfirmSig(t *testing.T) {
+ const (
+ correctSig = "e108a7776de6b87183b0690484a74daef44aa6daf907e91abaf7bbfa426ae7706b12e0bd44ef7b0634710d99c2d81087a2f39e075158212343a3b2948ecf33d01c"
+ invalidSig = "fffff7776de6b87183b0690484a74daef44aa6daf907e91abaf7bbfa426ae7706b12e0bd44ef7b0634710d99c2d81087a2f39e075158212343a3b2948ecf33d01c"
+ ethAddress = "0xc783df8a850f42e7F7e57013759C285caa701eB6"
+ hash = "88165860d955aee7dc3e83d9d1156a5864b708841965585d206dbef6e9e1a499"
+ )
+
+ specs := map[string]struct {
+ srcHash string
+ srcSignature string
+ srcETHAddr string
+ expErr bool
+ }{
+ "all good": {
+ srcHash: hash,
+ srcSignature: correctSig,
+ srcETHAddr: ethAddress,
+ },
+ "invalid signature": {
+ srcHash: hash,
+ srcSignature: invalidSig,
+ srcETHAddr: ethAddress,
+ expErr: true,
+ },
+ "empty hash": {
+ srcSignature: correctSig,
+ srcETHAddr: ethAddress,
+ expErr: true,
+ },
+ "hash too short": {
+ srcSignature: correctSig,
+ srcETHAddr: ethAddress,
+ srcHash: hash[0:30],
+ expErr: true,
+ },
+ "hash too long": {
+ srcSignature: correctSig,
+ srcETHAddr: ethAddress,
+ srcHash: hash + "01",
+ expErr: true,
+ },
+ "empty signature": {
+ srcHash: hash,
+ srcETHAddr: ethAddress,
+ expErr: true,
+ },
+ "signature too short": {
+ srcHash: hash,
+ srcSignature: correctSig[0:64],
+ srcETHAddr: ethAddress,
+ expErr: true,
+ },
+ "empty eth address": {
+ srcHash: hash,
+ srcSignature: correctSig,
+ expErr: true,
+ },
+ }
+ for msg, spec := range specs {
+ t.Run(msg, func(t *testing.T) {
+ var err error
+ var hashBytes []byte
+ if len(spec.srcHash) != 0 {
+ hashBytes, err = hex.DecodeString(spec.srcHash)
+ require.NoError(t, err)
+ }
+ sigBytes, err := hex.DecodeString(spec.srcSignature)
+ require.NoError(t, err)
+
+ // when
+ err = ValidateEthereumSignature(hashBytes, sigBytes, common.HexToAddress(spec.srcETHAddr))
+ if spec.expErr {
+ assert.Error(t, err)
+ return
+ }
+ assert.NoError(t, err)
+ })
+ }
+}
diff --git a/module/x/gravity/types/events.go b/module/x/gravity/types/events.go
new file mode 100644
index 0000000..948075d
--- /dev/null
+++ b/module/x/gravity/types/events.go
@@ -0,0 +1,33 @@
+package types
+
+const (
+ EventTypeObservation = "observation"
+ EventTypeOutgoingBatch = "outgoing_batch"
+ EventTypeMultisigUpdateRequest = "multisig_update_request"
+ EventTypeOutgoingBatchCanceled = "outgoing_batch_canceled"
+ EventTypeContractCallTxCanceled = "outgoing_logic_call_canceled"
+ EventTypeBridgeWithdrawalReceived = "withdrawal_received"
+ EventTypeBridgeDepositReceived = "deposit_received"
+ EventTypeBridgeWithdrawCanceled = "withdraw_canceled"
+
+ AttributeKeyEthereumEventVoteRecordID = "ethereum_event_vote_record_id"
+ AttributeKeyBatchConfirmKey = "batch_confirm_key"
+ AttributeKeyEthereumSignatureKey = "ethereum_signature_key"
+ AttributeKeyOutgoingBatchID = "batch_id"
+ AttributeKeyOutgoingTXID = "outgoing_tx_id"
+ AttributeKeyEthereumEventType = "ethereum_event_type"
+ AttributeKeyContract = "bridge_contract"
+ AttributeKeyNonce = "nonce"
+ AttributeKeySignerSetNonce = "signerset_nonce"
+ AttributeKeyBatchNonce = "batch_nonce"
+ AttributeKeyBridgeChainID = "bridge_chain_id"
+ AttributeKeySetOrchestratorAddr = "set_orchestrator_address"
+ AttributeKeySetEthereumAddr = "set_ethereum_address"
+ AttributeKeyValidatorAddr = "validator_address"
+ AttributeKeyContractCallInvalidationScope = "contract_call_invalidation_scope"
+ AttributeKeyContractCallInvalidationNonce = "contract_call_invalidation_nonce"
+ AttributeKeyContractCallPayload = "contract_call_payload"
+ AttributeKeyContractCallTokens = "contract_call_tokens"
+ AttributeKeyContractCallFees = "contract_call_fees"
+ AttributeKeyEthTxTimeout = "eth_tx_timeout"
+)
diff --git a/module/x/gravity/types/expected_keepers.go b/module/x/gravity/types/expected_keepers.go
new file mode 100644
index 0000000..e86d5a1
--- /dev/null
+++ b/module/x/gravity/types/expected_keepers.go
@@ -0,0 +1,49 @@
+package types
+
+import (
+ "time"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ bank "github.com/cosmos/cosmos-sdk/x/bank/types"
+ slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+)
+
+// StakingKeeper defines the expected staking keeper methods
+type StakingKeeper interface {
+ GetBondedValidatorsByPower(ctx sdk.Context) []stakingtypes.Validator
+ GetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress) int64
+ GetLastTotalPower(ctx sdk.Context) (power sdk.Int)
+ IterateValidators(sdk.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool))
+ ValidatorQueueIterator(ctx sdk.Context, endTime time.Time, endHeight int64) sdk.Iterator
+ GetParams(ctx sdk.Context) stakingtypes.Params
+ GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool)
+ IterateBondedValidatorsByPower(sdk.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool))
+ IterateLastValidators(sdk.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool))
+ Validator(sdk.Context, sdk.ValAddress) stakingtypes.ValidatorI
+ ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI
+ Slash(sdk.Context, sdk.ConsAddress, int64, int64, sdk.Dec)
+ Jail(sdk.Context, sdk.ConsAddress)
+}
+
+// BankKeeper defines the expected bank keeper methods
+type BankKeeper interface {
+ GetSupply(ctx sdk.Context, denom string) sdk.Coin
+ SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
+ SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error
+ SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
+ MintCoins(ctx sdk.Context, name string, amt sdk.Coins) error
+ BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error
+ GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
+ GetDenomMetaData(ctx sdk.Context, denom string) (bank.Metadata, bool)
+}
+
+type SlashingKeeper interface {
+ GetValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress) (info slashingtypes.ValidatorSigningInfo, found bool)
+}
+
+// AccountKeeper defines the interface contract required for account
+// functionality.
+type AccountKeeper interface {
+ GetSequence(ctx sdk.Context, addr sdk.AccAddress) (uint64, error)
+}
diff --git a/module/x/gravity/types/genesis.go b/module/x/gravity/types/genesis.go
new file mode 100644
index 0000000..4cb669e
--- /dev/null
+++ b/module/x/gravity/types/genesis.go
@@ -0,0 +1,371 @@
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "time"
+
+ cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
+ "github.com/ethereum/go-ethereum/common"
+)
+
+// DefaultParamspace defines the default auth module parameter subspace
+const (
+ // todo: implement oracle constants as params
+ DefaultParamspace = ModuleName
+ EventVoteRecordPeriod = 24 * time.Hour // TODO: value????
+)
+
+var (
+ // ParamsStoreKeyGravityID stores the gravity id
+ ParamsStoreKeyGravityID = []byte("GravityID")
+
+ // ParamsStoreKeyContractHash stores the contract hash
+ ParamsStoreKeyContractHash = []byte("ContractHash")
+
+ // ParamsStoreKeyBridgeContractAddress stores the contract address
+ ParamsStoreKeyBridgeContractAddress = []byte("BridgeContractAddress")
+
+ // ParamsStoreKeyBridgeContractChainID stores the bridge chain id
+ ParamsStoreKeyBridgeContractChainID = []byte("BridgeChainID")
+
+ // ParamsStoreKeySignedSignerSetTxsWindow stores the signed blocks window
+ ParamsStoreKeySignedSignerSetTxsWindow = []byte("SignedSignerSetTxWindow")
+
+ // ParamsStoreKeySignedBatchesWindow stores the signed blocks window
+ ParamsStoreKeySignedBatchesWindow = []byte("SignedBatchesWindow")
+
+ // ParamsStoreKeyEthereumSignaturesWindow stores the signed blocks window
+ ParamsStoreKeyEthereumSignaturesWindow = []byte("EthereumSignaturesWindow")
+
+ // ParamsStoreKeyTargetEthTxTimeout stores the target ethereum transaction timeout
+ ParamsStoreKeyTargetEthTxTimeout = []byte("TargetEthTxTimeout")
+
+ // ParamsStoreKeyAverageBlockTime stores the signed blocks window
+ ParamsStoreKeyAverageBlockTime = []byte("AverageBlockTime")
+
+ // ParamsStoreKeyAverageEthereumBlockTime stores the signed blocks window
+ ParamsStoreKeyAverageEthereumBlockTime = []byte("AverageEthereumBlockTime")
+
+ // ParamsStoreSlashFractionSignerSetTx stores the slash fraction valset
+ ParamsStoreSlashFractionSignerSetTx = []byte("SlashFractionSignerSetTx")
+
+ // ParamsStoreSlashFractionBatch stores the slash fraction Batch
+ ParamsStoreSlashFractionBatch = []byte("SlashFractionBatch")
+
+ // ParamsStoreSlashFractionEthereumSignature stores the slash fraction ethereum siganture
+ ParamsStoreSlashFractionEthereumSignature = []byte("SlashFractionEthereumSignature")
+
+ // ParamsStoreSlashFractionConflictingEthereumSignature stores the slash fraction ConflictingEthereumSignature
+ ParamsStoreSlashFractionConflictingEthereumSignature = []byte("SlashFractionConflictingEthereumSignature")
+
+ // ParamStoreUnbondSlashingSignerSetTxsWindow stores unbond slashing valset window
+ ParamStoreUnbondSlashingSignerSetTxsWindow = []byte("UnbondSlashingSignerSetTxsWindow")
+
+ // Ensure that params implements the proper interface
+ _ paramtypes.ParamSet = &Params{}
+)
+
+func (gs *GenesisState) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
+ for _, otx := range gs.OutgoingTxs {
+ var outgoing OutgoingTx
+ if err := unpacker.UnpackAny(otx, &outgoing); err != nil {
+ return err
+ }
+ }
+ for _, sig := range gs.Confirmations {
+ var signature EthereumTxConfirmation
+ if err := unpacker.UnpackAny(sig, &signature); err != nil {
+ return err
+ }
+ }
+ for _, evr := range gs.EthereumEventVoteRecords {
+ if err := evr.UnpackInterfaces(unpacker); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func EventVoteRecordPowerThreshold(totalPower sdk.Int) sdk.Int {
+ return sdk.NewInt(66).Mul(totalPower).Quo(sdk.NewInt(100))
+}
+
+// ValidateBasic validates genesis state by looping through the params and
+// calling their validation functions
+func (s GenesisState) ValidateBasic() error {
+ if err := s.Params.ValidateBasic(); err != nil {
+ return sdkerrors.Wrap(err, "params")
+ }
+ return nil
+}
+
+// DefaultGenesisState returns empty genesis state
+// TODO: set some better defaults here
+func DefaultGenesisState() *GenesisState {
+ return &GenesisState{
+ Params: DefaultParams(),
+ }
+}
+
+// DefaultParams returns a copy of the default params
+func DefaultParams() *Params {
+ return &Params{
+ GravityId: "defaultgravityid",
+ BridgeEthereumAddress: "0x0000000000000000000000000000000000000000",
+ SignedSignerSetTxsWindow: 10000,
+ SignedBatchesWindow: 10000,
+ EthereumSignaturesWindow: 10000,
+ TargetEthTxTimeout: 43200000,
+ AverageBlockTime: 5000,
+ AverageEthereumBlockTime: 15000,
+ SlashFractionSignerSetTx: sdk.NewDec(1).Quo(sdk.NewDec(1000)),
+ SlashFractionBatch: sdk.NewDec(1).Quo(sdk.NewDec(1000)),
+ SlashFractionEthereumSignature: sdk.NewDec(1).Quo(sdk.NewDec(1000)),
+ SlashFractionConflictingEthereumSignature: sdk.NewDec(1).Quo(sdk.NewDec(1000)),
+ UnbondSlashingSignerSetTxsWindow: 10000,
+ }
+}
+
+// ValidateBasic checks that the parameters have valid values.
+func (p Params) ValidateBasic() error {
+ if err := validateGravityID(p.GravityId); err != nil {
+ return sdkerrors.Wrap(err, "gravity id")
+ }
+ if err := validateContractHash(p.ContractSourceHash); err != nil {
+ return sdkerrors.Wrap(err, "contract hash")
+ }
+ if err := validateBridgeContractAddress(p.BridgeEthereumAddress); err != nil {
+ return sdkerrors.Wrap(err, "bridge contract address")
+ }
+ if err := validateBridgeChainID(p.BridgeChainId); err != nil {
+ return sdkerrors.Wrap(err, "bridge chain id")
+ }
+ if err := validateTargetEthTxTimeout(p.TargetEthTxTimeout); err != nil {
+ return sdkerrors.Wrap(err, "Batch timeout")
+ }
+ if err := validateAverageBlockTime(p.AverageBlockTime); err != nil {
+ return sdkerrors.Wrap(err, "Block time")
+ }
+ if err := validateAverageEthereumBlockTime(p.AverageEthereumBlockTime); err != nil {
+ return sdkerrors.Wrap(err, "Ethereum block time")
+ }
+ if err := validateSignedSignerSetTxsWindow(p.SignedSignerSetTxsWindow); err != nil {
+ return sdkerrors.Wrap(err, "signed blocks window")
+ }
+ if err := validateSignedBatchesWindow(p.SignedBatchesWindow); err != nil {
+ return sdkerrors.Wrap(err, "signed blocks window")
+ }
+ if err := validateEthereumSignaturesWindow(p.EthereumSignaturesWindow); err != nil {
+ return sdkerrors.Wrap(err, "signed blocks window")
+ }
+ if err := validateSlashFractionSignerSetTx(p.SlashFractionSignerSetTx); err != nil {
+ return sdkerrors.Wrap(err, "slash fraction signersettx")
+ }
+ if err := validateSlashFractionBatch(p.SlashFractionBatch); err != nil {
+ return sdkerrors.Wrap(err, "slash fraction batch tx")
+ }
+ if err := validateSlashFractionEthereumSignature(p.SlashFractionEthereumSignature); err != nil {
+ return sdkerrors.Wrap(err, "slash fraction ethereum signature")
+ }
+ if err := validateSlashFractionConflictingEthereumSignature(p.SlashFractionConflictingEthereumSignature); err != nil {
+ return sdkerrors.Wrap(err, "slash fraction conflicting ethereum signature")
+ }
+ if err := validateUnbondSlashingSignerSetTxsWindow(p.UnbondSlashingSignerSetTxsWindow); err != nil {
+ return sdkerrors.Wrap(err, "unbond slashing signersettx window")
+ }
+
+ return nil
+}
+
+// ParamKeyTable for auth module
+func ParamKeyTable() paramtypes.KeyTable {
+ return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
+}
+
+// ParamSetPairs implements the ParamSet interface and returns all the key/value pairs
+// pairs of auth module's parameters.
+func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
+ return paramtypes.ParamSetPairs{
+ paramtypes.NewParamSetPair(ParamsStoreKeyGravityID, &p.GravityId, validateGravityID),
+ paramtypes.NewParamSetPair(ParamsStoreKeyContractHash, &p.ContractSourceHash, validateContractHash),
+ paramtypes.NewParamSetPair(ParamsStoreKeyBridgeContractAddress, &p.BridgeEthereumAddress, validateBridgeContractAddress),
+ paramtypes.NewParamSetPair(ParamsStoreKeyBridgeContractChainID, &p.BridgeChainId, validateBridgeChainID),
+ paramtypes.NewParamSetPair(ParamsStoreKeySignedSignerSetTxsWindow, &p.SignedSignerSetTxsWindow, validateSignedSignerSetTxsWindow),
+ paramtypes.NewParamSetPair(ParamsStoreKeySignedBatchesWindow, &p.SignedBatchesWindow, validateSignedBatchesWindow),
+ paramtypes.NewParamSetPair(ParamsStoreKeyEthereumSignaturesWindow, &p.EthereumSignaturesWindow, validateEthereumSignaturesWindow),
+ paramtypes.NewParamSetPair(ParamsStoreKeyAverageBlockTime, &p.AverageBlockTime, validateAverageBlockTime),
+ paramtypes.NewParamSetPair(ParamsStoreKeyTargetEthTxTimeout, &p.TargetEthTxTimeout, validateTargetEthTxTimeout),
+ paramtypes.NewParamSetPair(ParamsStoreKeyAverageEthereumBlockTime, &p.AverageEthereumBlockTime, validateAverageEthereumBlockTime),
+ paramtypes.NewParamSetPair(ParamsStoreSlashFractionSignerSetTx, &p.SlashFractionSignerSetTx, validateSlashFractionSignerSetTx),
+ paramtypes.NewParamSetPair(ParamsStoreSlashFractionBatch, &p.SlashFractionBatch, validateSlashFractionBatch),
+ paramtypes.NewParamSetPair(ParamsStoreSlashFractionEthereumSignature, &p.SlashFractionEthereumSignature, validateSlashFractionEthereumSignature),
+ paramtypes.NewParamSetPair(ParamsStoreSlashFractionConflictingEthereumSignature, &p.SlashFractionConflictingEthereumSignature, validateSlashFractionConflictingEthereumSignature),
+ paramtypes.NewParamSetPair(ParamStoreUnbondSlashingSignerSetTxsWindow, &p.UnbondSlashingSignerSetTxsWindow, validateUnbondSlashingSignerSetTxsWindow),
+ }
+}
+
+// Equal returns a boolean determining if two Params types are identical.
+func (p Params) Equal(p2 Params) bool {
+ pb, err := p.Marshal()
+ if err != nil {
+ panic(err)
+ }
+ p2b, err := p2.Marshal()
+ if err != nil {
+ panic(err)
+ }
+ return bytes.Equal(pb, p2b)
+}
+
+func validateGravityID(i interface{}) error {
+ v, ok := i.(string)
+ if !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ if _, err := strToFixByteArray(v); err != nil {
+ return err
+ }
+ return nil
+}
+
+func validateContractHash(i interface{}) error {
+ // TODO: should we validate that the input here is a properly formatted
+ // SHA256 (or other) hash?
+ if _, ok := i.(string); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func validateBridgeChainID(i interface{}) error {
+ if _, ok := i.(uint64); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func validateTargetEthTxTimeout(i interface{}) error {
+ val, ok := i.(uint64)
+ if !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ } else if val < 60000 {
+ return fmt.Errorf("invalid target batch timeout, less than 60 seconds is too short")
+ }
+ return nil
+}
+
+func validateAverageBlockTime(i interface{}) error {
+ val, ok := i.(uint64)
+ if !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ } else if val < 100 {
+ return fmt.Errorf("invalid average Cosmos block time, too short for latency limitations")
+ }
+ return nil
+}
+
+func validateAverageEthereumBlockTime(i interface{}) error {
+ val, ok := i.(uint64)
+ if !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ } else if val < 100 {
+ return fmt.Errorf("invalid average Ethereum block time, too short for latency limitations")
+ }
+ return nil
+}
+
+func validateBridgeContractAddress(i interface{}) error {
+ v, ok := i.(string)
+ if !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ if !common.IsHexAddress(v) {
+ return fmt.Errorf("not an ethereum address: %s", v)
+ }
+ return nil
+}
+
+func validateSignedSignerSetTxsWindow(i interface{}) error {
+ // TODO: do we want to set some bounds on this value?
+ if _, ok := i.(uint64); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func validateUnbondSlashingSignerSetTxsWindow(i interface{}) error {
+ // TODO: do we want to set some bounds on this value?
+ if _, ok := i.(uint64); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func validateSlashFractionSignerSetTx(i interface{}) error {
+ // TODO: do we want to set some bounds on this value?
+ if _, ok := i.(sdk.Dec); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func validateSignedBatchesWindow(i interface{}) error {
+ // TODO: do we want to set some bounds on this value?
+ if _, ok := i.(uint64); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func validateEthereumSignaturesWindow(i interface{}) error {
+ // TODO: do we want to set some bounds on this value?
+ if _, ok := i.(uint64); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func validateSlashFractionBatch(i interface{}) error {
+ // TODO: do we want to set some bounds on this value?
+ if _, ok := i.(sdk.Dec); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func validateSlashFractionEthereumSignature(i interface{}) error {
+ // TODO: do we want to set some bounds on this value?
+ if _, ok := i.(sdk.Dec); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func validateSlashFractionConflictingEthereumSignature(i interface{}) error {
+ // TODO: do we want to set some bounds on this value?
+ if _, ok := i.(sdk.Dec); !ok {
+ return fmt.Errorf("invalid parameter type: %T", i)
+ }
+ return nil
+}
+
+func strToFixByteArray(s string) ([32]byte, error) {
+ var out [32]byte
+ if len([]byte(s)) > 32 {
+ return out, fmt.Errorf("string too long")
+ }
+ copy(out[:], s)
+ return out, nil
+}
+
+func byteArrayToFixByteArray(b []byte) (out [32]byte, err error) {
+ if len(b) > 32 {
+ return out, fmt.Errorf("array too long")
+ }
+ copy(out[:], b)
+ return out, nil
+}
diff --git a/module/x/gravity/types/genesis.pb.go b/module/x/gravity/types/genesis.pb.go
new file mode 100644
index 0000000..5bfbc6f
--- /dev/null
+++ b/module/x/gravity/types/genesis.pb.go
@@ -0,0 +1,1817 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: gravity/v1/genesis.proto
+
+package types
+
+import (
+ fmt "fmt"
+ types "github.com/cosmos/cosmos-sdk/codec/types"
+ github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
+ _ "github.com/gogo/protobuf/gogoproto"
+ proto "github.com/gogo/protobuf/proto"
+ io "io"
+ math "math"
+ math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// Params represent the Gravity genesis and store parameters
+// gravity_id:
+// a random 32 byte value to prevent signature reuse, for example if the
+// cosmos validators decided to use the same Ethereum keys for another chain
+// also running Gravity we would not want it to be possible to play a deposit
+// from chain A back on chain B's Gravity. This value IS USED ON ETHEREUM so
+// it must be set in your genesis.json before launch and not changed after
+// deploying Gravity
+//
+// contract_hash:
+// the code hash of a known good version of the Gravity contract
+// solidity code. This can be used to verify the correct version
+// of the contract has been deployed. This is a reference value for
+// goernance action only it is never read by any Gravity code
+//
+// bridge_ethereum_address:
+// is address of the bridge contract on the Ethereum side, this is a
+// reference value for governance only and is not actually used by any
+// Gravity code
+//
+// bridge_chain_id:
+// the unique identifier of the Ethereum chain, this is a reference value
+// only and is not actually used by any Gravity code
+//
+// These reference values may be used by future Gravity client implemetnations
+// to allow for saftey features or convenience features like the Gravity address
+// in your relayer. A relayer would require a configured Gravity address if
+// governance had not set the address on the chain it was relaying for.
+//
+// signed_signer_set_txs_window
+// signed_batches_window
+// signed_ethereum_signatures_window
+//
+// These values represent the time in blocks that a validator has to submit
+// a signature for a batch or valset, or to submit a ethereum_signature for a
+// particular attestation nonce. In the case of attestations this clock starts
+// when the attestation is created, but only allows for slashing once the event
+// has passed
+//
+// target_eth_tx_timeout:
+//
+// This is the 'target' value for when ethereum transactions time out, this is a target
+// because Ethereum is a probabilistic chain and you can't say for sure what the
+// block frequency is ahead of time.
+//
+// average_block_time
+// average_ethereum_block_time
+//
+// These values are the average Cosmos block time and Ethereum block time
+// respectively and they are used to compute what the target batch timeout is. It
+// is important that governance updates these in case of any major, prolonged
+// change in the time it takes to produce a block
+//
+// slash_fraction_signer_set_tx
+// slash_fraction_batch
+// slash_fraction_ethereum_signature
+// slash_fraction_conflicting_ethereum_signature
+//
+// The slashing fractions for the various gravity related slashing conditions.
+// The first three refer to not submitting a particular message, the third for
+// submitting a different ethereum_signature for the same Ethereum event
+type Params struct {
+ GravityId string `protobuf:"bytes,1,opt,name=gravity_id,json=gravityId,proto3" json:"gravity_id,omitempty"`
+ ContractSourceHash string `protobuf:"bytes,2,opt,name=contract_source_hash,json=contractSourceHash,proto3" json:"contract_source_hash,omitempty"`
+ BridgeEthereumAddress string `protobuf:"bytes,4,opt,name=bridge_ethereum_address,json=bridgeEthereumAddress,proto3" json:"bridge_ethereum_address,omitempty"`
+ BridgeChainId uint64 `protobuf:"varint,5,opt,name=bridge_chain_id,json=bridgeChainId,proto3" json:"bridge_chain_id,omitempty"`
+ SignedSignerSetTxsWindow uint64 `protobuf:"varint,6,opt,name=signed_signer_set_txs_window,json=signedSignerSetTxsWindow,proto3" json:"signed_signer_set_txs_window,omitempty"`
+ SignedBatchesWindow uint64 `protobuf:"varint,7,opt,name=signed_batches_window,json=signedBatchesWindow,proto3" json:"signed_batches_window,omitempty"`
+ EthereumSignaturesWindow uint64 `protobuf:"varint,8,opt,name=ethereum_signatures_window,json=ethereumSignaturesWindow,proto3" json:"ethereum_signatures_window,omitempty"`
+ TargetEthTxTimeout uint64 `protobuf:"varint,10,opt,name=target_eth_tx_timeout,json=targetEthTxTimeout,proto3" json:"target_eth_tx_timeout,omitempty"`
+ AverageBlockTime uint64 `protobuf:"varint,11,opt,name=average_block_time,json=averageBlockTime,proto3" json:"average_block_time,omitempty"`
+ AverageEthereumBlockTime uint64 `protobuf:"varint,12,opt,name=average_ethereum_block_time,json=averageEthereumBlockTime,proto3" json:"average_ethereum_block_time,omitempty"`
+ // TODO: slash fraction for contract call txs too
+ SlashFractionSignerSetTx github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,13,opt,name=slash_fraction_signer_set_tx,json=slashFractionSignerSetTx,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"slash_fraction_signer_set_tx"`
+ SlashFractionBatch github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,14,opt,name=slash_fraction_batch,json=slashFractionBatch,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"slash_fraction_batch"`
+ SlashFractionEthereumSignature github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,15,opt,name=slash_fraction_ethereum_signature,json=slashFractionEthereumSignature,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"slash_fraction_ethereum_signature"`
+ SlashFractionConflictingEthereumSignature github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,16,opt,name=slash_fraction_conflicting_ethereum_signature,json=slashFractionConflictingEthereumSignature,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"slash_fraction_conflicting_ethereum_signature"`
+ UnbondSlashingSignerSetTxsWindow uint64 `protobuf:"varint,17,opt,name=unbond_slashing_signer_set_txs_window,json=unbondSlashingSignerSetTxsWindow,proto3" json:"unbond_slashing_signer_set_txs_window,omitempty"`
+}
+
+func (m *Params) Reset() { *m = Params{} }
+func (m *Params) String() string { return proto.CompactTextString(m) }
+func (*Params) ProtoMessage() {}
+func (*Params) Descriptor() ([]byte, []int) {
+ return fileDescriptor_387b0aba880adb60, []int{0}
+}
+func (m *Params) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_Params.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *Params) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Params.Merge(m, src)
+}
+func (m *Params) XXX_Size() int {
+ return m.Size()
+}
+func (m *Params) XXX_DiscardUnknown() {
+ xxx_messageInfo_Params.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Params proto.InternalMessageInfo
+
+func (m *Params) GetGravityId() string {
+ if m != nil {
+ return m.GravityId
+ }
+ return ""
+}
+
+func (m *Params) GetContractSourceHash() string {
+ if m != nil {
+ return m.ContractSourceHash
+ }
+ return ""
+}
+
+func (m *Params) GetBridgeEthereumAddress() string {
+ if m != nil {
+ return m.BridgeEthereumAddress
+ }
+ return ""
+}
+
+func (m *Params) GetBridgeChainId() uint64 {
+ if m != nil {
+ return m.BridgeChainId
+ }
+ return 0
+}
+
+func (m *Params) GetSignedSignerSetTxsWindow() uint64 {
+ if m != nil {
+ return m.SignedSignerSetTxsWindow
+ }
+ return 0
+}
+
+func (m *Params) GetSignedBatchesWindow() uint64 {
+ if m != nil {
+ return m.SignedBatchesWindow
+ }
+ return 0
+}
+
+func (m *Params) GetEthereumSignaturesWindow() uint64 {
+ if m != nil {
+ return m.EthereumSignaturesWindow
+ }
+ return 0
+}
+
+func (m *Params) GetTargetEthTxTimeout() uint64 {
+ if m != nil {
+ return m.TargetEthTxTimeout
+ }
+ return 0
+}
+
+func (m *Params) GetAverageBlockTime() uint64 {
+ if m != nil {
+ return m.AverageBlockTime
+ }
+ return 0
+}
+
+func (m *Params) GetAverageEthereumBlockTime() uint64 {
+ if m != nil {
+ return m.AverageEthereumBlockTime
+ }
+ return 0
+}
+
+func (m *Params) GetUnbondSlashingSignerSetTxsWindow() uint64 {
+ if m != nil {
+ return m.UnbondSlashingSignerSetTxsWindow
+ }
+ return 0
+}
+
+// GenesisState struct
+// TODO: this need to be audited and potentially simplified using the new
+// interfaces
+type GenesisState struct {
+ Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"`
+ LastObservedEventNonce uint64 `protobuf:"varint,2,opt,name=last_observed_event_nonce,json=lastObservedEventNonce,proto3" json:"last_observed_event_nonce,omitempty"`
+ OutgoingTxs []*types.Any `protobuf:"bytes,3,rep,name=outgoing_txs,json=outgoingTxs,proto3" json:"outgoing_txs,omitempty"`
+ Confirmations []*types.Any `protobuf:"bytes,4,rep,name=confirmations,proto3" json:"confirmations,omitempty"`
+ EthereumEventVoteRecords []*EthereumEventVoteRecord `protobuf:"bytes,9,rep,name=ethereum_event_vote_records,json=ethereumEventVoteRecords,proto3" json:"ethereum_event_vote_records,omitempty"`
+ DelegateKeys []*MsgDelegateKeys `protobuf:"bytes,10,rep,name=delegate_keys,json=delegateKeys,proto3" json:"delegate_keys,omitempty"`
+ Erc20ToDenoms []*ERC20ToDenom `protobuf:"bytes,11,rep,name=erc20_to_denoms,json=erc20ToDenoms,proto3" json:"erc20_to_denoms,omitempty"`
+ UnbatchedSendToEthereumTxs []*SendToEthereum `protobuf:"bytes,12,rep,name=unbatched_send_to_ethereum_txs,json=unbatchedSendToEthereumTxs,proto3" json:"unbatched_send_to_ethereum_txs,omitempty"`
+}
+
+func (m *GenesisState) Reset() { *m = GenesisState{} }
+func (m *GenesisState) String() string { return proto.CompactTextString(m) }
+func (*GenesisState) ProtoMessage() {}
+func (*GenesisState) Descriptor() ([]byte, []int) {
+ return fileDescriptor_387b0aba880adb60, []int{1}
+}
+func (m *GenesisState) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *GenesisState) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_GenesisState.Merge(m, src)
+}
+func (m *GenesisState) XXX_Size() int {
+ return m.Size()
+}
+func (m *GenesisState) XXX_DiscardUnknown() {
+ xxx_messageInfo_GenesisState.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_GenesisState proto.InternalMessageInfo
+
+func (m *GenesisState) GetParams() *Params {
+ if m != nil {
+ return m.Params
+ }
+ return nil
+}
+
+func (m *GenesisState) GetLastObservedEventNonce() uint64 {
+ if m != nil {
+ return m.LastObservedEventNonce
+ }
+ return 0
+}
+
+func (m *GenesisState) GetOutgoingTxs() []*types.Any {
+ if m != nil {
+ return m.OutgoingTxs
+ }
+ return nil
+}
+
+func (m *GenesisState) GetConfirmations() []*types.Any {
+ if m != nil {
+ return m.Confirmations
+ }
+ return nil
+}
+
+func (m *GenesisState) GetEthereumEventVoteRecords() []*EthereumEventVoteRecord {
+ if m != nil {
+ return m.EthereumEventVoteRecords
+ }
+ return nil
+}
+
+func (m *GenesisState) GetDelegateKeys() []*MsgDelegateKeys {
+ if m != nil {
+ return m.DelegateKeys
+ }
+ return nil
+}
+
+func (m *GenesisState) GetErc20ToDenoms() []*ERC20ToDenom {
+ if m != nil {
+ return m.Erc20ToDenoms
+ }
+ return nil
+}
+
+func (m *GenesisState) GetUnbatchedSendToEthereumTxs() []*SendToEthereum {
+ if m != nil {
+ return m.UnbatchedSendToEthereumTxs
+ }
+ return nil
+}
+
+// This records the relationship between an ERC20 token and the denom
+// of the corresponding Cosmos originated asset
+type ERC20ToDenom struct {
+ Erc20 string `protobuf:"bytes,1,opt,name=erc20,proto3" json:"erc20,omitempty"`
+ Denom string `protobuf:"bytes,2,opt,name=denom,proto3" json:"denom,omitempty"`
+}
+
+func (m *ERC20ToDenom) Reset() { *m = ERC20ToDenom{} }
+func (m *ERC20ToDenom) String() string { return proto.CompactTextString(m) }
+func (*ERC20ToDenom) ProtoMessage() {}
+func (*ERC20ToDenom) Descriptor() ([]byte, []int) {
+ return fileDescriptor_387b0aba880adb60, []int{2}
+}
+func (m *ERC20ToDenom) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ERC20ToDenom) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ERC20ToDenom.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ERC20ToDenom) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ERC20ToDenom.Merge(m, src)
+}
+func (m *ERC20ToDenom) XXX_Size() int {
+ return m.Size()
+}
+func (m *ERC20ToDenom) XXX_DiscardUnknown() {
+ xxx_messageInfo_ERC20ToDenom.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ERC20ToDenom proto.InternalMessageInfo
+
+func (m *ERC20ToDenom) GetErc20() string {
+ if m != nil {
+ return m.Erc20
+ }
+ return ""
+}
+
+func (m *ERC20ToDenom) GetDenom() string {
+ if m != nil {
+ return m.Denom
+ }
+ return ""
+}
+
+func init() {
+ proto.RegisterType((*Params)(nil), "gravity.v1.Params")
+ proto.RegisterType((*GenesisState)(nil), "gravity.v1.GenesisState")
+ proto.RegisterType((*ERC20ToDenom)(nil), "gravity.v1.ERC20ToDenom")
+}
+
+func init() { proto.RegisterFile("gravity/v1/genesis.proto", fileDescriptor_387b0aba880adb60) }
+
+var fileDescriptor_387b0aba880adb60 = []byte{
+ // 907 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x6e, 0x1b, 0x45,
+ 0x14, 0xb6, 0xa9, 0x1b, 0x9a, 0xb1, 0x4d, 0xca, 0xe0, 0xc0, 0xd6, 0x29, 0xae, 0x09, 0xa2, 0x0a,
+ 0x88, 0xac, 0x13, 0x23, 0xf1, 0x13, 0x01, 0x6a, 0xf3, 0x03, 0x54, 0x08, 0x8a, 0xd6, 0x16, 0x48,
+ 0x5c, 0x30, 0x8c, 0x77, 0x4e, 0xc6, 0x4b, 0xec, 0x99, 0x68, 0x67, 0xd6, 0xb5, 0xef, 0x78, 0x84,
+ 0x3e, 0x0b, 0x8f, 0xc0, 0x55, 0x2f, 0x7b, 0x89, 0x10, 0xaa, 0x50, 0xf2, 0x22, 0x68, 0x7e, 0xd6,
+ 0x5e, 0x3b, 0xe5, 0x26, 0x57, 0xeb, 0x39, 0xdf, 0xf7, 0x9d, 0xf3, 0xcd, 0x1c, 0xcf, 0x19, 0x14,
+ 0xf0, 0x94, 0x4e, 0x12, 0x3d, 0xeb, 0x4c, 0xf6, 0x3b, 0x1c, 0x04, 0xa8, 0x44, 0x85, 0xe7, 0xa9,
+ 0xd4, 0x12, 0x23, 0x8f, 0x84, 0x93, 0xfd, 0x66, 0x83, 0x4b, 0x2e, 0x6d, 0xb8, 0x63, 0x7e, 0x39,
+ 0x46, 0x73, 0x49, 0xeb, 0xc9, 0x0e, 0xd9, 0x2c, 0x20, 0x63, 0xc5, 0x7d, 0xca, 0xe6, 0x1d, 0x2e,
+ 0x25, 0x1f, 0x41, 0xc7, 0xae, 0x06, 0xd9, 0x69, 0x87, 0x0a, 0xaf, 0xd8, 0xfe, 0xf3, 0x16, 0x5a,
+ 0xfb, 0x81, 0xa6, 0x74, 0xac, 0xf0, 0xdb, 0x28, 0x2f, 0x4d, 0x12, 0x16, 0x94, 0xdb, 0xe5, 0x9d,
+ 0xf5, 0x68, 0xdd, 0x47, 0x1e, 0x31, 0xbc, 0x87, 0x1a, 0xb1, 0x14, 0x3a, 0xa5, 0xb1, 0x26, 0x4a,
+ 0x66, 0x69, 0x0c, 0x64, 0x48, 0xd5, 0x30, 0x78, 0xc5, 0x12, 0x71, 0x8e, 0xf5, 0x2c, 0xf4, 0x0d,
+ 0x55, 0x43, 0xfc, 0x31, 0x7a, 0x6b, 0x90, 0x26, 0x8c, 0x03, 0x01, 0x3d, 0x84, 0x14, 0xb2, 0x31,
+ 0xa1, 0x8c, 0xa5, 0xa0, 0x54, 0x50, 0xb1, 0xa2, 0x4d, 0x07, 0x9f, 0x78, 0xf4, 0xa1, 0x03, 0xf1,
+ 0x7d, 0xb4, 0xe1, 0x75, 0xf1, 0x90, 0x26, 0xc2, 0xb8, 0xb9, 0xd9, 0x2e, 0xef, 0x54, 0xa2, 0xba,
+ 0x0b, 0x1f, 0x99, 0xe8, 0x23, 0x86, 0xbf, 0x44, 0x77, 0x55, 0xc2, 0x05, 0x30, 0x62, 0x3f, 0x29,
+ 0x51, 0xa0, 0x89, 0x9e, 0x2a, 0xf2, 0x24, 0x11, 0x4c, 0x3e, 0x09, 0xd6, 0xac, 0x28, 0x70, 0x9c,
+ 0x9e, 0xa5, 0xf4, 0x40, 0xf7, 0xa7, 0xea, 0x27, 0x8b, 0xe3, 0x2e, 0xda, 0xf4, 0xfa, 0x01, 0xd5,
+ 0xf1, 0x10, 0xe6, 0xc2, 0x57, 0xad, 0xf0, 0x0d, 0x07, 0x1e, 0x3a, 0xcc, 0x6b, 0x3e, 0x47, 0xcd,
+ 0xf9, 0x66, 0x0c, 0x4e, 0x75, 0x96, 0x2e, 0x84, 0xb7, 0x5c, 0xc5, 0x9c, 0xd1, 0x9b, 0x13, 0xbc,
+ 0x7a, 0x1f, 0x6d, 0x6a, 0x9a, 0x72, 0xd0, 0xe6, 0x44, 0x88, 0x9e, 0x12, 0x9d, 0x8c, 0x41, 0x66,
+ 0x3a, 0x40, 0x56, 0x88, 0x1d, 0x78, 0xa2, 0x87, 0xfd, 0x69, 0xdf, 0x21, 0xf8, 0x43, 0x84, 0xe9,
+ 0x04, 0x52, 0xca, 0x81, 0x0c, 0x46, 0x32, 0x3e, 0xb3, 0x92, 0xa0, 0x6a, 0xf9, 0xb7, 0x3d, 0x72,
+ 0x68, 0x00, 0x23, 0xc0, 0x5f, 0xa0, 0xad, 0x9c, 0x3d, 0xb7, 0x59, 0x90, 0xd5, 0x9c, 0x3f, 0x4f,
+ 0xc9, 0xcf, 0x7d, 0x21, 0x17, 0xe8, 0xae, 0x1a, 0x51, 0x35, 0x24, 0xa7, 0xa6, 0x95, 0x89, 0x14,
+ 0xcb, 0x27, 0x1b, 0xd4, 0xdb, 0xe5, 0x9d, 0xda, 0x61, 0xf8, 0xec, 0xc5, 0xbd, 0xd2, 0xdf, 0x2f,
+ 0xee, 0xdd, 0xe7, 0x89, 0x1e, 0x66, 0x83, 0x30, 0x96, 0xe3, 0x4e, 0x2c, 0xd5, 0x58, 0x2a, 0xff,
+ 0xd9, 0x55, 0xec, 0xac, 0xa3, 0x67, 0xe7, 0xa0, 0xc2, 0x63, 0x88, 0xa3, 0xc0, 0xe6, 0xfc, 0xca,
+ 0xa7, 0x2c, 0x34, 0x02, 0xff, 0x8a, 0x1a, 0x2b, 0xf5, 0x6c, 0x27, 0x82, 0xd7, 0xae, 0x55, 0x07,
+ 0x2f, 0xd5, 0xb1, 0x7d, 0xc3, 0x33, 0xf4, 0xce, 0x4a, 0x85, 0xab, 0xed, 0x0b, 0x36, 0xae, 0x55,
+ 0xae, 0xb5, 0x54, 0xee, 0x64, 0xb5, 0xe7, 0xf8, 0x69, 0x19, 0xed, 0xae, 0xd4, 0x8e, 0xa5, 0x38,
+ 0x1d, 0x25, 0xb1, 0x4e, 0x04, 0x7f, 0x99, 0x8f, 0xdb, 0xd7, 0xf2, 0xf1, 0xfe, 0x92, 0x8f, 0xa3,
+ 0x45, 0x89, 0xab, 0x96, 0x1e, 0xa3, 0xf7, 0x32, 0x31, 0x90, 0x82, 0x11, 0xab, 0x31, 0x36, 0x5e,
+ 0x7e, 0x75, 0x5e, 0xb7, 0x7f, 0x94, 0xb6, 0x23, 0xf7, 0x3c, 0xf7, 0xea, 0x15, 0x3a, 0xa8, 0xfc,
+ 0xfe, 0x4f, 0xbb, 0xb4, 0xfd, 0x47, 0x05, 0xd5, 0xbe, 0x76, 0x43, 0xac, 0xa7, 0xa9, 0x06, 0xfc,
+ 0x01, 0x5a, 0x3b, 0xb7, 0x43, 0xc5, 0x8e, 0x91, 0x6a, 0x17, 0x87, 0x8b, 0xa1, 0x16, 0xba, 0x71,
+ 0x13, 0x79, 0x06, 0xfe, 0x0c, 0xdd, 0x19, 0x51, 0xa5, 0x89, 0x1c, 0x28, 0x48, 0x27, 0xc0, 0x08,
+ 0x4c, 0x40, 0x68, 0x22, 0xa4, 0x88, 0xc1, 0x0e, 0x97, 0x4a, 0xf4, 0xa6, 0x21, 0x3c, 0xf6, 0xf8,
+ 0x89, 0x81, 0xbf, 0x37, 0x28, 0xfe, 0x04, 0xd5, 0x64, 0xa6, 0xb9, 0x34, 0xfb, 0xd0, 0x53, 0x15,
+ 0xdc, 0x68, 0xdf, 0xd8, 0xa9, 0x76, 0x1b, 0xa1, 0x1b, 0x77, 0x61, 0x3e, 0xee, 0xc2, 0x87, 0x62,
+ 0x16, 0x55, 0x73, 0x66, 0x7f, 0xaa, 0xf0, 0x01, 0xaa, 0x9b, 0x56, 0x24, 0xe9, 0x98, 0x9a, 0x33,
+ 0x33, 0xf3, 0xe8, 0xff, 0x95, 0xcb, 0x54, 0x3c, 0x40, 0x5b, 0xf3, 0xd6, 0x39, 0xab, 0x13, 0xa9,
+ 0x81, 0xa4, 0x10, 0xcb, 0x94, 0xa9, 0x60, 0xdd, 0x66, 0x7a, 0xb7, 0xb8, 0xe1, 0xbc, 0x0f, 0xd6,
+ 0xf9, 0x8f, 0x52, 0x43, 0x64, 0xb9, 0x8b, 0x39, 0xb1, 0x02, 0x28, 0xfc, 0x00, 0xd5, 0x19, 0x8c,
+ 0x80, 0x53, 0x0d, 0xe4, 0x0c, 0x66, 0x2a, 0x40, 0x36, 0xeb, 0x56, 0x31, 0xeb, 0x77, 0x8a, 0x1f,
+ 0x7b, 0xce, 0xb7, 0x30, 0x53, 0x51, 0x8d, 0x15, 0x56, 0xf8, 0x01, 0xda, 0x80, 0x34, 0xee, 0xee,
+ 0x11, 0x2d, 0x09, 0x03, 0x21, 0xc7, 0x2a, 0xa8, 0xda, 0x1c, 0xc1, 0x92, 0xb3, 0xe8, 0xa8, 0xbb,
+ 0xd7, 0x97, 0xc7, 0x86, 0x10, 0xd5, 0xad, 0xc0, 0xaf, 0x14, 0xfe, 0x05, 0xb5, 0x32, 0xe1, 0x06,
+ 0x23, 0x23, 0x0a, 0x04, 0x33, 0xa9, 0xe6, 0x3b, 0x37, 0xc7, 0x5d, 0xb3, 0x09, 0x9b, 0xc5, 0x84,
+ 0x3d, 0x10, 0xac, 0x2f, 0xf3, 0x0d, 0x47, 0xcd, 0x79, 0x86, 0x65, 0xa0, 0x3f, 0x55, 0xdb, 0x07,
+ 0xa8, 0x56, 0x2c, 0x8f, 0x1b, 0xe8, 0xa6, 0x35, 0xe0, 0x5f, 0x1e, 0xb7, 0x30, 0x51, 0x6b, 0xdf,
+ 0x3f, 0x33, 0x6e, 0x71, 0x18, 0x3d, 0xbb, 0x68, 0x95, 0x9f, 0x5f, 0xb4, 0xca, 0xff, 0x5e, 0xb4,
+ 0xca, 0x4f, 0x2f, 0x5b, 0xa5, 0xe7, 0x97, 0xad, 0xd2, 0x5f, 0x97, 0xad, 0xd2, 0xcf, 0x9f, 0x16,
+ 0x2e, 0xcd, 0x39, 0x70, 0x3e, 0xfb, 0x6d, 0x92, 0xbf, 0x91, 0xbb, 0xee, 0xf5, 0xe8, 0x8c, 0x25,
+ 0xcb, 0x46, 0xd0, 0x99, 0xe6, 0x71, 0x77, 0x95, 0x06, 0x6b, 0xb6, 0xe9, 0x1f, 0xfd, 0x17, 0x00,
+ 0x00, 0xff, 0xff, 0x37, 0xc4, 0xc6, 0x03, 0x9a, 0x07, 0x00, 0x00,
+}
+
+func (m *Params) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *Params) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.UnbondSlashingSignerSetTxsWindow != 0 {
+ i = encodeVarintGenesis(dAtA, i, uint64(m.UnbondSlashingSignerSetTxsWindow))
+ i--
+ dAtA[i] = 0x1
+ i--
+ dAtA[i] = 0x88
+ }
+ {
+ size := m.SlashFractionConflictingEthereumSignature.Size()
+ i -= size
+ if _, err := m.SlashFractionConflictingEthereumSignature.MarshalTo(dAtA[i:]); err != nil {
+ return 0, err
+ }
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1
+ i--
+ dAtA[i] = 0x82
+ {
+ size := m.SlashFractionEthereumSignature.Size()
+ i -= size
+ if _, err := m.SlashFractionEthereumSignature.MarshalTo(dAtA[i:]); err != nil {
+ return 0, err
+ }
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x7a
+ {
+ size := m.SlashFractionBatch.Size()
+ i -= size
+ if _, err := m.SlashFractionBatch.MarshalTo(dAtA[i:]); err != nil {
+ return 0, err
+ }
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x72
+ {
+ size := m.SlashFractionSignerSetTx.Size()
+ i -= size
+ if _, err := m.SlashFractionSignerSetTx.MarshalTo(dAtA[i:]); err != nil {
+ return 0, err
+ }
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x6a
+ if m.AverageEthereumBlockTime != 0 {
+ i = encodeVarintGenesis(dAtA, i, uint64(m.AverageEthereumBlockTime))
+ i--
+ dAtA[i] = 0x60
+ }
+ if m.AverageBlockTime != 0 {
+ i = encodeVarintGenesis(dAtA, i, uint64(m.AverageBlockTime))
+ i--
+ dAtA[i] = 0x58
+ }
+ if m.TargetEthTxTimeout != 0 {
+ i = encodeVarintGenesis(dAtA, i, uint64(m.TargetEthTxTimeout))
+ i--
+ dAtA[i] = 0x50
+ }
+ if m.EthereumSignaturesWindow != 0 {
+ i = encodeVarintGenesis(dAtA, i, uint64(m.EthereumSignaturesWindow))
+ i--
+ dAtA[i] = 0x40
+ }
+ if m.SignedBatchesWindow != 0 {
+ i = encodeVarintGenesis(dAtA, i, uint64(m.SignedBatchesWindow))
+ i--
+ dAtA[i] = 0x38
+ }
+ if m.SignedSignerSetTxsWindow != 0 {
+ i = encodeVarintGenesis(dAtA, i, uint64(m.SignedSignerSetTxsWindow))
+ i--
+ dAtA[i] = 0x30
+ }
+ if m.BridgeChainId != 0 {
+ i = encodeVarintGenesis(dAtA, i, uint64(m.BridgeChainId))
+ i--
+ dAtA[i] = 0x28
+ }
+ if len(m.BridgeEthereumAddress) > 0 {
+ i -= len(m.BridgeEthereumAddress)
+ copy(dAtA[i:], m.BridgeEthereumAddress)
+ i = encodeVarintGenesis(dAtA, i, uint64(len(m.BridgeEthereumAddress)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.ContractSourceHash) > 0 {
+ i -= len(m.ContractSourceHash)
+ copy(dAtA[i:], m.ContractSourceHash)
+ i = encodeVarintGenesis(dAtA, i, uint64(len(m.ContractSourceHash)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.GravityId) > 0 {
+ i -= len(m.GravityId)
+ copy(dAtA[i:], m.GravityId)
+ i = encodeVarintGenesis(dAtA, i, uint64(len(m.GravityId)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *GenesisState) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.UnbatchedSendToEthereumTxs) > 0 {
+ for iNdEx := len(m.UnbatchedSendToEthereumTxs) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.UnbatchedSendToEthereumTxs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x62
+ }
+ }
+ if len(m.Erc20ToDenoms) > 0 {
+ for iNdEx := len(m.Erc20ToDenoms) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Erc20ToDenoms[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x5a
+ }
+ }
+ if len(m.DelegateKeys) > 0 {
+ for iNdEx := len(m.DelegateKeys) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.DelegateKeys[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x52
+ }
+ }
+ if len(m.EthereumEventVoteRecords) > 0 {
+ for iNdEx := len(m.EthereumEventVoteRecords) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.EthereumEventVoteRecords[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x4a
+ }
+ }
+ if len(m.Confirmations) > 0 {
+ for iNdEx := len(m.Confirmations) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Confirmations[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x22
+ }
+ }
+ if len(m.OutgoingTxs) > 0 {
+ for iNdEx := len(m.OutgoingTxs) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.OutgoingTxs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
+ }
+ }
+ if m.LastObservedEventNonce != 0 {
+ i = encodeVarintGenesis(dAtA, i, uint64(m.LastObservedEventNonce))
+ i--
+ dAtA[i] = 0x10
+ }
+ if m.Params != nil {
+ {
+ size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ERC20ToDenom) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ERC20ToDenom) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ERC20ToDenom) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Denom) > 0 {
+ i -= len(m.Denom)
+ copy(dAtA[i:], m.Denom)
+ i = encodeVarintGenesis(dAtA, i, uint64(len(m.Denom)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.Erc20) > 0 {
+ i -= len(m.Erc20)
+ copy(dAtA[i:], m.Erc20)
+ i = encodeVarintGenesis(dAtA, i, uint64(len(m.Erc20)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
+ offset -= sovGenesis(v)
+ base := offset
+ for v >= 1<<7 {
+ dAtA[offset] = uint8(v&0x7f | 0x80)
+ v >>= 7
+ offset++
+ }
+ dAtA[offset] = uint8(v)
+ return base
+}
+func (m *Params) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.GravityId)
+ if l > 0 {
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ l = len(m.ContractSourceHash)
+ if l > 0 {
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ l = len(m.BridgeEthereumAddress)
+ if l > 0 {
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ if m.BridgeChainId != 0 {
+ n += 1 + sovGenesis(uint64(m.BridgeChainId))
+ }
+ if m.SignedSignerSetTxsWindow != 0 {
+ n += 1 + sovGenesis(uint64(m.SignedSignerSetTxsWindow))
+ }
+ if m.SignedBatchesWindow != 0 {
+ n += 1 + sovGenesis(uint64(m.SignedBatchesWindow))
+ }
+ if m.EthereumSignaturesWindow != 0 {
+ n += 1 + sovGenesis(uint64(m.EthereumSignaturesWindow))
+ }
+ if m.TargetEthTxTimeout != 0 {
+ n += 1 + sovGenesis(uint64(m.TargetEthTxTimeout))
+ }
+ if m.AverageBlockTime != 0 {
+ n += 1 + sovGenesis(uint64(m.AverageBlockTime))
+ }
+ if m.AverageEthereumBlockTime != 0 {
+ n += 1 + sovGenesis(uint64(m.AverageEthereumBlockTime))
+ }
+ l = m.SlashFractionSignerSetTx.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ l = m.SlashFractionBatch.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ l = m.SlashFractionEthereumSignature.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ l = m.SlashFractionConflictingEthereumSignature.Size()
+ n += 2 + l + sovGenesis(uint64(l))
+ if m.UnbondSlashingSignerSetTxsWindow != 0 {
+ n += 2 + sovGenesis(uint64(m.UnbondSlashingSignerSetTxsWindow))
+ }
+ return n
+}
+
+func (m *GenesisState) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Params != nil {
+ l = m.Params.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ if m.LastObservedEventNonce != 0 {
+ n += 1 + sovGenesis(uint64(m.LastObservedEventNonce))
+ }
+ if len(m.OutgoingTxs) > 0 {
+ for _, e := range m.OutgoingTxs {
+ l = e.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ }
+ if len(m.Confirmations) > 0 {
+ for _, e := range m.Confirmations {
+ l = e.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ }
+ if len(m.EthereumEventVoteRecords) > 0 {
+ for _, e := range m.EthereumEventVoteRecords {
+ l = e.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ }
+ if len(m.DelegateKeys) > 0 {
+ for _, e := range m.DelegateKeys {
+ l = e.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ }
+ if len(m.Erc20ToDenoms) > 0 {
+ for _, e := range m.Erc20ToDenoms {
+ l = e.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ }
+ if len(m.UnbatchedSendToEthereumTxs) > 0 {
+ for _, e := range m.UnbatchedSendToEthereumTxs {
+ l = e.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *ERC20ToDenom) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Erc20)
+ if l > 0 {
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ l = len(m.Denom)
+ if l > 0 {
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ return n
+}
+
+func sovGenesis(x uint64) (n int) {
+ return (math_bits.Len64(x|1) + 6) / 7
+}
+func sozGenesis(x uint64) (n int) {
+ return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *Params) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: Params: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field GravityId", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.GravityId = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ContractSourceHash", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ContractSourceHash = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BridgeEthereumAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.BridgeEthereumAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 5:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BridgeChainId", wireType)
+ }
+ m.BridgeChainId = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.BridgeChainId |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 6:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SignedSignerSetTxsWindow", wireType)
+ }
+ m.SignedSignerSetTxsWindow = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.SignedSignerSetTxsWindow |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 7:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SignedBatchesWindow", wireType)
+ }
+ m.SignedBatchesWindow = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.SignedBatchesWindow |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 8:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumSignaturesWindow", wireType)
+ }
+ m.EthereumSignaturesWindow = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EthereumSignaturesWindow |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 10:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field TargetEthTxTimeout", wireType)
+ }
+ m.TargetEthTxTimeout = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.TargetEthTxTimeout |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 11:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field AverageBlockTime", wireType)
+ }
+ m.AverageBlockTime = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.AverageBlockTime |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 12:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field AverageEthereumBlockTime", wireType)
+ }
+ m.AverageEthereumBlockTime = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.AverageEthereumBlockTime |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 13:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SlashFractionSignerSetTx", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.SlashFractionSignerSetTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 14:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SlashFractionBatch", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.SlashFractionBatch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 15:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SlashFractionEthereumSignature", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.SlashFractionEthereumSignature.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 16:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SlashFractionConflictingEthereumSignature", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.SlashFractionConflictingEthereumSignature.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 17:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field UnbondSlashingSignerSetTxsWindow", wireType)
+ }
+ m.UnbondSlashingSignerSetTxsWindow = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.UnbondSlashingSignerSetTxsWindow |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenesis(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *GenesisState) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Params == nil {
+ m.Params = &Params{}
+ }
+ if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field LastObservedEventNonce", wireType)
+ }
+ m.LastObservedEventNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.LastObservedEventNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field OutgoingTxs", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.OutgoingTxs = append(m.OutgoingTxs, &types.Any{})
+ if err := m.OutgoingTxs[len(m.OutgoingTxs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Confirmations", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Confirmations = append(m.Confirmations, &types.Any{})
+ if err := m.Confirmations[len(m.Confirmations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 9:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumEventVoteRecords", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumEventVoteRecords = append(m.EthereumEventVoteRecords, &EthereumEventVoteRecord{})
+ if err := m.EthereumEventVoteRecords[len(m.EthereumEventVoteRecords)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 10:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field DelegateKeys", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.DelegateKeys = append(m.DelegateKeys, &MsgDelegateKeys{})
+ if err := m.DelegateKeys[len(m.DelegateKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 11:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20ToDenoms", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Erc20ToDenoms = append(m.Erc20ToDenoms, &ERC20ToDenom{})
+ if err := m.Erc20ToDenoms[len(m.Erc20ToDenoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 12:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field UnbatchedSendToEthereumTxs", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.UnbatchedSendToEthereumTxs = append(m.UnbatchedSendToEthereumTxs, &SendToEthereum{})
+ if err := m.UnbatchedSendToEthereumTxs[len(m.UnbatchedSendToEthereumTxs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenesis(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ERC20ToDenom) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ERC20ToDenom: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ERC20ToDenom: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Erc20 = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Denom = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenesis(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGenesis
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func skipGenesis(dAtA []byte) (n int, err error) {
+ l := len(dAtA)
+ iNdEx := 0
+ depth := 0
+ for iNdEx < l {
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ wireType := int(wire & 0x7)
+ switch wireType {
+ case 0:
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ iNdEx++
+ if dAtA[iNdEx-1] < 0x80 {
+ break
+ }
+ }
+ case 1:
+ iNdEx += 8
+ case 2:
+ var length int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowGenesis
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ length |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if length < 0 {
+ return 0, ErrInvalidLengthGenesis
+ }
+ iNdEx += length
+ case 3:
+ depth++
+ case 4:
+ if depth == 0 {
+ return 0, ErrUnexpectedEndOfGroupGenesis
+ }
+ depth--
+ case 5:
+ iNdEx += 4
+ default:
+ return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+ }
+ if iNdEx < 0 {
+ return 0, ErrInvalidLengthGenesis
+ }
+ if depth == 0 {
+ return iNdEx, nil
+ }
+ }
+ return 0, io.ErrUnexpectedEOF
+}
+
+var (
+ ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
+ ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
+ ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
+)
diff --git a/module/x/gravity/types/genesis_test.go b/module/x/gravity/types/genesis_test.go
new file mode 100644
index 0000000..f1eadcc
--- /dev/null
+++ b/module/x/gravity/types/genesis_test.go
@@ -0,0 +1,57 @@
+package types
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestGenesisStateValidate(t *testing.T) {
+ specs := map[string]struct {
+ src *GenesisState
+ expErr bool
+ }{
+ "default params": {src: DefaultGenesisState(), expErr: false},
+ "empty params": {src: &GenesisState{Params: &Params{}}, expErr: true},
+ "invalid params": {src: &GenesisState{
+ Params: &Params{
+ GravityId: "foo",
+ ContractSourceHash: "laksdjflasdkfja",
+ BridgeEthereumAddress: "invalid-eth-address",
+ BridgeChainId: 3279089,
+ },
+ }, expErr: true},
+ }
+ for msg, spec := range specs {
+ t.Run(msg, func(t *testing.T) {
+ err := spec.src.ValidateBasic()
+ if spec.expErr {
+ require.Error(t, err)
+ return
+ }
+ require.NoError(t, err)
+ })
+ }
+}
+
+func TestStringToByteArray(t *testing.T) {
+ specs := map[string]struct {
+ testString string
+ expErr bool
+ }{
+ "16 bytes": {"lakjsdflaksdjfds", false},
+ "32 bytes": {"lakjsdflaksdjfdslakjsdflaksdjfds", false},
+ "33 bytes": {"€€€€€€€€€€€", true},
+ }
+
+ for msg, spec := range specs {
+ t.Run(msg, func(t *testing.T) {
+ _, err := strToFixByteArray(spec.testString)
+ if spec.expErr {
+ require.Error(t, err)
+ return
+ }
+ require.NoError(t, err)
+ })
+ }
+}
diff --git a/module/x/gravity/types/gravity.pb.go b/module/x/gravity/types/gravity.pb.go
new file mode 100644
index 0000000..e0dbf60
--- /dev/null
+++ b/module/x/gravity/types/gravity.pb.go
@@ -0,0 +1,2809 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: gravity/v1/gravity.proto
+
+package types
+
+import (
+ fmt "fmt"
+ types "github.com/cosmos/cosmos-sdk/codec/types"
+ _ "github.com/cosmos/cosmos-sdk/types"
+ github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
+ _ "github.com/gogo/protobuf/gogoproto"
+ proto "github.com/gogo/protobuf/proto"
+ _ "github.com/regen-network/cosmos-proto"
+ github_com_tendermint_tendermint_libs_bytes "github.com/tendermint/tendermint/libs/bytes"
+ _ "google.golang.org/protobuf/types/known/timestamppb"
+ io "io"
+ math "math"
+ math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// EthereumEventVoteRecord is an event that is pending of confirmation by 2/3 of
+// the signer set. The event is then attested and executed in the state machine
+// once the required threshold is met.
+type EthereumEventVoteRecord struct {
+ Event *types.Any `protobuf:"bytes,1,opt,name=event,proto3" json:"event,omitempty"`
+ Votes []string `protobuf:"bytes,2,rep,name=votes,proto3" json:"votes,omitempty"`
+ Accepted bool `protobuf:"varint,3,opt,name=accepted,proto3" json:"accepted,omitempty"`
+}
+
+func (m *EthereumEventVoteRecord) Reset() { *m = EthereumEventVoteRecord{} }
+func (m *EthereumEventVoteRecord) String() string { return proto.CompactTextString(m) }
+func (*EthereumEventVoteRecord) ProtoMessage() {}
+func (*EthereumEventVoteRecord) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1715a041eadeb531, []int{0}
+}
+func (m *EthereumEventVoteRecord) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *EthereumEventVoteRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_EthereumEventVoteRecord.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *EthereumEventVoteRecord) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_EthereumEventVoteRecord.Merge(m, src)
+}
+func (m *EthereumEventVoteRecord) XXX_Size() int {
+ return m.Size()
+}
+func (m *EthereumEventVoteRecord) XXX_DiscardUnknown() {
+ xxx_messageInfo_EthereumEventVoteRecord.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_EthereumEventVoteRecord proto.InternalMessageInfo
+
+func (m *EthereumEventVoteRecord) GetEvent() *types.Any {
+ if m != nil {
+ return m.Event
+ }
+ return nil
+}
+
+func (m *EthereumEventVoteRecord) GetVotes() []string {
+ if m != nil {
+ return m.Votes
+ }
+ return nil
+}
+
+func (m *EthereumEventVoteRecord) GetAccepted() bool {
+ if m != nil {
+ return m.Accepted
+ }
+ return false
+}
+
+// LatestEthereumBlockHeight defines the latest observed ethereum block height
+// and the corresponding timestamp value in nanoseconds.
+type LatestEthereumBlockHeight struct {
+ EthereumHeight uint64 `protobuf:"varint,1,opt,name=ethereum_height,json=ethereumHeight,proto3" json:"ethereum_height,omitempty"`
+ CosmosHeight uint64 `protobuf:"varint,2,opt,name=cosmos_height,json=cosmosHeight,proto3" json:"cosmos_height,omitempty"`
+}
+
+func (m *LatestEthereumBlockHeight) Reset() { *m = LatestEthereumBlockHeight{} }
+func (m *LatestEthereumBlockHeight) String() string { return proto.CompactTextString(m) }
+func (*LatestEthereumBlockHeight) ProtoMessage() {}
+func (*LatestEthereumBlockHeight) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1715a041eadeb531, []int{1}
+}
+func (m *LatestEthereumBlockHeight) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *LatestEthereumBlockHeight) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_LatestEthereumBlockHeight.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *LatestEthereumBlockHeight) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LatestEthereumBlockHeight.Merge(m, src)
+}
+func (m *LatestEthereumBlockHeight) XXX_Size() int {
+ return m.Size()
+}
+func (m *LatestEthereumBlockHeight) XXX_DiscardUnknown() {
+ xxx_messageInfo_LatestEthereumBlockHeight.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LatestEthereumBlockHeight proto.InternalMessageInfo
+
+func (m *LatestEthereumBlockHeight) GetEthereumHeight() uint64 {
+ if m != nil {
+ return m.EthereumHeight
+ }
+ return 0
+}
+
+func (m *LatestEthereumBlockHeight) GetCosmosHeight() uint64 {
+ if m != nil {
+ return m.CosmosHeight
+ }
+ return 0
+}
+
+// EthereumSigner represents a cosmos validator with its corresponding bridge
+// operator ethereum address and its staking consensus power.
+type EthereumSigner struct {
+ Power uint64 `protobuf:"varint,1,opt,name=power,proto3" json:"power,omitempty"`
+ EthereumAddress string `protobuf:"bytes,2,opt,name=ethereum_address,json=ethereumAddress,proto3" json:"ethereum_address,omitempty"`
+}
+
+func (m *EthereumSigner) Reset() { *m = EthereumSigner{} }
+func (m *EthereumSigner) String() string { return proto.CompactTextString(m) }
+func (*EthereumSigner) ProtoMessage() {}
+func (*EthereumSigner) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1715a041eadeb531, []int{2}
+}
+func (m *EthereumSigner) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *EthereumSigner) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_EthereumSigner.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *EthereumSigner) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_EthereumSigner.Merge(m, src)
+}
+func (m *EthereumSigner) XXX_Size() int {
+ return m.Size()
+}
+func (m *EthereumSigner) XXX_DiscardUnknown() {
+ xxx_messageInfo_EthereumSigner.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_EthereumSigner proto.InternalMessageInfo
+
+func (m *EthereumSigner) GetPower() uint64 {
+ if m != nil {
+ return m.Power
+ }
+ return 0
+}
+
+func (m *EthereumSigner) GetEthereumAddress() string {
+ if m != nil {
+ return m.EthereumAddress
+ }
+ return ""
+}
+
+// SignerSetTx is the Ethereum Bridge multisig set that relays
+// transactions the two chains. The staking validators keep ethereum keys which
+// are used to check signatures on Ethereum in order to get significant gas
+// savings.
+type SignerSetTx struct {
+ Nonce uint64 `protobuf:"varint,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
+ Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
+ Signers EthereumSigners `protobuf:"bytes,3,rep,name=signers,proto3,castrepeated=EthereumSigners" json:"signers,omitempty"`
+}
+
+func (m *SignerSetTx) Reset() { *m = SignerSetTx{} }
+func (m *SignerSetTx) String() string { return proto.CompactTextString(m) }
+func (*SignerSetTx) ProtoMessage() {}
+func (*SignerSetTx) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1715a041eadeb531, []int{3}
+}
+func (m *SignerSetTx) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SignerSetTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SignerSetTx.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SignerSetTx) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SignerSetTx.Merge(m, src)
+}
+func (m *SignerSetTx) XXX_Size() int {
+ return m.Size()
+}
+func (m *SignerSetTx) XXX_DiscardUnknown() {
+ xxx_messageInfo_SignerSetTx.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignerSetTx proto.InternalMessageInfo
+
+func (m *SignerSetTx) GetNonce() uint64 {
+ if m != nil {
+ return m.Nonce
+ }
+ return 0
+}
+
+func (m *SignerSetTx) GetHeight() uint64 {
+ if m != nil {
+ return m.Height
+ }
+ return 0
+}
+
+func (m *SignerSetTx) GetSigners() EthereumSigners {
+ if m != nil {
+ return m.Signers
+ }
+ return nil
+}
+
+// BatchTx represents a batch of transactions going from Cosmos to Ethereum.
+// Batch txs are are identified by a unique hash and the token contract that is
+// shared by all the SendToEthereum
+type BatchTx struct {
+ BatchNonce uint64 `protobuf:"varint,1,opt,name=batch_nonce,json=batchNonce,proto3" json:"batch_nonce,omitempty"`
+ Timeout uint64 `protobuf:"varint,2,opt,name=timeout,proto3" json:"timeout,omitempty"`
+ Transactions []*SendToEthereum `protobuf:"bytes,3,rep,name=transactions,proto3" json:"transactions,omitempty"`
+ TokenContract string `protobuf:"bytes,4,opt,name=token_contract,json=tokenContract,proto3" json:"token_contract,omitempty"`
+ Height uint64 `protobuf:"varint,5,opt,name=height,proto3" json:"height,omitempty"`
+}
+
+func (m *BatchTx) Reset() { *m = BatchTx{} }
+func (m *BatchTx) String() string { return proto.CompactTextString(m) }
+func (*BatchTx) ProtoMessage() {}
+func (*BatchTx) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1715a041eadeb531, []int{4}
+}
+func (m *BatchTx) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTx.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTx) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTx.Merge(m, src)
+}
+func (m *BatchTx) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTx) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTx.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTx proto.InternalMessageInfo
+
+func (m *BatchTx) GetBatchNonce() uint64 {
+ if m != nil {
+ return m.BatchNonce
+ }
+ return 0
+}
+
+func (m *BatchTx) GetTimeout() uint64 {
+ if m != nil {
+ return m.Timeout
+ }
+ return 0
+}
+
+func (m *BatchTx) GetTransactions() []*SendToEthereum {
+ if m != nil {
+ return m.Transactions
+ }
+ return nil
+}
+
+func (m *BatchTx) GetTokenContract() string {
+ if m != nil {
+ return m.TokenContract
+ }
+ return ""
+}
+
+func (m *BatchTx) GetHeight() uint64 {
+ if m != nil {
+ return m.Height
+ }
+ return 0
+}
+
+// SendToEthereum represents an individual SendToEthereum from Cosmos to
+// Ethereum
+type SendToEthereum struct {
+ Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"`
+ EthereumRecipient string `protobuf:"bytes,3,opt,name=ethereum_recipient,json=ethereumRecipient,proto3" json:"ethereum_recipient,omitempty"`
+ Erc20Token ERC20Token `protobuf:"bytes,4,opt,name=erc20_token,json=erc20Token,proto3" json:"erc20_token"`
+ Erc20Fee ERC20Token `protobuf:"bytes,5,opt,name=erc20_fee,json=erc20Fee,proto3" json:"erc20_fee"`
+}
+
+func (m *SendToEthereum) Reset() { *m = SendToEthereum{} }
+func (m *SendToEthereum) String() string { return proto.CompactTextString(m) }
+func (*SendToEthereum) ProtoMessage() {}
+func (*SendToEthereum) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1715a041eadeb531, []int{5}
+}
+func (m *SendToEthereum) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SendToEthereum) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SendToEthereum.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SendToEthereum) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SendToEthereum.Merge(m, src)
+}
+func (m *SendToEthereum) XXX_Size() int {
+ return m.Size()
+}
+func (m *SendToEthereum) XXX_DiscardUnknown() {
+ xxx_messageInfo_SendToEthereum.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SendToEthereum proto.InternalMessageInfo
+
+func (m *SendToEthereum) GetId() uint64 {
+ if m != nil {
+ return m.Id
+ }
+ return 0
+}
+
+func (m *SendToEthereum) GetSender() string {
+ if m != nil {
+ return m.Sender
+ }
+ return ""
+}
+
+func (m *SendToEthereum) GetEthereumRecipient() string {
+ if m != nil {
+ return m.EthereumRecipient
+ }
+ return ""
+}
+
+func (m *SendToEthereum) GetErc20Token() ERC20Token {
+ if m != nil {
+ return m.Erc20Token
+ }
+ return ERC20Token{}
+}
+
+func (m *SendToEthereum) GetErc20Fee() ERC20Token {
+ if m != nil {
+ return m.Erc20Fee
+ }
+ return ERC20Token{}
+}
+
+// ContractCallTx represents an individual arbitrary logic call transaction
+// from Cosmos to Ethereum.
+type ContractCallTx struct {
+ InvalidationNonce uint64 `protobuf:"varint,1,opt,name=invalidation_nonce,json=invalidationNonce,proto3" json:"invalidation_nonce,omitempty"`
+ InvalidationScope github_com_tendermint_tendermint_libs_bytes.HexBytes `protobuf:"bytes,2,opt,name=invalidation_scope,json=invalidationScope,proto3,casttype=github.com/tendermint/tendermint/libs/bytes.HexBytes" json:"invalidation_scope,omitempty"`
+ Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
+ Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3" json:"payload,omitempty"`
+ Timeout uint64 `protobuf:"varint,5,opt,name=timeout,proto3" json:"timeout,omitempty"`
+ Tokens []ERC20Token `protobuf:"bytes,6,rep,name=tokens,proto3" json:"tokens"`
+ Fees []ERC20Token `protobuf:"bytes,7,rep,name=fees,proto3" json:"fees"`
+ Height uint64 `protobuf:"varint,8,opt,name=height,proto3" json:"height,omitempty"`
+}
+
+func (m *ContractCallTx) Reset() { *m = ContractCallTx{} }
+func (m *ContractCallTx) String() string { return proto.CompactTextString(m) }
+func (*ContractCallTx) ProtoMessage() {}
+func (*ContractCallTx) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1715a041eadeb531, []int{6}
+}
+func (m *ContractCallTx) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ContractCallTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ContractCallTx.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ContractCallTx) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ContractCallTx.Merge(m, src)
+}
+func (m *ContractCallTx) XXX_Size() int {
+ return m.Size()
+}
+func (m *ContractCallTx) XXX_DiscardUnknown() {
+ xxx_messageInfo_ContractCallTx.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ContractCallTx proto.InternalMessageInfo
+
+func (m *ContractCallTx) GetInvalidationNonce() uint64 {
+ if m != nil {
+ return m.InvalidationNonce
+ }
+ return 0
+}
+
+func (m *ContractCallTx) GetInvalidationScope() github_com_tendermint_tendermint_libs_bytes.HexBytes {
+ if m != nil {
+ return m.InvalidationScope
+ }
+ return nil
+}
+
+func (m *ContractCallTx) GetAddress() string {
+ if m != nil {
+ return m.Address
+ }
+ return ""
+}
+
+func (m *ContractCallTx) GetPayload() []byte {
+ if m != nil {
+ return m.Payload
+ }
+ return nil
+}
+
+func (m *ContractCallTx) GetTimeout() uint64 {
+ if m != nil {
+ return m.Timeout
+ }
+ return 0
+}
+
+func (m *ContractCallTx) GetTokens() []ERC20Token {
+ if m != nil {
+ return m.Tokens
+ }
+ return nil
+}
+
+func (m *ContractCallTx) GetFees() []ERC20Token {
+ if m != nil {
+ return m.Fees
+ }
+ return nil
+}
+
+func (m *ContractCallTx) GetHeight() uint64 {
+ if m != nil {
+ return m.Height
+ }
+ return 0
+}
+
+type ERC20Token struct {
+ Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"`
+ Amount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount"`
+}
+
+func (m *ERC20Token) Reset() { *m = ERC20Token{} }
+func (m *ERC20Token) String() string { return proto.CompactTextString(m) }
+func (*ERC20Token) ProtoMessage() {}
+func (*ERC20Token) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1715a041eadeb531, []int{7}
+}
+func (m *ERC20Token) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ERC20Token) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ERC20Token.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ERC20Token) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ERC20Token.Merge(m, src)
+}
+func (m *ERC20Token) XXX_Size() int {
+ return m.Size()
+}
+func (m *ERC20Token) XXX_DiscardUnknown() {
+ xxx_messageInfo_ERC20Token.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ERC20Token proto.InternalMessageInfo
+
+func (m *ERC20Token) GetContract() string {
+ if m != nil {
+ return m.Contract
+ }
+ return ""
+}
+
+type IDSet struct {
+ Ids []uint64 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids,omitempty"`
+}
+
+func (m *IDSet) Reset() { *m = IDSet{} }
+func (m *IDSet) String() string { return proto.CompactTextString(m) }
+func (*IDSet) ProtoMessage() {}
+func (*IDSet) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1715a041eadeb531, []int{8}
+}
+func (m *IDSet) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *IDSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_IDSet.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *IDSet) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_IDSet.Merge(m, src)
+}
+func (m *IDSet) XXX_Size() int {
+ return m.Size()
+}
+func (m *IDSet) XXX_DiscardUnknown() {
+ xxx_messageInfo_IDSet.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IDSet proto.InternalMessageInfo
+
+func (m *IDSet) GetIds() []uint64 {
+ if m != nil {
+ return m.Ids
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*EthereumEventVoteRecord)(nil), "gravity.v1.EthereumEventVoteRecord")
+ proto.RegisterType((*LatestEthereumBlockHeight)(nil), "gravity.v1.LatestEthereumBlockHeight")
+ proto.RegisterType((*EthereumSigner)(nil), "gravity.v1.EthereumSigner")
+ proto.RegisterType((*SignerSetTx)(nil), "gravity.v1.SignerSetTx")
+ proto.RegisterType((*BatchTx)(nil), "gravity.v1.BatchTx")
+ proto.RegisterType((*SendToEthereum)(nil), "gravity.v1.SendToEthereum")
+ proto.RegisterType((*ContractCallTx)(nil), "gravity.v1.ContractCallTx")
+ proto.RegisterType((*ERC20Token)(nil), "gravity.v1.ERC20Token")
+ proto.RegisterType((*IDSet)(nil), "gravity.v1.IDSet")
+}
+
+func init() { proto.RegisterFile("gravity/v1/gravity.proto", fileDescriptor_1715a041eadeb531) }
+
+var fileDescriptor_1715a041eadeb531 = []byte{
+ // 850 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4f, 0x6f, 0xe3, 0xc4,
+ 0x1b, 0xae, 0xf3, 0xaf, 0xed, 0xa4, 0xcd, 0x6e, 0xe7, 0x57, 0xed, 0xcf, 0xed, 0x21, 0x89, 0x82,
+ 0x80, 0x70, 0xa8, 0xdd, 0x86, 0x3d, 0x2c, 0x87, 0x45, 0x5a, 0x97, 0x5d, 0x6d, 0x25, 0x84, 0x84,
+ 0x13, 0x71, 0xe0, 0x12, 0x8d, 0xed, 0xb7, 0xce, 0xd0, 0xc4, 0x63, 0x79, 0x26, 0x21, 0xf9, 0x02,
+ 0x1c, 0x38, 0xf1, 0x39, 0x38, 0xf3, 0x0d, 0xb8, 0xac, 0x38, 0xed, 0x11, 0x71, 0x28, 0xd0, 0x7e,
+ 0x07, 0x0e, 0x9c, 0xd0, 0xfc, 0xcb, 0xda, 0x2b, 0x04, 0x9c, 0x3a, 0xcf, 0xf3, 0xbe, 0xef, 0x33,
+ 0x8f, 0x1f, 0xbf, 0x75, 0x90, 0x9b, 0x16, 0x64, 0x45, 0xc5, 0xc6, 0x5f, 0x5d, 0xf8, 0xe6, 0xe8,
+ 0xe5, 0x05, 0x13, 0x0c, 0x23, 0x0b, 0x57, 0x17, 0xa7, 0x27, 0x31, 0xe3, 0x0b, 0xc6, 0xa7, 0xaa,
+ 0xe2, 0x6b, 0xa0, 0xdb, 0x4e, 0x7b, 0x29, 0x63, 0xe9, 0x1c, 0x7c, 0x85, 0xa2, 0xe5, 0xb5, 0x2f,
+ 0xe8, 0x02, 0xb8, 0x20, 0x8b, 0xdc, 0x34, 0x1c, 0xa7, 0x2c, 0x65, 0x7a, 0x50, 0x9e, 0x0c, 0xdb,
+ 0xd5, 0x22, 0x7e, 0x44, 0x38, 0xf8, 0xab, 0x8b, 0x08, 0x04, 0xb9, 0xf0, 0x63, 0x46, 0x33, 0x53,
+ 0x3f, 0x79, 0x5b, 0x96, 0x64, 0xc6, 0xd8, 0xe0, 0x5b, 0x07, 0xfd, 0xff, 0xb9, 0x98, 0x41, 0x01,
+ 0xcb, 0xc5, 0xf3, 0x15, 0x64, 0xe2, 0x0b, 0x26, 0x20, 0x84, 0x98, 0x15, 0x09, 0x7e, 0x8a, 0x9a,
+ 0x20, 0x29, 0xd7, 0xe9, 0x3b, 0xc3, 0xf6, 0xe8, 0xd8, 0xd3, 0x32, 0x9e, 0x95, 0xf1, 0x9e, 0x65,
+ 0x9b, 0xe0, 0xe8, 0xa7, 0x1f, 0xce, 0x0e, 0x2b, 0x0a, 0xa1, 0x9e, 0xc2, 0xc7, 0xa8, 0xb9, 0x62,
+ 0x02, 0xb8, 0x5b, 0xeb, 0xd7, 0x87, 0xfb, 0xa1, 0x06, 0xf8, 0x14, 0xed, 0x91, 0x38, 0x86, 0x5c,
+ 0x40, 0xe2, 0xd6, 0xfb, 0xce, 0x70, 0x2f, 0xdc, 0xe2, 0x01, 0x45, 0x27, 0x9f, 0x12, 0x01, 0x5c,
+ 0x58, 0xbd, 0x60, 0xce, 0xe2, 0x9b, 0x97, 0x40, 0xd3, 0x99, 0xc0, 0xef, 0xa3, 0x07, 0x60, 0xe8,
+ 0xe9, 0x4c, 0x51, 0xca, 0x57, 0x23, 0xec, 0x58, 0xda, 0x34, 0xbe, 0x83, 0x0e, 0x4d, 0xc2, 0xa6,
+ 0xad, 0xa6, 0xda, 0x0e, 0x34, 0xa9, 0x9b, 0x06, 0x9f, 0xa3, 0x8e, 0xbd, 0x64, 0x4c, 0xd3, 0x0c,
+ 0x0a, 0x69, 0x37, 0x67, 0x5f, 0x43, 0x61, 0x54, 0x35, 0xc0, 0x1f, 0xa0, 0x87, 0xdb, 0x5b, 0x49,
+ 0x92, 0x14, 0xc0, 0xb9, 0xd2, 0xdb, 0x0f, 0xb7, 0x6e, 0x9e, 0x69, 0x7a, 0xf0, 0x8d, 0x83, 0xda,
+ 0x5a, 0x6b, 0x0c, 0x62, 0xb2, 0x96, 0x82, 0x19, 0xcb, 0x62, 0xb0, 0x82, 0x0a, 0xe0, 0x47, 0xa8,
+ 0x55, 0xb1, 0x65, 0x10, 0xbe, 0x42, 0xbb, 0x5c, 0x0d, 0x73, 0xb7, 0xde, 0xaf, 0x0f, 0xdb, 0xa3,
+ 0x53, 0xef, 0xcd, 0xce, 0x78, 0x55, 0xaf, 0xc1, 0xff, 0xbe, 0xff, 0xb5, 0xf7, 0xa0, 0xca, 0xf1,
+ 0xd0, 0xce, 0x0f, 0x7e, 0x74, 0xd0, 0x6e, 0x40, 0x44, 0x3c, 0x9b, 0xac, 0x71, 0x0f, 0xb5, 0x23,
+ 0x79, 0x9c, 0x96, 0xad, 0x20, 0x45, 0x7d, 0xa6, 0xfc, 0xb8, 0x68, 0x57, 0x2e, 0x19, 0x5b, 0x5a,
+ 0x43, 0x16, 0xe2, 0x8f, 0xd1, 0x81, 0x28, 0x48, 0xc6, 0x49, 0x2c, 0x28, 0xcb, 0xfe, 0xd6, 0xd6,
+ 0x18, 0xb2, 0x64, 0xc2, 0xac, 0x91, 0xb0, 0xd2, 0x8f, 0xdf, 0x45, 0x1d, 0xc1, 0x6e, 0x20, 0x9b,
+ 0xc6, 0x2c, 0x13, 0x05, 0x89, 0x85, 0xdb, 0x50, 0xc1, 0x1d, 0x2a, 0xf6, 0xd2, 0x90, 0xa5, 0x40,
+ 0x9a, 0xe5, 0x40, 0x06, 0xbf, 0x3b, 0xa8, 0x53, 0xd5, 0xc7, 0x1d, 0x54, 0xa3, 0x89, 0x79, 0x86,
+ 0x1a, 0x4d, 0xe4, 0x28, 0x87, 0x2c, 0x81, 0xc2, 0xbc, 0x12, 0x83, 0xf0, 0x19, 0xc2, 0xdb, 0x97,
+ 0x56, 0x40, 0x4c, 0x73, 0x2a, 0xb7, 0xb8, 0xae, 0x7a, 0x8e, 0x6c, 0x25, 0xb4, 0x05, 0xfc, 0x14,
+ 0xb5, 0xa1, 0x88, 0x47, 0xe7, 0x53, 0x65, 0x4c, 0xb9, 0x6c, 0x8f, 0x1e, 0x55, 0xe2, 0x0f, 0x2f,
+ 0x47, 0xe7, 0x13, 0x59, 0x0d, 0x1a, 0xaf, 0x6e, 0x7b, 0x3b, 0x21, 0x52, 0x03, 0x8a, 0xc1, 0x1f,
+ 0xa1, 0x7d, 0x3d, 0x7e, 0x0d, 0xa0, 0x9e, 0xe1, 0xdf, 0x86, 0xf7, 0x54, 0xfb, 0x0b, 0x80, 0xc1,
+ 0x1f, 0x35, 0xd4, 0xb1, 0x41, 0x5c, 0x92, 0xf9, 0x7c, 0xb2, 0x96, 0xde, 0x69, 0xb6, 0x22, 0x73,
+ 0x9a, 0x10, 0x19, 0x63, 0xe5, 0xbd, 0x1d, 0x95, 0x2b, 0xfa, 0xf5, 0xa5, 0x6f, 0xb5, 0xf3, 0x98,
+ 0xe5, 0xa0, 0xe2, 0x38, 0x08, 0x9e, 0xfc, 0x79, 0xdb, 0x7b, 0x9c, 0x52, 0x31, 0x5b, 0x46, 0x5e,
+ 0xcc, 0x16, 0xbe, 0x50, 0xe9, 0x2c, 0x68, 0x26, 0xca, 0xc7, 0x39, 0x8d, 0xb8, 0x1f, 0x6d, 0x04,
+ 0x70, 0xef, 0x25, 0xac, 0x03, 0x79, 0xa8, 0x5e, 0x34, 0x96, 0x92, 0x72, 0x4f, 0xec, 0xfe, 0xeb,
+ 0x20, 0x2d, 0x94, 0x95, 0x9c, 0x6c, 0xe6, 0x8c, 0x24, 0x2a, 0xba, 0x83, 0xd0, 0xc2, 0xf2, 0x6e,
+ 0x35, 0xab, 0xbb, 0xf5, 0x18, 0xb5, 0x54, 0xd8, 0xdc, 0x6d, 0xa9, 0xad, 0xfa, 0xe7, 0xc0, 0x4c,
+ 0x2f, 0x3e, 0x47, 0x8d, 0x6b, 0x00, 0xee, 0xee, 0xfe, 0x87, 0x19, 0xd5, 0x59, 0x5a, 0xae, 0xbd,
+ 0xca, 0x72, 0xe5, 0x08, 0xbd, 0x99, 0x90, 0xdf, 0xa4, 0xed, 0x8e, 0x3a, 0xea, 0xe1, 0xb6, 0x18,
+ 0xbf, 0x40, 0x2d, 0xb2, 0x60, 0xcb, 0x4c, 0xff, 0x7b, 0xec, 0x07, 0x9e, 0x54, 0xff, 0xe5, 0xb6,
+ 0xf7, 0x5e, 0x29, 0x58, 0xf3, 0xf9, 0xd5, 0x7f, 0xce, 0x78, 0x72, 0xe3, 0x8b, 0x4d, 0x0e, 0xdc,
+ 0xbb, 0xca, 0x44, 0x68, 0xa6, 0x07, 0x27, 0xa8, 0x79, 0xf5, 0xc9, 0x18, 0x04, 0x7e, 0x88, 0xea,
+ 0x34, 0xe1, 0xae, 0xd3, 0xaf, 0x0f, 0x1b, 0xa1, 0x3c, 0x06, 0xe1, 0xab, 0xbb, 0xae, 0xf3, 0xfa,
+ 0xae, 0xeb, 0xfc, 0x76, 0xd7, 0x75, 0xbe, 0xbb, 0xef, 0xee, 0xbc, 0xbe, 0xef, 0xee, 0xfc, 0x7c,
+ 0xdf, 0xdd, 0xf9, 0xf2, 0x49, 0xe9, 0x92, 0x1c, 0xd2, 0x74, 0xf3, 0xd5, 0xca, 0xfe, 0xb0, 0x9c,
+ 0x45, 0x05, 0x4d, 0x52, 0xf0, 0x17, 0x2c, 0x59, 0xce, 0xc1, 0x5f, 0x5b, 0x5e, 0x5f, 0x1d, 0xb5,
+ 0xd4, 0x47, 0xfa, 0xc3, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x32, 0xe5, 0xf6, 0xc4, 0x93, 0x06,
+ 0x00, 0x00,
+}
+
+func (m *EthereumEventVoteRecord) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *EthereumEventVoteRecord) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *EthereumEventVoteRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Accepted {
+ i--
+ if m.Accepted {
+ dAtA[i] = 1
+ } else {
+ dAtA[i] = 0
+ }
+ i--
+ dAtA[i] = 0x18
+ }
+ if len(m.Votes) > 0 {
+ for iNdEx := len(m.Votes) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.Votes[iNdEx])
+ copy(dAtA[i:], m.Votes[iNdEx])
+ i = encodeVarintGravity(dAtA, i, uint64(len(m.Votes[iNdEx])))
+ i--
+ dAtA[i] = 0x12
+ }
+ }
+ if m.Event != nil {
+ {
+ size, err := m.Event.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGravity(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *LatestEthereumBlockHeight) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *LatestEthereumBlockHeight) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *LatestEthereumBlockHeight) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.CosmosHeight != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.CosmosHeight))
+ i--
+ dAtA[i] = 0x10
+ }
+ if m.EthereumHeight != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.EthereumHeight))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *EthereumSigner) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *EthereumSigner) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *EthereumSigner) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.EthereumAddress) > 0 {
+ i -= len(m.EthereumAddress)
+ copy(dAtA[i:], m.EthereumAddress)
+ i = encodeVarintGravity(dAtA, i, uint64(len(m.EthereumAddress)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.Power != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.Power))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *SignerSetTx) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SignerSetTx) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SignerSetTx) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signers) > 0 {
+ for iNdEx := len(m.Signers) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Signers[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGravity(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
+ }
+ }
+ if m.Height != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.Height))
+ i--
+ dAtA[i] = 0x10
+ }
+ if m.Nonce != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.Nonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTx) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTx) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTx) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Height != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.Height))
+ i--
+ dAtA[i] = 0x28
+ }
+ if len(m.TokenContract) > 0 {
+ i -= len(m.TokenContract)
+ copy(dAtA[i:], m.TokenContract)
+ i = encodeVarintGravity(dAtA, i, uint64(len(m.TokenContract)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.Transactions) > 0 {
+ for iNdEx := len(m.Transactions) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Transactions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGravity(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
+ }
+ }
+ if m.Timeout != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.Timeout))
+ i--
+ dAtA[i] = 0x10
+ }
+ if m.BatchNonce != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.BatchNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *SendToEthereum) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SendToEthereum) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SendToEthereum) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ {
+ size, err := m.Erc20Fee.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGravity(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x2a
+ {
+ size, err := m.Erc20Token.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGravity(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x22
+ if len(m.EthereumRecipient) > 0 {
+ i -= len(m.EthereumRecipient)
+ copy(dAtA[i:], m.EthereumRecipient)
+ i = encodeVarintGravity(dAtA, i, uint64(len(m.EthereumRecipient)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if len(m.Sender) > 0 {
+ i -= len(m.Sender)
+ copy(dAtA[i:], m.Sender)
+ i = encodeVarintGravity(dAtA, i, uint64(len(m.Sender)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.Id != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.Id))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ContractCallTx) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ContractCallTx) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ContractCallTx) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Height != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.Height))
+ i--
+ dAtA[i] = 0x40
+ }
+ if len(m.Fees) > 0 {
+ for iNdEx := len(m.Fees) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Fees[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGravity(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x3a
+ }
+ }
+ if len(m.Tokens) > 0 {
+ for iNdEx := len(m.Tokens) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Tokens[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGravity(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x32
+ }
+ }
+ if m.Timeout != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.Timeout))
+ i--
+ dAtA[i] = 0x28
+ }
+ if len(m.Payload) > 0 {
+ i -= len(m.Payload)
+ copy(dAtA[i:], m.Payload)
+ i = encodeVarintGravity(dAtA, i, uint64(len(m.Payload)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.Address) > 0 {
+ i -= len(m.Address)
+ copy(dAtA[i:], m.Address)
+ i = encodeVarintGravity(dAtA, i, uint64(len(m.Address)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if len(m.InvalidationScope) > 0 {
+ i -= len(m.InvalidationScope)
+ copy(dAtA[i:], m.InvalidationScope)
+ i = encodeVarintGravity(dAtA, i, uint64(len(m.InvalidationScope)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.InvalidationNonce != 0 {
+ i = encodeVarintGravity(dAtA, i, uint64(m.InvalidationNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ERC20Token) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ERC20Token) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ERC20Token) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ {
+ size := m.Amount.Size()
+ i -= size
+ if _, err := m.Amount.MarshalTo(dAtA[i:]); err != nil {
+ return 0, err
+ }
+ i = encodeVarintGravity(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ if len(m.Contract) > 0 {
+ i -= len(m.Contract)
+ copy(dAtA[i:], m.Contract)
+ i = encodeVarintGravity(dAtA, i, uint64(len(m.Contract)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *IDSet) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *IDSet) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *IDSet) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Ids) > 0 {
+ dAtA5 := make([]byte, len(m.Ids)*10)
+ var j4 int
+ for _, num := range m.Ids {
+ for num >= 1<<7 {
+ dAtA5[j4] = uint8(uint64(num)&0x7f | 0x80)
+ num >>= 7
+ j4++
+ }
+ dAtA5[j4] = uint8(num)
+ j4++
+ }
+ i -= j4
+ copy(dAtA[i:], dAtA5[:j4])
+ i = encodeVarintGravity(dAtA, i, uint64(j4))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func encodeVarintGravity(dAtA []byte, offset int, v uint64) int {
+ offset -= sovGravity(v)
+ base := offset
+ for v >= 1<<7 {
+ dAtA[offset] = uint8(v&0x7f | 0x80)
+ v >>= 7
+ offset++
+ }
+ dAtA[offset] = uint8(v)
+ return base
+}
+func (m *EthereumEventVoteRecord) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Event != nil {
+ l = m.Event.Size()
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ if len(m.Votes) > 0 {
+ for _, s := range m.Votes {
+ l = len(s)
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ }
+ if m.Accepted {
+ n += 2
+ }
+ return n
+}
+
+func (m *LatestEthereumBlockHeight) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.EthereumHeight != 0 {
+ n += 1 + sovGravity(uint64(m.EthereumHeight))
+ }
+ if m.CosmosHeight != 0 {
+ n += 1 + sovGravity(uint64(m.CosmosHeight))
+ }
+ return n
+}
+
+func (m *EthereumSigner) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Power != 0 {
+ n += 1 + sovGravity(uint64(m.Power))
+ }
+ l = len(m.EthereumAddress)
+ if l > 0 {
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ return n
+}
+
+func (m *SignerSetTx) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Nonce != 0 {
+ n += 1 + sovGravity(uint64(m.Nonce))
+ }
+ if m.Height != 0 {
+ n += 1 + sovGravity(uint64(m.Height))
+ }
+ if len(m.Signers) > 0 {
+ for _, e := range m.Signers {
+ l = e.Size()
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *BatchTx) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.BatchNonce != 0 {
+ n += 1 + sovGravity(uint64(m.BatchNonce))
+ }
+ if m.Timeout != 0 {
+ n += 1 + sovGravity(uint64(m.Timeout))
+ }
+ if len(m.Transactions) > 0 {
+ for _, e := range m.Transactions {
+ l = e.Size()
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ }
+ l = len(m.TokenContract)
+ if l > 0 {
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ if m.Height != 0 {
+ n += 1 + sovGravity(uint64(m.Height))
+ }
+ return n
+}
+
+func (m *SendToEthereum) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Id != 0 {
+ n += 1 + sovGravity(uint64(m.Id))
+ }
+ l = len(m.Sender)
+ if l > 0 {
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ l = len(m.EthereumRecipient)
+ if l > 0 {
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ l = m.Erc20Token.Size()
+ n += 1 + l + sovGravity(uint64(l))
+ l = m.Erc20Fee.Size()
+ n += 1 + l + sovGravity(uint64(l))
+ return n
+}
+
+func (m *ContractCallTx) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.InvalidationNonce != 0 {
+ n += 1 + sovGravity(uint64(m.InvalidationNonce))
+ }
+ l = len(m.InvalidationScope)
+ if l > 0 {
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ l = len(m.Address)
+ if l > 0 {
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ l = len(m.Payload)
+ if l > 0 {
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ if m.Timeout != 0 {
+ n += 1 + sovGravity(uint64(m.Timeout))
+ }
+ if len(m.Tokens) > 0 {
+ for _, e := range m.Tokens {
+ l = e.Size()
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ }
+ if len(m.Fees) > 0 {
+ for _, e := range m.Fees {
+ l = e.Size()
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ }
+ if m.Height != 0 {
+ n += 1 + sovGravity(uint64(m.Height))
+ }
+ return n
+}
+
+func (m *ERC20Token) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Contract)
+ if l > 0 {
+ n += 1 + l + sovGravity(uint64(l))
+ }
+ l = m.Amount.Size()
+ n += 1 + l + sovGravity(uint64(l))
+ return n
+}
+
+func (m *IDSet) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Ids) > 0 {
+ l = 0
+ for _, e := range m.Ids {
+ l += sovGravity(uint64(e))
+ }
+ n += 1 + sovGravity(uint64(l)) + l
+ }
+ return n
+}
+
+func sovGravity(x uint64) (n int) {
+ return (math_bits.Len64(x|1) + 6) / 7
+}
+func sozGravity(x uint64) (n int) {
+ return sovGravity(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *EthereumEventVoteRecord) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: EthereumEventVoteRecord: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: EthereumEventVoteRecord: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Event == nil {
+ m.Event = &types.Any{}
+ }
+ if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Votes", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Votes = append(m.Votes, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
+ case 3:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Accepted", wireType)
+ }
+ var v int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ m.Accepted = bool(v != 0)
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGravity(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *LatestEthereumBlockHeight) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: LatestEthereumBlockHeight: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: LatestEthereumBlockHeight: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumHeight", wireType)
+ }
+ m.EthereumHeight = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EthereumHeight |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CosmosHeight", wireType)
+ }
+ m.CosmosHeight = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.CosmosHeight |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGravity(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *EthereumSigner) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: EthereumSigner: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: EthereumSigner: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType)
+ }
+ m.Power = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Power |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGravity(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SignerSetTx) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SignerSetTx: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SignerSetTx: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Nonce", wireType)
+ }
+ m.Nonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Nonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+ }
+ m.Height = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Height |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signers", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signers = append(m.Signers, &EthereumSigner{})
+ if err := m.Signers[len(m.Signers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGravity(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTx) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTx: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTx: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BatchNonce", wireType)
+ }
+ m.BatchNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.BatchNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Timeout", wireType)
+ }
+ m.Timeout = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Timeout |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Transactions", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Transactions = append(m.Transactions, &SendToEthereum{})
+ if err := m.Transactions[len(m.Transactions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field TokenContract", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.TokenContract = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 5:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+ }
+ m.Height = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Height |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGravity(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SendToEthereum) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SendToEthereum: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SendToEthereum: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType)
+ }
+ m.Id = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Id |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Sender = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumRecipient", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumRecipient = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20Token", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Erc20Token.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 5:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20Fee", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Erc20Fee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGravity(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ContractCallTx) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ContractCallTx: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ContractCallTx: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationNonce", wireType)
+ }
+ m.InvalidationNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.InvalidationNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationScope", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.InvalidationScope = append(m.InvalidationScope[:0], dAtA[iNdEx:postIndex]...)
+ if m.InvalidationScope == nil {
+ m.InvalidationScope = []byte{}
+ }
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Address = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...)
+ if m.Payload == nil {
+ m.Payload = []byte{}
+ }
+ iNdEx = postIndex
+ case 5:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Timeout", wireType)
+ }
+ m.Timeout = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Timeout |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 6:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Tokens", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Tokens = append(m.Tokens, ERC20Token{})
+ if err := m.Tokens[len(m.Tokens)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 7:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Fees", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Fees = append(m.Fees, ERC20Token{})
+ if err := m.Fees[len(m.Fees)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 8:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+ }
+ m.Height = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Height |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGravity(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ERC20Token) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ERC20Token: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ERC20Token: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Contract = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGravity(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *IDSet) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: IDSet: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: IDSet: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType == 0 {
+ var v uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ m.Ids = append(m.Ids, v)
+ } else if wireType == 2 {
+ var packedLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ packedLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if packedLen < 0 {
+ return ErrInvalidLengthGravity
+ }
+ postIndex := iNdEx + packedLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ var elementCount int
+ var count int
+ for _, integer := range dAtA[iNdEx:postIndex] {
+ if integer < 128 {
+ count++
+ }
+ }
+ elementCount = count
+ if elementCount != 0 && len(m.Ids) == 0 {
+ m.Ids = make([]uint64, 0, elementCount)
+ }
+ for iNdEx < postIndex {
+ var v uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ m.Ids = append(m.Ids, v)
+ }
+ } else {
+ return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType)
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGravity(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthGravity
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func skipGravity(dAtA []byte) (n int, err error) {
+ l := len(dAtA)
+ iNdEx := 0
+ depth := 0
+ for iNdEx < l {
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ wireType := int(wire & 0x7)
+ switch wireType {
+ case 0:
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ iNdEx++
+ if dAtA[iNdEx-1] < 0x80 {
+ break
+ }
+ }
+ case 1:
+ iNdEx += 8
+ case 2:
+ var length int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowGravity
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ length |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if length < 0 {
+ return 0, ErrInvalidLengthGravity
+ }
+ iNdEx += length
+ case 3:
+ depth++
+ case 4:
+ if depth == 0 {
+ return 0, ErrUnexpectedEndOfGroupGravity
+ }
+ depth--
+ case 5:
+ iNdEx += 4
+ default:
+ return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+ }
+ if iNdEx < 0 {
+ return 0, ErrInvalidLengthGravity
+ }
+ if depth == 0 {
+ return iNdEx, nil
+ }
+ }
+ return 0, io.ErrUnexpectedEOF
+}
+
+var (
+ ErrInvalidLengthGravity = fmt.Errorf("proto: negative length found during unmarshaling")
+ ErrIntOverflowGravity = fmt.Errorf("proto: integer overflow")
+ ErrUnexpectedEndOfGroupGravity = fmt.Errorf("proto: unexpected end of group")
+)
diff --git a/module/x/gravity/types/hooks.go b/module/x/gravity/types/hooks.go
new file mode 100644
index 0000000..79b53f7
--- /dev/null
+++ b/module/x/gravity/types/hooks.go
@@ -0,0 +1,47 @@
+package types
+
+import sdk "github.com/cosmos/cosmos-sdk/types"
+
+type GravityHooks interface {
+ AfterContractCallExecutedEvent(ctx sdk.Context, event ContractCallExecutedEvent)
+ AfterERC20DeployedEvent(ctx sdk.Context, event ERC20DeployedEvent)
+ AfterSignerSetExecutedEvent(ctx sdk.Context, event SignerSetTxExecutedEvent)
+ AfterBatchExecutedEvent(ctx sdk.Context, event BatchExecutedEvent)
+ AfterSendToCosmosEvent(ctx sdk.Context, event SendToCosmosEvent)
+}
+
+type MultiGravityHooks []GravityHooks
+
+func NewMultiGravityHooks(hooks ...GravityHooks) MultiGravityHooks {
+ return hooks
+}
+
+func (mghs MultiGravityHooks) AfterContractCallExecutedEvent(ctx sdk.Context, event ContractCallExecutedEvent) {
+ for i := range mghs {
+ mghs[i].AfterContractCallExecutedEvent(ctx, event)
+ }
+}
+
+func (mghs MultiGravityHooks) AfterERC20DeployedEvent(ctx sdk.Context, event ERC20DeployedEvent) {
+ for i := range mghs {
+ mghs[i].AfterERC20DeployedEvent(ctx, event)
+ }
+}
+
+func (mghs MultiGravityHooks) AfterSignerSetExecutedEvent(ctx sdk.Context, event SignerSetTxExecutedEvent) {
+ for i := range mghs {
+ mghs[i].AfterSignerSetExecutedEvent(ctx, event)
+ }
+}
+
+func (mghs MultiGravityHooks) AfterBatchExecutedEvent(ctx sdk.Context, event BatchExecutedEvent) {
+ for i := range mghs {
+ mghs[i].AfterBatchExecutedEvent(ctx, event)
+ }
+}
+
+func (mghs MultiGravityHooks) AfterSendToCosmosEvent(ctx sdk.Context, event SendToCosmosEvent) {
+ for i := range mghs {
+ mghs[i].AfterSendToCosmosEvent(ctx, event)
+ }
+}
diff --git a/module/x/gravity/types/interfaces.go b/module/x/gravity/types/interfaces.go
new file mode 100644
index 0000000..803cc0c
--- /dev/null
+++ b/module/x/gravity/types/interfaces.go
@@ -0,0 +1,40 @@
+package types
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/gogo/protobuf/proto"
+ tmbytes "github.com/tendermint/tendermint/libs/bytes"
+)
+
+// EthereumTxConfirmation represents one validtors signature for a given
+// outgoing ethereum transaction
+type EthereumTxConfirmation interface {
+ proto.Message
+
+ GetSigner() common.Address
+ GetSignature() []byte
+ GetStoreIndex() []byte
+ Validate() error
+}
+
+// EthereumEvent represents a event from the gravity contract
+// on the counterparty ethereum chain
+type EthereumEvent interface {
+ proto.Message
+
+ GetEventNonce() uint64
+ GetEthereumHeight() uint64
+ Hash() tmbytes.HexBytes
+ Validate() error
+}
+
+type OutgoingTx interface {
+ // NOTE: currently the function signatures here don't match, figure out how to do this proprly
+ // maybe add an interface arg here and typecheck in each implementation?
+
+ // The only one that will be problematic is BatchTx which needs to pull all the constituent
+ // transactions before calculating the checkpoint
+ GetCheckpoint([]byte) []byte
+ GetStoreIndex() []byte
+ GetCosmosHeight() uint64
+}
diff --git a/module/x/gravity/types/key.go b/module/x/gravity/types/key.go
new file mode 100644
index 0000000..6450094
--- /dev/null
+++ b/module/x/gravity/types/key.go
@@ -0,0 +1,158 @@
+package types
+
+import (
+ "bytes"
+
+ "github.com/ethereum/go-ethereum/common"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+)
+
+const (
+ // ModuleName is the name of the module
+ ModuleName = "gravity"
+
+ // StoreKey to be used when creating the KVStore
+ StoreKey = ModuleName
+
+ // RouterKey is the module name router key
+ RouterKey = ModuleName
+
+ // QuerierRoute to be used for querierer msgs
+ QuerierRoute = ModuleName
+)
+
+const (
+ _ = byte(iota)
+ // Key Delegation
+ ValidatorEthereumAddressKey
+ OrchestratorValidatorAddressKey
+ EthereumOrchestratorAddressKey
+
+ // Core types
+ EthereumSignatureKey
+ EthereumEventVoteRecordKey
+ OutgoingTxKey
+ SendToEthereumKey
+
+ // Latest nonce indexes
+ LastEventNonceByValidatorKey
+ LastObservedEventNonceKey
+ LatestSignerSetTxNonceKey
+ LastSlashedOutgoingTxBlockKey
+ LastSlashedSignerSetTxNonceKey
+ LastOutgoingBatchNonceKey
+
+ // LastSendToEthereumIDKey indexes the lastTxPoolID
+ LastSendToEthereumIDKey
+
+ // LastEthereumBlockHeightKey indexes the latest Ethereum block height
+ LastEthereumBlockHeightKey
+
+ // DenomToERC20Key prefixes the index of Cosmos originated asset denoms to ERC20s
+ DenomToERC20Key
+
+ // ERC20ToDenomKey prefixes the index of Cosmos originated assets ERC20s to denoms
+ ERC20ToDenomKey
+
+ // LastUnBondingBlockHeightKey indexes the last validator unbonding block height
+ LastUnBondingBlockHeightKey
+
+ LastObservedSignerSetKey
+)
+
+////////////////////
+// Key Delegation //
+////////////////////
+
+// MakeOrchestratorValidatorAddressKey returns the following key format
+// prefix
+// [0xe8][cosmos1ahx7f8wyertuus9r20284ej0asrs085case3kn]
+func MakeOrchestratorValidatorAddressKey(orc sdk.AccAddress) []byte {
+ return append([]byte{OrchestratorValidatorAddressKey}, orc.Bytes()...)
+}
+
+// MakeValidatorEthereumAddressKey returns the following key format
+// prefix cosmos-validator
+// [0x0][cosmosvaloper1ahx7f8wyertuus9r20284ej0asrs085case3kn]
+func MakeValidatorEthereumAddressKey(validator sdk.ValAddress) []byte {
+ return append([]byte{ValidatorEthereumAddressKey}, validator.Bytes()...)
+}
+
+// MakeEthereumOrchestratorAddressKey returns the following key format
+// prefix cosmos-validator
+// [0x0][cosmosvaloper1ahx7f8wyertuus9r20284ej0asrs085case3kn]
+func MakeEthereumOrchestratorAddressKey(eth common.Address) []byte {
+ return append([]byte{EthereumOrchestratorAddressKey}, eth.Bytes()...)
+}
+
+/////////////////////////
+// Etheruem Signatures //
+/////////////////////////
+
+// MakeEthereumSignatureKey returns the following key format
+// prefix nonce validator-address
+// [0x0][0 0 0 0 0 0 0 1][cosmos1ahx7f8wyertuus9r20284ej0asrs085case3kn]
+func MakeEthereumSignatureKey(storeIndex []byte, validator sdk.ValAddress) []byte {
+ return bytes.Join([][]byte{{EthereumSignatureKey}, storeIndex, validator.Bytes()}, []byte{})
+}
+
+/////////////////////////////////
+// Etheruem Event Vote Records //
+/////////////////////////////////
+
+// MakeEthereumEventVoteRecordKey returns the following key format
+// prefix nonce claim-details-hash
+// [0x5][0 0 0 0 0 0 0 1][fd1af8cec6c67fcf156f1b61fdf91ebc04d05484d007436e75342fc05bbff35a]
+func MakeEthereumEventVoteRecordKey(eventNonce uint64, claimHash []byte) []byte {
+ return bytes.Join([][]byte{{EthereumEventVoteRecordKey}, sdk.Uint64ToBigEndian(eventNonce), claimHash}, []byte{})
+}
+
+//////////////////
+// Outgoing Txs //
+//////////////////
+
+// MakeOutgoingTxKey returns the store index passed with a prefix
+func MakeOutgoingTxKey(storeIndex []byte) []byte {
+ return append([]byte{OutgoingTxKey}, storeIndex...)
+}
+
+//////////////////////
+// Send To Etheruem //
+//////////////////////
+
+// MakeSendToEthereumKey returns the following key format
+// prefix eth-contract-address fee_amount id
+// [0x9][0xc783df8a850f42e7F7e57013759C285caa701eB6][1000000000][0 0 0 0 0 0 0 1]
+func MakeSendToEthereumKey(id uint64, fee ERC20Token) []byte {
+ amount := make([]byte, 32)
+ return bytes.Join([][]byte{{SendToEthereumKey}, common.HexToAddress(fee.Contract).Bytes(), fee.Amount.BigInt().FillBytes(amount), sdk.Uint64ToBigEndian(id)}, []byte{})
+}
+
+// MakeLastEventNonceByValidatorKey indexes lateset event nonce by validator
+// MakeLastEventNonceByValidatorKey returns the following key format
+// prefix cosmos-validator
+// [0x0][cosmos1ahx7f8wyertuus9r20284ej0asrs085case3kn]
+func MakeLastEventNonceByValidatorKey(validator sdk.ValAddress) []byte {
+ return append([]byte{LastEventNonceByValidatorKey}, validator.Bytes()...)
+}
+
+func MakeDenomToERC20Key(denom string) []byte {
+ return append([]byte{DenomToERC20Key}, []byte(denom)...)
+}
+
+func MakeERC20ToDenomKey(erc20 string) []byte {
+ return append([]byte{ERC20ToDenomKey}, []byte(erc20)...)
+}
+
+func MakeSignerSetTxKey(nonce uint64) []byte {
+ return append([]byte{SignerSetTxPrefixByte}, sdk.Uint64ToBigEndian(nonce)...)
+}
+
+func MakeBatchTxKey(addr common.Address, nonce uint64) []byte {
+ return bytes.Join([][]byte{{BatchTxPrefixByte}, addr.Bytes(), sdk.Uint64ToBigEndian(nonce)}, []byte{})
+}
+
+func MakeContractCallTxKey(invalscope []byte, invalnonce uint64) []byte {
+ return bytes.Join([][]byte{{ContractCallTxPrefixByte}, invalscope, sdk.Uint64ToBigEndian(invalnonce)}, []byte{})
+}
diff --git a/module/x/gravity/types/msgs.go b/module/x/gravity/types/msgs.go
new file mode 100644
index 0000000..157b390
--- /dev/null
+++ b/module/x/gravity/types/msgs.go
@@ -0,0 +1,289 @@
+package types
+
+import (
+ "fmt"
+
+ cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/ethereum/go-ethereum/common"
+)
+
+var (
+ _ sdk.Msg = &MsgDelegateKeys{}
+ _ sdk.Msg = &MsgSendToEthereum{}
+ _ sdk.Msg = &MsgCancelSendToEthereum{}
+ _ sdk.Msg = &MsgRequestBatchTx{}
+ _ sdk.Msg = &MsgSubmitEthereumEvent{}
+ _ sdk.Msg = &MsgSubmitEthereumTxConfirmation{}
+
+ _ cdctypes.UnpackInterfacesMessage = &MsgSubmitEthereumEvent{}
+ _ cdctypes.UnpackInterfacesMessage = &MsgSubmitEthereumTxConfirmation{}
+ _ cdctypes.UnpackInterfacesMessage = &EthereumEventVoteRecord{}
+)
+
+// NewMsgDelegateKeys returns a reference to a new MsgDelegateKeys.
+func NewMsgDelegateKeys(val sdk.ValAddress, orchAddr sdk.AccAddress, ethAddr string, ethSig []byte) *MsgDelegateKeys {
+ return &MsgDelegateKeys{
+ ValidatorAddress: val.String(),
+ OrchestratorAddress: orchAddr.String(),
+ EthereumAddress: ethAddr,
+ EthSignature: ethSig,
+ }
+}
+
+// Route should return the name of the module
+func (msg *MsgDelegateKeys) Route() string { return RouterKey }
+
+// Type should return the action
+func (msg *MsgDelegateKeys) Type() string { return "delegate_keys" }
+
+// ValidateBasic performs stateless checks
+func (msg *MsgDelegateKeys) ValidateBasic() (err error) {
+ if _, err = sdk.ValAddressFromBech32(msg.ValidatorAddress); err != nil {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.ValidatorAddress)
+ }
+ if _, err = sdk.AccAddressFromBech32(msg.OrchestratorAddress); err != nil {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.OrchestratorAddress)
+ }
+ if !common.IsHexAddress(msg.EthereumAddress) {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "ethereum address")
+ }
+ if len(msg.EthSignature) == 0 {
+ return ErrEmptyEthSig
+ }
+
+ return nil
+}
+
+// GetSignBytes encodes the message for signing
+func (msg *MsgDelegateKeys) GetSignBytes() []byte {
+ return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg))
+}
+
+// GetSigners defines whose signature is required
+func (msg *MsgDelegateKeys) GetSigners() []sdk.AccAddress {
+ acc, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
+ if err != nil {
+ panic(err)
+ }
+ return []sdk.AccAddress{sdk.AccAddress(acc)}
+}
+
+// Route should return the name of the module
+func (msg *MsgSubmitEthereumEvent) Route() string { return RouterKey }
+
+// Type should return the action
+func (msg *MsgSubmitEthereumEvent) Type() string { return "submit_ethereum_event" }
+
+// ValidateBasic performs stateless checks
+func (msg *MsgSubmitEthereumEvent) ValidateBasic() (err error) {
+ if _, err = sdk.AccAddressFromBech32(msg.Signer); err != nil {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Signer)
+ }
+
+ event, err := UnpackEvent(msg.Event)
+ if err != nil {
+ return err
+ }
+ return event.Validate()
+}
+
+// GetSignBytes encodes the message for signing
+func (msg *MsgSubmitEthereumEvent) GetSignBytes() []byte {
+ panic(fmt.Errorf("deprecated"))
+}
+
+// GetSigners defines whose signature is required
+func (msg *MsgSubmitEthereumEvent) GetSigners() []sdk.AccAddress {
+ // TODO: figure out how to convert between AccAddress and ValAddress properly
+ acc, err := sdk.AccAddressFromBech32(msg.Signer)
+ if err != nil {
+ panic(err)
+ }
+ return []sdk.AccAddress{acc}
+}
+
+func (msg *MsgSubmitEthereumEvent) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
+ var event EthereumEvent
+ return unpacker.UnpackAny(msg.Event, &event)
+}
+
+// Route should return the name of the module
+func (msg *MsgSubmitEthereumTxConfirmation) Route() string { return RouterKey }
+
+// Type should return the action
+func (msg *MsgSubmitEthereumTxConfirmation) Type() string { return "submit_ethereum_signature" }
+
+// ValidateBasic performs stateless checks
+func (msg *MsgSubmitEthereumTxConfirmation) ValidateBasic() (err error) {
+ if _, err = sdk.AccAddressFromBech32(msg.Signer); err != nil {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Signer)
+ }
+
+ event, err := UnpackConfirmation(msg.Confirmation)
+
+ if err != nil {
+ return err
+ }
+
+ return event.Validate()
+}
+
+// GetSignBytes encodes the message for signing
+func (msg *MsgSubmitEthereumTxConfirmation) GetSignBytes() []byte {
+ panic(fmt.Errorf("deprecated"))
+}
+
+// GetSigners defines whose signature is required
+func (msg *MsgSubmitEthereumTxConfirmation) GetSigners() []sdk.AccAddress {
+ // TODO: figure out how to convert between AccAddress and ValAddress properly
+ acc, err := sdk.AccAddressFromBech32(msg.Signer)
+ if err != nil {
+ panic(err)
+ }
+ return []sdk.AccAddress{acc}
+}
+
+func (msg *MsgSubmitEthereumTxConfirmation) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
+ var sig EthereumTxConfirmation
+ return unpacker.UnpackAny(msg.Confirmation, &sig)
+}
+
+// NewMsgSendToEthereum returns a new MsgSendToEthereum
+func NewMsgSendToEthereum(sender sdk.AccAddress, destAddress string, send sdk.Coin, bridgeFee sdk.Coin) *MsgSendToEthereum {
+ return &MsgSendToEthereum{
+ Sender: sender.String(),
+ EthereumRecipient: destAddress,
+ Amount: send,
+ BridgeFee: bridgeFee,
+ }
+}
+
+// Route should return the name of the module
+func (msg MsgSendToEthereum) Route() string { return RouterKey }
+
+// Type should return the action
+func (msg MsgSendToEthereum) Type() string { return "send_to_eth" }
+
+// ValidateBasic runs stateless checks on the message
+// Checks if the Eth address is valid
+func (msg MsgSendToEthereum) ValidateBasic() error {
+ if _, err := sdk.AccAddressFromBech32(msg.Sender); err != nil {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Sender)
+ }
+
+ // fee and send must be of the same denom
+ // this check is VERY IMPORTANT
+ if msg.Amount.Denom != msg.BridgeFee.Denom {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins,
+ fmt.Sprintf("fee and amount must be the same type %s != %s", msg.Amount.Denom, msg.BridgeFee.Denom))
+ }
+
+ if !msg.Amount.IsValid() || msg.Amount.IsZero() {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "amount")
+ }
+ if !msg.BridgeFee.IsValid() {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "fee")
+ }
+ if !common.IsHexAddress(msg.EthereumRecipient) {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "ethereum address")
+ }
+
+ return nil
+}
+
+// GetSignBytes encodes the message for signing
+func (msg MsgSendToEthereum) GetSignBytes() []byte {
+ panic(fmt.Errorf("deprecated"))
+}
+
+// GetSigners defines whose signature is required
+func (msg MsgSendToEthereum) GetSigners() []sdk.AccAddress {
+ acc, err := sdk.AccAddressFromBech32(msg.Sender)
+ if err != nil {
+ panic(err)
+ }
+
+ return []sdk.AccAddress{acc}
+}
+
+// NewMsgRequestBatchTx returns a new msgRequestBatch
+func NewMsgRequestBatchTx(denom string, signer sdk.AccAddress) *MsgRequestBatchTx {
+ return &MsgRequestBatchTx{
+ Denom: denom,
+ Signer: signer.String(),
+ }
+}
+
+// Route should return the name of the module
+func (msg MsgRequestBatchTx) Route() string { return RouterKey }
+
+// Type should return the action
+func (msg MsgRequestBatchTx) Type() string { return "request_batch" }
+
+// ValidateBasic performs stateless checks
+func (msg MsgRequestBatchTx) ValidateBasic() error {
+ if err := sdk.ValidateDenom(msg.Denom); err != nil {
+ return sdkerrors.Wrap(err, "denom is invalid")
+ }
+ if _, err := sdk.AccAddressFromBech32(msg.Signer); err != nil {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Signer)
+ }
+ return nil
+}
+
+// GetSignBytes encodes the message for signing
+func (msg MsgRequestBatchTx) GetSignBytes() []byte {
+ panic(fmt.Errorf("deprecated"))
+}
+
+// GetSigners defines whose signature is required
+func (msg MsgRequestBatchTx) GetSigners() []sdk.AccAddress {
+ acc, err := sdk.AccAddressFromBech32(msg.Signer)
+ if err != nil {
+ panic(err)
+ }
+
+ return []sdk.AccAddress{acc}
+}
+
+// NewMsgCancelSendToEthereum returns a new MsgCancelSendToEthereum
+func NewMsgCancelSendToEthereum(id uint64, orchestrator sdk.AccAddress) *MsgCancelSendToEthereum {
+ return &MsgCancelSendToEthereum{
+ Id: id,
+ Sender: orchestrator.String(),
+ }
+}
+
+// Route should return the name of the module
+func (msg MsgCancelSendToEthereum) Route() string { return RouterKey }
+
+// Type should return the action
+func (msg MsgCancelSendToEthereum) Type() string { return "cancel_send_to_ethereum" }
+
+// ValidateBasic performs stateless checks
+func (msg MsgCancelSendToEthereum) ValidateBasic() error {
+ if msg.Id == 0 {
+ return sdkerrors.Wrap(ErrInvalid, "Id cannot be 0")
+ }
+ if _, err := sdk.AccAddressFromBech32(msg.Sender); err != nil {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Sender)
+ }
+ return nil
+}
+
+// GetSignBytes encodes the message for signing
+func (msg MsgCancelSendToEthereum) GetSignBytes() []byte {
+ panic(fmt.Errorf("deprecated"))
+}
+
+// GetSigners defines whose signature is required
+func (msg MsgCancelSendToEthereum) GetSigners() []sdk.AccAddress {
+ acc, err := sdk.AccAddressFromBech32(msg.Sender)
+ if err != nil {
+ panic(err)
+ }
+
+ return []sdk.AccAddress{acc}
+}
diff --git a/module/x/gravity/types/msgs.pb.go b/module/x/gravity/types/msgs.pb.go
new file mode 100644
index 0000000..7ff255c
--- /dev/null
+++ b/module/x/gravity/types/msgs.pb.go
@@ -0,0 +1,5626 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: gravity/v1/msgs.proto
+
+package types
+
+import (
+ context "context"
+ fmt "fmt"
+ types1 "github.com/cosmos/cosmos-sdk/codec/types"
+ github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
+ types "github.com/cosmos/cosmos-sdk/types"
+ _ "github.com/gogo/protobuf/gogoproto"
+ grpc1 "github.com/gogo/protobuf/grpc"
+ proto "github.com/gogo/protobuf/proto"
+ _ "github.com/regen-network/cosmos-proto"
+ github_com_tendermint_tendermint_libs_bytes "github.com/tendermint/tendermint/libs/bytes"
+ _ "google.golang.org/genproto/googleapis/api/annotations"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+ io "io"
+ math "math"
+ math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// MsgSendToEthereum submits a SendToEthereum attempt to bridge an asset over to
+// Ethereum. The SendToEthereum will be stored and then included in a batch and
+// then submitted to Ethereum.
+type MsgSendToEthereum struct {
+ Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"`
+ EthereumRecipient string `protobuf:"bytes,2,opt,name=ethereum_recipient,json=ethereumRecipient,proto3" json:"ethereum_recipient,omitempty"`
+ Amount types.Coin `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount"`
+ BridgeFee types.Coin `protobuf:"bytes,4,opt,name=bridge_fee,json=bridgeFee,proto3" json:"bridge_fee"`
+}
+
+func (m *MsgSendToEthereum) Reset() { *m = MsgSendToEthereum{} }
+func (m *MsgSendToEthereum) String() string { return proto.CompactTextString(m) }
+func (*MsgSendToEthereum) ProtoMessage() {}
+func (*MsgSendToEthereum) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{0}
+}
+func (m *MsgSendToEthereum) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgSendToEthereum) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgSendToEthereum.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgSendToEthereum) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgSendToEthereum.Merge(m, src)
+}
+func (m *MsgSendToEthereum) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgSendToEthereum) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgSendToEthereum.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgSendToEthereum proto.InternalMessageInfo
+
+func (m *MsgSendToEthereum) GetSender() string {
+ if m != nil {
+ return m.Sender
+ }
+ return ""
+}
+
+func (m *MsgSendToEthereum) GetEthereumRecipient() string {
+ if m != nil {
+ return m.EthereumRecipient
+ }
+ return ""
+}
+
+func (m *MsgSendToEthereum) GetAmount() types.Coin {
+ if m != nil {
+ return m.Amount
+ }
+ return types.Coin{}
+}
+
+func (m *MsgSendToEthereum) GetBridgeFee() types.Coin {
+ if m != nil {
+ return m.BridgeFee
+ }
+ return types.Coin{}
+}
+
+// MsgSendToEthereumResponse returns the SendToEthereum transaction ID which
+// will be included in the batch tx.
+type MsgSendToEthereumResponse struct {
+ Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+}
+
+func (m *MsgSendToEthereumResponse) Reset() { *m = MsgSendToEthereumResponse{} }
+func (m *MsgSendToEthereumResponse) String() string { return proto.CompactTextString(m) }
+func (*MsgSendToEthereumResponse) ProtoMessage() {}
+func (*MsgSendToEthereumResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{1}
+}
+func (m *MsgSendToEthereumResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgSendToEthereumResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgSendToEthereumResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgSendToEthereumResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgSendToEthereumResponse.Merge(m, src)
+}
+func (m *MsgSendToEthereumResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgSendToEthereumResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgSendToEthereumResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgSendToEthereumResponse proto.InternalMessageInfo
+
+func (m *MsgSendToEthereumResponse) GetId() uint64 {
+ if m != nil {
+ return m.Id
+ }
+ return 0
+}
+
+// MsgCancelSendToEthereum allows the sender to cancel its own outgoing
+// SendToEthereum tx and recieve a refund of the tokens and bridge fees. This tx
+// will only succeed if the SendToEthereum tx hasn't been batched to be
+// processed and relayed to Ethereum.
+type MsgCancelSendToEthereum struct {
+ Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"`
+}
+
+func (m *MsgCancelSendToEthereum) Reset() { *m = MsgCancelSendToEthereum{} }
+func (m *MsgCancelSendToEthereum) String() string { return proto.CompactTextString(m) }
+func (*MsgCancelSendToEthereum) ProtoMessage() {}
+func (*MsgCancelSendToEthereum) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{2}
+}
+func (m *MsgCancelSendToEthereum) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgCancelSendToEthereum) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgCancelSendToEthereum.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgCancelSendToEthereum) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgCancelSendToEthereum.Merge(m, src)
+}
+func (m *MsgCancelSendToEthereum) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgCancelSendToEthereum) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgCancelSendToEthereum.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgCancelSendToEthereum proto.InternalMessageInfo
+
+func (m *MsgCancelSendToEthereum) GetId() uint64 {
+ if m != nil {
+ return m.Id
+ }
+ return 0
+}
+
+func (m *MsgCancelSendToEthereum) GetSender() string {
+ if m != nil {
+ return m.Sender
+ }
+ return ""
+}
+
+type MsgCancelSendToEthereumResponse struct {
+}
+
+func (m *MsgCancelSendToEthereumResponse) Reset() { *m = MsgCancelSendToEthereumResponse{} }
+func (m *MsgCancelSendToEthereumResponse) String() string { return proto.CompactTextString(m) }
+func (*MsgCancelSendToEthereumResponse) ProtoMessage() {}
+func (*MsgCancelSendToEthereumResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{3}
+}
+func (m *MsgCancelSendToEthereumResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgCancelSendToEthereumResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgCancelSendToEthereumResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgCancelSendToEthereumResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgCancelSendToEthereumResponse.Merge(m, src)
+}
+func (m *MsgCancelSendToEthereumResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgCancelSendToEthereumResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgCancelSendToEthereumResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgCancelSendToEthereumResponse proto.InternalMessageInfo
+
+// MsgRequestBatchTx requests a batch of transactions with a given coin
+// denomination to send across the bridge to Ethereum.
+type MsgRequestBatchTx struct {
+ Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
+ Signer string `protobuf:"bytes,2,opt,name=signer,proto3" json:"signer,omitempty"`
+}
+
+func (m *MsgRequestBatchTx) Reset() { *m = MsgRequestBatchTx{} }
+func (m *MsgRequestBatchTx) String() string { return proto.CompactTextString(m) }
+func (*MsgRequestBatchTx) ProtoMessage() {}
+func (*MsgRequestBatchTx) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{4}
+}
+func (m *MsgRequestBatchTx) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgRequestBatchTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgRequestBatchTx.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgRequestBatchTx) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgRequestBatchTx.Merge(m, src)
+}
+func (m *MsgRequestBatchTx) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgRequestBatchTx) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgRequestBatchTx.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgRequestBatchTx proto.InternalMessageInfo
+
+func (m *MsgRequestBatchTx) GetDenom() string {
+ if m != nil {
+ return m.Denom
+ }
+ return ""
+}
+
+func (m *MsgRequestBatchTx) GetSigner() string {
+ if m != nil {
+ return m.Signer
+ }
+ return ""
+}
+
+type MsgRequestBatchTxResponse struct {
+}
+
+func (m *MsgRequestBatchTxResponse) Reset() { *m = MsgRequestBatchTxResponse{} }
+func (m *MsgRequestBatchTxResponse) String() string { return proto.CompactTextString(m) }
+func (*MsgRequestBatchTxResponse) ProtoMessage() {}
+func (*MsgRequestBatchTxResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{5}
+}
+func (m *MsgRequestBatchTxResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgRequestBatchTxResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgRequestBatchTxResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgRequestBatchTxResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgRequestBatchTxResponse.Merge(m, src)
+}
+func (m *MsgRequestBatchTxResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgRequestBatchTxResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgRequestBatchTxResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgRequestBatchTxResponse proto.InternalMessageInfo
+
+// MsgSubmitEthereumTxConfirmation submits an ethereum signature for a given
+// validator
+type MsgSubmitEthereumTxConfirmation struct {
+ // TODO: can we make this take an array?
+ Confirmation *types1.Any `protobuf:"bytes,1,opt,name=confirmation,proto3" json:"confirmation,omitempty"`
+ Signer string `protobuf:"bytes,2,opt,name=signer,proto3" json:"signer,omitempty"`
+}
+
+func (m *MsgSubmitEthereumTxConfirmation) Reset() { *m = MsgSubmitEthereumTxConfirmation{} }
+func (m *MsgSubmitEthereumTxConfirmation) String() string { return proto.CompactTextString(m) }
+func (*MsgSubmitEthereumTxConfirmation) ProtoMessage() {}
+func (*MsgSubmitEthereumTxConfirmation) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{6}
+}
+func (m *MsgSubmitEthereumTxConfirmation) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgSubmitEthereumTxConfirmation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgSubmitEthereumTxConfirmation.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgSubmitEthereumTxConfirmation) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgSubmitEthereumTxConfirmation.Merge(m, src)
+}
+func (m *MsgSubmitEthereumTxConfirmation) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgSubmitEthereumTxConfirmation) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgSubmitEthereumTxConfirmation.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgSubmitEthereumTxConfirmation proto.InternalMessageInfo
+
+// ContractCallTxConfirmation is a signature on behalf of a validator for a
+// ContractCallTx.
+type ContractCallTxConfirmation struct {
+ InvalidationScope []byte `protobuf:"bytes,1,opt,name=invalidation_scope,json=invalidationScope,proto3" json:"invalidation_scope,omitempty"`
+ InvalidationNonce uint64 `protobuf:"varint,2,opt,name=invalidation_nonce,json=invalidationNonce,proto3" json:"invalidation_nonce,omitempty"`
+ EthereumSigner string `protobuf:"bytes,3,opt,name=ethereum_signer,json=ethereumSigner,proto3" json:"ethereum_signer,omitempty"`
+ Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"`
+}
+
+func (m *ContractCallTxConfirmation) Reset() { *m = ContractCallTxConfirmation{} }
+func (m *ContractCallTxConfirmation) String() string { return proto.CompactTextString(m) }
+func (*ContractCallTxConfirmation) ProtoMessage() {}
+func (*ContractCallTxConfirmation) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{7}
+}
+func (m *ContractCallTxConfirmation) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ContractCallTxConfirmation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ContractCallTxConfirmation.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ContractCallTxConfirmation) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ContractCallTxConfirmation.Merge(m, src)
+}
+func (m *ContractCallTxConfirmation) XXX_Size() int {
+ return m.Size()
+}
+func (m *ContractCallTxConfirmation) XXX_DiscardUnknown() {
+ xxx_messageInfo_ContractCallTxConfirmation.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ContractCallTxConfirmation proto.InternalMessageInfo
+
+func (m *ContractCallTxConfirmation) GetInvalidationScope() []byte {
+ if m != nil {
+ return m.InvalidationScope
+ }
+ return nil
+}
+
+func (m *ContractCallTxConfirmation) GetInvalidationNonce() uint64 {
+ if m != nil {
+ return m.InvalidationNonce
+ }
+ return 0
+}
+
+func (m *ContractCallTxConfirmation) GetEthereumSigner() string {
+ if m != nil {
+ return m.EthereumSigner
+ }
+ return ""
+}
+
+func (m *ContractCallTxConfirmation) GetSignature() []byte {
+ if m != nil {
+ return m.Signature
+ }
+ return nil
+}
+
+// BatchTxConfirmation is a signature on behalf of a validator for a BatchTx.
+type BatchTxConfirmation struct {
+ TokenContract string `protobuf:"bytes,1,opt,name=token_contract,json=tokenContract,proto3" json:"token_contract,omitempty"`
+ BatchNonce uint64 `protobuf:"varint,2,opt,name=batch_nonce,json=batchNonce,proto3" json:"batch_nonce,omitempty"`
+ EthereumSigner string `protobuf:"bytes,3,opt,name=ethereum_signer,json=ethereumSigner,proto3" json:"ethereum_signer,omitempty"`
+ Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"`
+}
+
+func (m *BatchTxConfirmation) Reset() { *m = BatchTxConfirmation{} }
+func (m *BatchTxConfirmation) String() string { return proto.CompactTextString(m) }
+func (*BatchTxConfirmation) ProtoMessage() {}
+func (*BatchTxConfirmation) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{8}
+}
+func (m *BatchTxConfirmation) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTxConfirmation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTxConfirmation.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTxConfirmation) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTxConfirmation.Merge(m, src)
+}
+func (m *BatchTxConfirmation) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTxConfirmation) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTxConfirmation.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTxConfirmation proto.InternalMessageInfo
+
+func (m *BatchTxConfirmation) GetTokenContract() string {
+ if m != nil {
+ return m.TokenContract
+ }
+ return ""
+}
+
+func (m *BatchTxConfirmation) GetBatchNonce() uint64 {
+ if m != nil {
+ return m.BatchNonce
+ }
+ return 0
+}
+
+func (m *BatchTxConfirmation) GetEthereumSigner() string {
+ if m != nil {
+ return m.EthereumSigner
+ }
+ return ""
+}
+
+func (m *BatchTxConfirmation) GetSignature() []byte {
+ if m != nil {
+ return m.Signature
+ }
+ return nil
+}
+
+// SignerSetTxConfirmation is a signature on behalf of a validator for a
+// SignerSetTx
+type SignerSetTxConfirmation struct {
+ SignerSetNonce uint64 `protobuf:"varint,1,opt,name=signer_set_nonce,json=signerSetNonce,proto3" json:"signer_set_nonce,omitempty"`
+ EthereumSigner string `protobuf:"bytes,2,opt,name=ethereum_signer,json=ethereumSigner,proto3" json:"ethereum_signer,omitempty"`
+ Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"`
+}
+
+func (m *SignerSetTxConfirmation) Reset() { *m = SignerSetTxConfirmation{} }
+func (m *SignerSetTxConfirmation) String() string { return proto.CompactTextString(m) }
+func (*SignerSetTxConfirmation) ProtoMessage() {}
+func (*SignerSetTxConfirmation) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{9}
+}
+func (m *SignerSetTxConfirmation) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SignerSetTxConfirmation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SignerSetTxConfirmation.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SignerSetTxConfirmation) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SignerSetTxConfirmation.Merge(m, src)
+}
+func (m *SignerSetTxConfirmation) XXX_Size() int {
+ return m.Size()
+}
+func (m *SignerSetTxConfirmation) XXX_DiscardUnknown() {
+ xxx_messageInfo_SignerSetTxConfirmation.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignerSetTxConfirmation proto.InternalMessageInfo
+
+func (m *SignerSetTxConfirmation) GetSignerSetNonce() uint64 {
+ if m != nil {
+ return m.SignerSetNonce
+ }
+ return 0
+}
+
+func (m *SignerSetTxConfirmation) GetEthereumSigner() string {
+ if m != nil {
+ return m.EthereumSigner
+ }
+ return ""
+}
+
+func (m *SignerSetTxConfirmation) GetSignature() []byte {
+ if m != nil {
+ return m.Signature
+ }
+ return nil
+}
+
+type MsgSubmitEthereumTxConfirmationResponse struct {
+}
+
+func (m *MsgSubmitEthereumTxConfirmationResponse) Reset() {
+ *m = MsgSubmitEthereumTxConfirmationResponse{}
+}
+func (m *MsgSubmitEthereumTxConfirmationResponse) String() string { return proto.CompactTextString(m) }
+func (*MsgSubmitEthereumTxConfirmationResponse) ProtoMessage() {}
+func (*MsgSubmitEthereumTxConfirmationResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{10}
+}
+func (m *MsgSubmitEthereumTxConfirmationResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgSubmitEthereumTxConfirmationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgSubmitEthereumTxConfirmationResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgSubmitEthereumTxConfirmationResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgSubmitEthereumTxConfirmationResponse.Merge(m, src)
+}
+func (m *MsgSubmitEthereumTxConfirmationResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgSubmitEthereumTxConfirmationResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgSubmitEthereumTxConfirmationResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgSubmitEthereumTxConfirmationResponse proto.InternalMessageInfo
+
+// MsgSubmitEthereumEvent
+type MsgSubmitEthereumEvent struct {
+ Event *types1.Any `protobuf:"bytes,1,opt,name=event,proto3" json:"event,omitempty"`
+ Signer string `protobuf:"bytes,2,opt,name=signer,proto3" json:"signer,omitempty"`
+}
+
+func (m *MsgSubmitEthereumEvent) Reset() { *m = MsgSubmitEthereumEvent{} }
+func (m *MsgSubmitEthereumEvent) String() string { return proto.CompactTextString(m) }
+func (*MsgSubmitEthereumEvent) ProtoMessage() {}
+func (*MsgSubmitEthereumEvent) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{11}
+}
+func (m *MsgSubmitEthereumEvent) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgSubmitEthereumEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgSubmitEthereumEvent.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgSubmitEthereumEvent) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgSubmitEthereumEvent.Merge(m, src)
+}
+func (m *MsgSubmitEthereumEvent) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgSubmitEthereumEvent) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgSubmitEthereumEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgSubmitEthereumEvent proto.InternalMessageInfo
+
+type MsgSubmitEthereumEventResponse struct {
+}
+
+func (m *MsgSubmitEthereumEventResponse) Reset() { *m = MsgSubmitEthereumEventResponse{} }
+func (m *MsgSubmitEthereumEventResponse) String() string { return proto.CompactTextString(m) }
+func (*MsgSubmitEthereumEventResponse) ProtoMessage() {}
+func (*MsgSubmitEthereumEventResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{12}
+}
+func (m *MsgSubmitEthereumEventResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgSubmitEthereumEventResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgSubmitEthereumEventResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgSubmitEthereumEventResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgSubmitEthereumEventResponse.Merge(m, src)
+}
+func (m *MsgSubmitEthereumEventResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgSubmitEthereumEventResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgSubmitEthereumEventResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgSubmitEthereumEventResponse proto.InternalMessageInfo
+
+// MsgDelegateKey allows validators to delegate their voting responsibilities
+// to a given orchestrator address. This key is then used as an optional
+// authentication method for attesting events from Ethereum.
+type MsgDelegateKeys struct {
+ ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
+ OrchestratorAddress string `protobuf:"bytes,2,opt,name=orchestrator_address,json=orchestratorAddress,proto3" json:"orchestrator_address,omitempty"`
+ EthereumAddress string `protobuf:"bytes,3,opt,name=ethereum_address,json=ethereumAddress,proto3" json:"ethereum_address,omitempty"`
+ EthSignature []byte `protobuf:"bytes,4,opt,name=eth_signature,json=ethSignature,proto3" json:"eth_signature,omitempty"`
+}
+
+func (m *MsgDelegateKeys) Reset() { *m = MsgDelegateKeys{} }
+func (m *MsgDelegateKeys) String() string { return proto.CompactTextString(m) }
+func (*MsgDelegateKeys) ProtoMessage() {}
+func (*MsgDelegateKeys) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{13}
+}
+func (m *MsgDelegateKeys) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgDelegateKeys) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgDelegateKeys.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgDelegateKeys) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgDelegateKeys.Merge(m, src)
+}
+func (m *MsgDelegateKeys) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgDelegateKeys) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgDelegateKeys.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgDelegateKeys proto.InternalMessageInfo
+
+func (m *MsgDelegateKeys) GetValidatorAddress() string {
+ if m != nil {
+ return m.ValidatorAddress
+ }
+ return ""
+}
+
+func (m *MsgDelegateKeys) GetOrchestratorAddress() string {
+ if m != nil {
+ return m.OrchestratorAddress
+ }
+ return ""
+}
+
+func (m *MsgDelegateKeys) GetEthereumAddress() string {
+ if m != nil {
+ return m.EthereumAddress
+ }
+ return ""
+}
+
+func (m *MsgDelegateKeys) GetEthSignature() []byte {
+ if m != nil {
+ return m.EthSignature
+ }
+ return nil
+}
+
+type MsgDelegateKeysResponse struct {
+}
+
+func (m *MsgDelegateKeysResponse) Reset() { *m = MsgDelegateKeysResponse{} }
+func (m *MsgDelegateKeysResponse) String() string { return proto.CompactTextString(m) }
+func (*MsgDelegateKeysResponse) ProtoMessage() {}
+func (*MsgDelegateKeysResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{14}
+}
+func (m *MsgDelegateKeysResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgDelegateKeysResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgDelegateKeysResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgDelegateKeysResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgDelegateKeysResponse.Merge(m, src)
+}
+func (m *MsgDelegateKeysResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgDelegateKeysResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgDelegateKeysResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgDelegateKeysResponse proto.InternalMessageInfo
+
+// DelegateKeysSignMsg defines the message structure an operator is expected to
+// sign when submitting a MsgDelegateKeys message. The resulting signature should
+// populate the eth_signature field.
+type DelegateKeysSignMsg struct {
+ ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
+ Nonce uint64 `protobuf:"varint,2,opt,name=nonce,proto3" json:"nonce,omitempty"`
+}
+
+func (m *DelegateKeysSignMsg) Reset() { *m = DelegateKeysSignMsg{} }
+func (m *DelegateKeysSignMsg) String() string { return proto.CompactTextString(m) }
+func (*DelegateKeysSignMsg) ProtoMessage() {}
+func (*DelegateKeysSignMsg) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{15}
+}
+func (m *DelegateKeysSignMsg) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DelegateKeysSignMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DelegateKeysSignMsg.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DelegateKeysSignMsg) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DelegateKeysSignMsg.Merge(m, src)
+}
+func (m *DelegateKeysSignMsg) XXX_Size() int {
+ return m.Size()
+}
+func (m *DelegateKeysSignMsg) XXX_DiscardUnknown() {
+ xxx_messageInfo_DelegateKeysSignMsg.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DelegateKeysSignMsg proto.InternalMessageInfo
+
+func (m *DelegateKeysSignMsg) GetValidatorAddress() string {
+ if m != nil {
+ return m.ValidatorAddress
+ }
+ return ""
+}
+
+func (m *DelegateKeysSignMsg) GetNonce() uint64 {
+ if m != nil {
+ return m.Nonce
+ }
+ return 0
+}
+
+// SendToCosmosEvent is submitted when the SendToCosmosEvent is emitted by they
+// gravity contract. ERC20 representation coins are minted to the cosmosreceiver
+// address.
+type SendToCosmosEvent struct {
+ EventNonce uint64 `protobuf:"varint,1,opt,name=event_nonce,json=eventNonce,proto3" json:"event_nonce,omitempty"`
+ TokenContract string `protobuf:"bytes,2,opt,name=token_contract,json=tokenContract,proto3" json:"token_contract,omitempty"`
+ Amount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount"`
+ EthereumSender string `protobuf:"bytes,4,opt,name=ethereum_sender,json=ethereumSender,proto3" json:"ethereum_sender,omitempty"`
+ CosmosReceiver string `protobuf:"bytes,5,opt,name=cosmos_receiver,json=cosmosReceiver,proto3" json:"cosmos_receiver,omitempty"`
+ EthereumHeight uint64 `protobuf:"varint,6,opt,name=ethereum_height,json=ethereumHeight,proto3" json:"ethereum_height,omitempty"`
+}
+
+func (m *SendToCosmosEvent) Reset() { *m = SendToCosmosEvent{} }
+func (m *SendToCosmosEvent) String() string { return proto.CompactTextString(m) }
+func (*SendToCosmosEvent) ProtoMessage() {}
+func (*SendToCosmosEvent) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{16}
+}
+func (m *SendToCosmosEvent) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SendToCosmosEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SendToCosmosEvent.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SendToCosmosEvent) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SendToCosmosEvent.Merge(m, src)
+}
+func (m *SendToCosmosEvent) XXX_Size() int {
+ return m.Size()
+}
+func (m *SendToCosmosEvent) XXX_DiscardUnknown() {
+ xxx_messageInfo_SendToCosmosEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SendToCosmosEvent proto.InternalMessageInfo
+
+func (m *SendToCosmosEvent) GetEventNonce() uint64 {
+ if m != nil {
+ return m.EventNonce
+ }
+ return 0
+}
+
+func (m *SendToCosmosEvent) GetTokenContract() string {
+ if m != nil {
+ return m.TokenContract
+ }
+ return ""
+}
+
+func (m *SendToCosmosEvent) GetEthereumSender() string {
+ if m != nil {
+ return m.EthereumSender
+ }
+ return ""
+}
+
+func (m *SendToCosmosEvent) GetCosmosReceiver() string {
+ if m != nil {
+ return m.CosmosReceiver
+ }
+ return ""
+}
+
+func (m *SendToCosmosEvent) GetEthereumHeight() uint64 {
+ if m != nil {
+ return m.EthereumHeight
+ }
+ return 0
+}
+
+// BatchExecutedEvent claims that a batch of BatchTxExecutedal operations on the
+// bridge contract was executed successfully on ETH
+type BatchExecutedEvent struct {
+ TokenContract string `protobuf:"bytes,1,opt,name=token_contract,json=tokenContract,proto3" json:"token_contract,omitempty"`
+ EventNonce uint64 `protobuf:"varint,2,opt,name=event_nonce,json=eventNonce,proto3" json:"event_nonce,omitempty"`
+ EthereumHeight uint64 `protobuf:"varint,3,opt,name=ethereum_height,json=ethereumHeight,proto3" json:"ethereum_height,omitempty"`
+ BatchNonce uint64 `protobuf:"varint,4,opt,name=batch_nonce,json=batchNonce,proto3" json:"batch_nonce,omitempty"`
+}
+
+func (m *BatchExecutedEvent) Reset() { *m = BatchExecutedEvent{} }
+func (m *BatchExecutedEvent) String() string { return proto.CompactTextString(m) }
+func (*BatchExecutedEvent) ProtoMessage() {}
+func (*BatchExecutedEvent) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{17}
+}
+func (m *BatchExecutedEvent) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchExecutedEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchExecutedEvent.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchExecutedEvent) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchExecutedEvent.Merge(m, src)
+}
+func (m *BatchExecutedEvent) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchExecutedEvent) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchExecutedEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchExecutedEvent proto.InternalMessageInfo
+
+func (m *BatchExecutedEvent) GetTokenContract() string {
+ if m != nil {
+ return m.TokenContract
+ }
+ return ""
+}
+
+func (m *BatchExecutedEvent) GetEventNonce() uint64 {
+ if m != nil {
+ return m.EventNonce
+ }
+ return 0
+}
+
+func (m *BatchExecutedEvent) GetEthereumHeight() uint64 {
+ if m != nil {
+ return m.EthereumHeight
+ }
+ return 0
+}
+
+func (m *BatchExecutedEvent) GetBatchNonce() uint64 {
+ if m != nil {
+ return m.BatchNonce
+ }
+ return 0
+}
+
+// NOTE: bytes.HexBytes is supposed to "help" with json encoding/decoding
+// investigate?
+type ContractCallExecutedEvent struct {
+ EventNonce uint64 `protobuf:"varint,1,opt,name=event_nonce,json=eventNonce,proto3" json:"event_nonce,omitempty"`
+ InvalidationScope github_com_tendermint_tendermint_libs_bytes.HexBytes `protobuf:"bytes,2,opt,name=invalidation_scope,json=invalidationScope,proto3,casttype=github.com/tendermint/tendermint/libs/bytes.HexBytes" json:"invalidation_scope,omitempty"`
+ InvalidationNonce uint64 `protobuf:"varint,3,opt,name=invalidation_nonce,json=invalidationNonce,proto3" json:"invalidation_nonce,omitempty"`
+ EthereumHeight uint64 `protobuf:"varint,4,opt,name=ethereum_height,json=ethereumHeight,proto3" json:"ethereum_height,omitempty"`
+}
+
+func (m *ContractCallExecutedEvent) Reset() { *m = ContractCallExecutedEvent{} }
+func (m *ContractCallExecutedEvent) String() string { return proto.CompactTextString(m) }
+func (*ContractCallExecutedEvent) ProtoMessage() {}
+func (*ContractCallExecutedEvent) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{18}
+}
+func (m *ContractCallExecutedEvent) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ContractCallExecutedEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ContractCallExecutedEvent.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ContractCallExecutedEvent) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ContractCallExecutedEvent.Merge(m, src)
+}
+func (m *ContractCallExecutedEvent) XXX_Size() int {
+ return m.Size()
+}
+func (m *ContractCallExecutedEvent) XXX_DiscardUnknown() {
+ xxx_messageInfo_ContractCallExecutedEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ContractCallExecutedEvent proto.InternalMessageInfo
+
+func (m *ContractCallExecutedEvent) GetEventNonce() uint64 {
+ if m != nil {
+ return m.EventNonce
+ }
+ return 0
+}
+
+func (m *ContractCallExecutedEvent) GetInvalidationScope() github_com_tendermint_tendermint_libs_bytes.HexBytes {
+ if m != nil {
+ return m.InvalidationScope
+ }
+ return nil
+}
+
+func (m *ContractCallExecutedEvent) GetInvalidationNonce() uint64 {
+ if m != nil {
+ return m.InvalidationNonce
+ }
+ return 0
+}
+
+func (m *ContractCallExecutedEvent) GetEthereumHeight() uint64 {
+ if m != nil {
+ return m.EthereumHeight
+ }
+ return 0
+}
+
+// ERC20DeployedEvent is submitted when an ERC20 contract
+// for a Cosmos SDK coin has been deployed on Ethereum.
+type ERC20DeployedEvent struct {
+ EventNonce uint64 `protobuf:"varint,1,opt,name=event_nonce,json=eventNonce,proto3" json:"event_nonce,omitempty"`
+ CosmosDenom string `protobuf:"bytes,2,opt,name=cosmos_denom,json=cosmosDenom,proto3" json:"cosmos_denom,omitempty"`
+ TokenContract string `protobuf:"bytes,3,opt,name=token_contract,json=tokenContract,proto3" json:"token_contract,omitempty"`
+ Erc20Name string `protobuf:"bytes,4,opt,name=erc20_name,json=erc20Name,proto3" json:"erc20_name,omitempty"`
+ Erc20Symbol string `protobuf:"bytes,5,opt,name=erc20_symbol,json=erc20Symbol,proto3" json:"erc20_symbol,omitempty"`
+ Erc20Decimals uint64 `protobuf:"varint,6,opt,name=erc20_decimals,json=erc20Decimals,proto3" json:"erc20_decimals,omitempty"`
+ EthereumHeight uint64 `protobuf:"varint,7,opt,name=ethereum_height,json=ethereumHeight,proto3" json:"ethereum_height,omitempty"`
+}
+
+func (m *ERC20DeployedEvent) Reset() { *m = ERC20DeployedEvent{} }
+func (m *ERC20DeployedEvent) String() string { return proto.CompactTextString(m) }
+func (*ERC20DeployedEvent) ProtoMessage() {}
+func (*ERC20DeployedEvent) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{19}
+}
+func (m *ERC20DeployedEvent) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ERC20DeployedEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ERC20DeployedEvent.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ERC20DeployedEvent) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ERC20DeployedEvent.Merge(m, src)
+}
+func (m *ERC20DeployedEvent) XXX_Size() int {
+ return m.Size()
+}
+func (m *ERC20DeployedEvent) XXX_DiscardUnknown() {
+ xxx_messageInfo_ERC20DeployedEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ERC20DeployedEvent proto.InternalMessageInfo
+
+func (m *ERC20DeployedEvent) GetEventNonce() uint64 {
+ if m != nil {
+ return m.EventNonce
+ }
+ return 0
+}
+
+func (m *ERC20DeployedEvent) GetCosmosDenom() string {
+ if m != nil {
+ return m.CosmosDenom
+ }
+ return ""
+}
+
+func (m *ERC20DeployedEvent) GetTokenContract() string {
+ if m != nil {
+ return m.TokenContract
+ }
+ return ""
+}
+
+func (m *ERC20DeployedEvent) GetErc20Name() string {
+ if m != nil {
+ return m.Erc20Name
+ }
+ return ""
+}
+
+func (m *ERC20DeployedEvent) GetErc20Symbol() string {
+ if m != nil {
+ return m.Erc20Symbol
+ }
+ return ""
+}
+
+func (m *ERC20DeployedEvent) GetErc20Decimals() uint64 {
+ if m != nil {
+ return m.Erc20Decimals
+ }
+ return 0
+}
+
+func (m *ERC20DeployedEvent) GetEthereumHeight() uint64 {
+ if m != nil {
+ return m.EthereumHeight
+ }
+ return 0
+}
+
+// This informs the Cosmos module that a validator
+// set has been updated.
+type SignerSetTxExecutedEvent struct {
+ EventNonce uint64 `protobuf:"varint,1,opt,name=event_nonce,json=eventNonce,proto3" json:"event_nonce,omitempty"`
+ SignerSetTxNonce uint64 `protobuf:"varint,2,opt,name=signer_set_tx_nonce,json=signerSetTxNonce,proto3" json:"signer_set_tx_nonce,omitempty"`
+ EthereumHeight uint64 `protobuf:"varint,3,opt,name=ethereum_height,json=ethereumHeight,proto3" json:"ethereum_height,omitempty"`
+ Members []*EthereumSigner `protobuf:"bytes,4,rep,name=members,proto3" json:"members,omitempty"`
+}
+
+func (m *SignerSetTxExecutedEvent) Reset() { *m = SignerSetTxExecutedEvent{} }
+func (m *SignerSetTxExecutedEvent) String() string { return proto.CompactTextString(m) }
+func (*SignerSetTxExecutedEvent) ProtoMessage() {}
+func (*SignerSetTxExecutedEvent) Descriptor() ([]byte, []int) {
+ return fileDescriptor_2f8523f2f6feb451, []int{20}
+}
+func (m *SignerSetTxExecutedEvent) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SignerSetTxExecutedEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SignerSetTxExecutedEvent.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SignerSetTxExecutedEvent) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SignerSetTxExecutedEvent.Merge(m, src)
+}
+func (m *SignerSetTxExecutedEvent) XXX_Size() int {
+ return m.Size()
+}
+func (m *SignerSetTxExecutedEvent) XXX_DiscardUnknown() {
+ xxx_messageInfo_SignerSetTxExecutedEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignerSetTxExecutedEvent proto.InternalMessageInfo
+
+func (m *SignerSetTxExecutedEvent) GetEventNonce() uint64 {
+ if m != nil {
+ return m.EventNonce
+ }
+ return 0
+}
+
+func (m *SignerSetTxExecutedEvent) GetSignerSetTxNonce() uint64 {
+ if m != nil {
+ return m.SignerSetTxNonce
+ }
+ return 0
+}
+
+func (m *SignerSetTxExecutedEvent) GetEthereumHeight() uint64 {
+ if m != nil {
+ return m.EthereumHeight
+ }
+ return 0
+}
+
+func (m *SignerSetTxExecutedEvent) GetMembers() []*EthereumSigner {
+ if m != nil {
+ return m.Members
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*MsgSendToEthereum)(nil), "gravity.v1.MsgSendToEthereum")
+ proto.RegisterType((*MsgSendToEthereumResponse)(nil), "gravity.v1.MsgSendToEthereumResponse")
+ proto.RegisterType((*MsgCancelSendToEthereum)(nil), "gravity.v1.MsgCancelSendToEthereum")
+ proto.RegisterType((*MsgCancelSendToEthereumResponse)(nil), "gravity.v1.MsgCancelSendToEthereumResponse")
+ proto.RegisterType((*MsgRequestBatchTx)(nil), "gravity.v1.MsgRequestBatchTx")
+ proto.RegisterType((*MsgRequestBatchTxResponse)(nil), "gravity.v1.MsgRequestBatchTxResponse")
+ proto.RegisterType((*MsgSubmitEthereumTxConfirmation)(nil), "gravity.v1.MsgSubmitEthereumTxConfirmation")
+ proto.RegisterType((*ContractCallTxConfirmation)(nil), "gravity.v1.ContractCallTxConfirmation")
+ proto.RegisterType((*BatchTxConfirmation)(nil), "gravity.v1.BatchTxConfirmation")
+ proto.RegisterType((*SignerSetTxConfirmation)(nil), "gravity.v1.SignerSetTxConfirmation")
+ proto.RegisterType((*MsgSubmitEthereumTxConfirmationResponse)(nil), "gravity.v1.MsgSubmitEthereumTxConfirmationResponse")
+ proto.RegisterType((*MsgSubmitEthereumEvent)(nil), "gravity.v1.MsgSubmitEthereumEvent")
+ proto.RegisterType((*MsgSubmitEthereumEventResponse)(nil), "gravity.v1.MsgSubmitEthereumEventResponse")
+ proto.RegisterType((*MsgDelegateKeys)(nil), "gravity.v1.MsgDelegateKeys")
+ proto.RegisterType((*MsgDelegateKeysResponse)(nil), "gravity.v1.MsgDelegateKeysResponse")
+ proto.RegisterType((*DelegateKeysSignMsg)(nil), "gravity.v1.DelegateKeysSignMsg")
+ proto.RegisterType((*SendToCosmosEvent)(nil), "gravity.v1.SendToCosmosEvent")
+ proto.RegisterType((*BatchExecutedEvent)(nil), "gravity.v1.BatchExecutedEvent")
+ proto.RegisterType((*ContractCallExecutedEvent)(nil), "gravity.v1.ContractCallExecutedEvent")
+ proto.RegisterType((*ERC20DeployedEvent)(nil), "gravity.v1.ERC20DeployedEvent")
+ proto.RegisterType((*SignerSetTxExecutedEvent)(nil), "gravity.v1.SignerSetTxExecutedEvent")
+}
+
+func init() { proto.RegisterFile("gravity/v1/msgs.proto", fileDescriptor_2f8523f2f6feb451) }
+
+var fileDescriptor_2f8523f2f6feb451 = []byte{
+ // 1289 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4d, 0x6f, 0xdb, 0x46,
+ 0x13, 0x16, 0x25, 0xd9, 0x81, 0x47, 0xfe, 0xa4, 0xfd, 0x26, 0xb2, 0x92, 0x48, 0x8e, 0x82, 0xbc,
+ 0x71, 0x1a, 0x88, 0x8c, 0x9d, 0x00, 0x0d, 0x02, 0xb4, 0x80, 0x25, 0x3b, 0x48, 0x51, 0x38, 0x07,
+ 0xca, 0x05, 0x82, 0x5e, 0x04, 0x8a, 0x9c, 0x50, 0x4c, 0x44, 0xae, 0xca, 0x5d, 0x09, 0xd6, 0xb5,
+ 0xa7, 0xa2, 0xa7, 0xf6, 0xd0, 0x7b, 0x0e, 0x41, 0x7f, 0x41, 0xfe, 0x40, 0x6e, 0x69, 0x4e, 0x01,
+ 0x7a, 0x29, 0x7a, 0x08, 0x8a, 0xe4, 0x52, 0xf4, 0x27, 0x14, 0x28, 0x50, 0x70, 0x77, 0x29, 0x93,
+ 0x14, 0xfd, 0x05, 0xf4, 0x64, 0xee, 0xcc, 0xb3, 0xb3, 0xcf, 0xcc, 0x3e, 0x9a, 0x59, 0xc3, 0xff,
+ 0x9c, 0xc0, 0x1c, 0xb9, 0x6c, 0xac, 0x8f, 0xb6, 0x74, 0x8f, 0x3a, 0x54, 0x1b, 0x04, 0x84, 0x11,
+ 0x15, 0xa4, 0x59, 0x1b, 0x6d, 0x55, 0xaa, 0x16, 0xa1, 0x1e, 0xa1, 0x7a, 0xd7, 0xa4, 0xa8, 0x8f,
+ 0xb6, 0xba, 0xc8, 0xcc, 0x2d, 0xdd, 0x22, 0xae, 0x2f, 0xb0, 0x95, 0x75, 0xe1, 0xef, 0xf0, 0x95,
+ 0x2e, 0x16, 0xd2, 0x55, 0x8e, 0x45, 0x8f, 0x22, 0x0a, 0xcf, 0x9a, 0x43, 0x1c, 0x22, 0x76, 0x84,
+ 0x5f, 0xd2, 0x7a, 0xc5, 0x21, 0xc4, 0xe9, 0xa3, 0x6e, 0x0e, 0x5c, 0xdd, 0xf4, 0x7d, 0xc2, 0x4c,
+ 0xe6, 0x12, 0x3f, 0x8a, 0xb6, 0x2e, 0xbd, 0x7c, 0xd5, 0x1d, 0x3e, 0xd5, 0x4d, 0x5f, 0x86, 0xab,
+ 0xff, 0xaa, 0xc0, 0xca, 0x3e, 0x75, 0xda, 0xe8, 0xdb, 0x07, 0x64, 0x8f, 0xf5, 0x30, 0xc0, 0xa1,
+ 0xa7, 0x5e, 0x84, 0x59, 0x8a, 0xbe, 0x8d, 0x41, 0x59, 0xd9, 0x50, 0x36, 0xe7, 0x0c, 0xb9, 0x52,
+ 0x1b, 0xa0, 0xa2, 0xc4, 0x74, 0x02, 0xb4, 0xdc, 0x81, 0x8b, 0x3e, 0x2b, 0xe7, 0x39, 0x66, 0x25,
+ 0xf2, 0x18, 0x91, 0x43, 0xfd, 0x14, 0x66, 0x4d, 0x8f, 0x0c, 0x7d, 0x56, 0x2e, 0x6c, 0x28, 0x9b,
+ 0xa5, 0xed, 0x75, 0x4d, 0x26, 0x19, 0x56, 0x44, 0x93, 0x15, 0xd1, 0x5a, 0xc4, 0xf5, 0x9b, 0xc5,
+ 0x37, 0xef, 0x6b, 0x39, 0x43, 0xc2, 0xd5, 0xcf, 0x01, 0xba, 0x81, 0x6b, 0x3b, 0xd8, 0x79, 0x8a,
+ 0x58, 0x2e, 0x9e, 0x6d, 0xf3, 0x9c, 0xd8, 0xf2, 0x10, 0xb1, 0x7e, 0x1b, 0xd6, 0xa7, 0x92, 0x32,
+ 0x90, 0x0e, 0x88, 0x4f, 0x51, 0x5d, 0x84, 0xbc, 0x6b, 0xf3, 0xc4, 0x8a, 0x46, 0xde, 0xb5, 0xeb,
+ 0x3b, 0x70, 0x69, 0x9f, 0x3a, 0x2d, 0xd3, 0xb7, 0xb0, 0x9f, 0xaa, 0x43, 0x0a, 0x1a, 0xab, 0x4b,
+ 0x3e, 0x5e, 0x97, 0xfa, 0x35, 0xa8, 0x1d, 0x13, 0x22, 0x3a, 0xb5, 0xbe, 0xc3, 0xeb, 0x6c, 0xe0,
+ 0x37, 0x43, 0xa4, 0xac, 0x69, 0x32, 0xab, 0x77, 0x70, 0xa8, 0xae, 0xc1, 0x8c, 0x8d, 0x3e, 0xf1,
+ 0x64, 0x99, 0xc5, 0x82, 0x9f, 0xe2, 0x3a, 0x7e, 0xec, 0x14, 0xbe, 0xaa, 0x5f, 0xe6, 0x59, 0x25,
+ 0x43, 0x4c, 0xe2, 0xff, 0xa4, 0x70, 0x0e, 0xed, 0x61, 0xd7, 0x73, 0x59, 0x74, 0xfa, 0xc1, 0x61,
+ 0x8b, 0xf8, 0x4f, 0xdd, 0xc0, 0xe3, 0x72, 0x50, 0x0f, 0x60, 0xde, 0x8a, 0xad, 0xf9, 0xa9, 0xa5,
+ 0xed, 0x35, 0x4d, 0xc8, 0x43, 0x8b, 0xe4, 0xa1, 0xed, 0xf8, 0xe3, 0x66, 0xe5, 0xed, 0xab, 0xc6,
+ 0xc5, 0xec, 0x38, 0x46, 0x22, 0xca, 0x71, 0x74, 0x1f, 0x14, 0xbf, 0x7b, 0x51, 0xcb, 0xd5, 0x5f,
+ 0x2b, 0x50, 0x69, 0x11, 0x9f, 0x05, 0xa6, 0xc5, 0x5a, 0x66, 0xbf, 0x9f, 0xa2, 0xd4, 0x00, 0xd5,
+ 0xf5, 0x47, 0x66, 0xdf, 0xb5, 0xf9, 0xba, 0x43, 0x2d, 0x32, 0x40, 0x4e, 0x6c, 0xde, 0x58, 0x89,
+ 0x7b, 0xda, 0xa1, 0x63, 0x0a, 0xee, 0x13, 0xdf, 0x42, 0x7e, 0x6e, 0x31, 0x09, 0x7f, 0x1c, 0x3a,
+ 0xd4, 0x9b, 0xb0, 0x34, 0xd1, 0xab, 0xe4, 0x58, 0xe0, 0x1c, 0x17, 0x23, 0x73, 0x9b, 0x5b, 0xd5,
+ 0x2b, 0x30, 0x17, 0xfa, 0x4d, 0x36, 0x0c, 0x84, 0xde, 0xe6, 0x8d, 0x23, 0x43, 0xfd, 0xa5, 0x02,
+ 0xab, 0xb2, 0xde, 0x09, 0xf2, 0x37, 0x60, 0x91, 0x91, 0xe7, 0xe8, 0x77, 0x2c, 0x99, 0xa0, 0xbc,
+ 0xc7, 0x05, 0x6e, 0x8d, 0xb2, 0x56, 0x6b, 0x50, 0xea, 0x86, 0xbb, 0x13, 0x6c, 0x81, 0x9b, 0xfe,
+ 0x53, 0x9a, 0xdf, 0x2b, 0x70, 0x49, 0x00, 0xdb, 0xc8, 0x52, 0x54, 0x37, 0x61, 0x59, 0x44, 0xee,
+ 0x50, 0x64, 0x92, 0x88, 0xd0, 0xf5, 0x22, 0x8d, 0xb6, 0x1c, 0x4b, 0x26, 0x7f, 0x3a, 0x99, 0x42,
+ 0x9a, 0xcc, 0x2d, 0xb8, 0x79, 0x8a, 0x1c, 0x27, 0xd2, 0x1d, 0xc2, 0xc5, 0x29, 0xe8, 0xde, 0x28,
+ 0x6c, 0x20, 0x9f, 0xc1, 0x0c, 0x86, 0x1f, 0x27, 0x2a, 0x75, 0xe5, 0xed, 0xab, 0xc6, 0x42, 0x62,
+ 0x9f, 0x21, 0x76, 0x9d, 0xa2, 0xcc, 0x0d, 0xa8, 0x66, 0x1f, 0x3b, 0x21, 0xf6, 0x5a, 0x81, 0xa5,
+ 0x7d, 0xea, 0xec, 0x62, 0x1f, 0x1d, 0x93, 0xe1, 0x97, 0x38, 0xa6, 0xea, 0x6d, 0x58, 0x91, 0x2a,
+ 0x23, 0x41, 0xc7, 0xb4, 0xed, 0x00, 0x29, 0x95, 0xd7, 0xbe, 0x3c, 0x71, 0xec, 0x08, 0xbb, 0xba,
+ 0x05, 0x6b, 0x24, 0xb0, 0x7a, 0x48, 0x59, 0x90, 0xc0, 0x0b, 0x3a, 0xab, 0x71, 0x5f, 0xb4, 0xe5,
+ 0x16, 0x2c, 0x4f, 0xca, 0x1f, 0xc1, 0x85, 0x18, 0x26, 0xd7, 0x12, 0x41, 0xaf, 0xc3, 0x02, 0xb2,
+ 0x5e, 0x27, 0xad, 0x88, 0x79, 0x64, 0xbd, 0xf6, 0xe4, 0x1e, 0xd6, 0x79, 0x77, 0x8b, 0xa7, 0x30,
+ 0x49, 0xef, 0x09, 0xac, 0xc6, 0xed, 0xe1, 0x9e, 0x7d, 0xea, 0x9c, 0x2f, 0xc3, 0x35, 0x98, 0x89,
+ 0xab, 0x5a, 0x2c, 0xea, 0x2f, 0xf3, 0xb0, 0x22, 0xfa, 0x60, 0x8b, 0xf7, 0x6c, 0x71, 0x9b, 0x35,
+ 0x28, 0xf1, 0x7b, 0x49, 0xc8, 0x0f, 0xb8, 0x49, 0x48, 0x6f, 0xfa, 0xf7, 0x94, 0xcf, 0xfa, 0x3d,
+ 0x3d, 0x4c, 0x8c, 0x95, 0xb9, 0xa6, 0x16, 0xb6, 0xff, 0xdf, 0xdf, 0xd7, 0xfe, 0xef, 0xb8, 0xac,
+ 0x37, 0xec, 0x6a, 0x16, 0xf1, 0xe4, 0x34, 0x95, 0x7f, 0x1a, 0xd4, 0x7e, 0xae, 0xb3, 0xf1, 0x00,
+ 0xa9, 0xf6, 0x85, 0xcf, 0x26, 0x53, 0x26, 0xa1, 0x74, 0xd1, 0xd6, 0x8b, 0x29, 0xa5, 0x8b, 0xb1,
+ 0x77, 0x13, 0x96, 0xe4, 0xa8, 0x0e, 0xd0, 0x42, 0x77, 0x84, 0x41, 0x79, 0x46, 0x00, 0x85, 0xd9,
+ 0x90, 0xd6, 0x44, 0xc4, 0x1e, 0xba, 0x4e, 0x8f, 0x95, 0x67, 0xc5, 0x8f, 0x2c, 0x32, 0x3f, 0xe2,
+ 0xd6, 0x07, 0xc5, 0x3f, 0x5f, 0xd4, 0x94, 0xfa, 0xcf, 0x0a, 0xa8, 0xbc, 0xaf, 0xec, 0x1d, 0xa2,
+ 0x35, 0x64, 0x68, 0x8b, 0x3a, 0x9d, 0xbd, 0xad, 0xc4, 0xcb, 0x99, 0x9f, 0x2a, 0x67, 0x06, 0x9b,
+ 0x42, 0x16, 0x9b, 0x74, 0x83, 0x2a, 0xa6, 0x1b, 0x54, 0xfd, 0x1f, 0x05, 0xd6, 0xe3, 0x4d, 0x3c,
+ 0xc9, 0xf7, 0xd4, 0x7b, 0x75, 0x32, 0x9b, 0x7c, 0x48, 0x78, 0xbe, 0x79, 0xff, 0xef, 0xf7, 0xb5,
+ 0x7b, 0xb1, 0x8b, 0x63, 0xbc, 0xe4, 0x9e, 0xeb, 0xb3, 0xf8, 0x67, 0xdf, 0xed, 0x52, 0xbd, 0x3b,
+ 0x66, 0x48, 0xb5, 0x47, 0x78, 0xd8, 0x0c, 0x3f, 0xce, 0x3e, 0x1e, 0x0a, 0x67, 0x19, 0x0f, 0xb2,
+ 0x40, 0xc5, 0xac, 0x02, 0xd5, 0x7f, 0xcc, 0x83, 0xba, 0x67, 0xb4, 0xb6, 0xef, 0xec, 0xe2, 0xa0,
+ 0x4f, 0xc6, 0x67, 0x4e, 0xfc, 0x5a, 0x38, 0x70, 0xb9, 0x70, 0xc4, 0x98, 0x17, 0x72, 0x2e, 0x09,
+ 0xdb, 0x2e, 0x1f, 0xf6, 0xd3, 0x97, 0x5d, 0xc8, 0xba, 0xec, 0xab, 0x00, 0x18, 0x58, 0xdb, 0x77,
+ 0x3a, 0xbe, 0xe9, 0xa1, 0x94, 0xe9, 0x1c, 0xb7, 0x3c, 0x36, 0x3d, 0x7e, 0x90, 0x70, 0xd3, 0xb1,
+ 0xd7, 0x25, 0x7d, 0x29, 0xcf, 0x12, 0xb7, 0xb5, 0xb9, 0x29, 0x3c, 0x48, 0x40, 0x6c, 0xb4, 0x5c,
+ 0xcf, 0xec, 0x53, 0x29, 0xcd, 0x05, 0x6e, 0xdd, 0x95, 0xc6, 0xac, 0x9a, 0x5c, 0xc8, 0xac, 0xc9,
+ 0x2f, 0x0a, 0x94, 0x63, 0xd3, 0xe6, 0x9c, 0x92, 0x68, 0xc0, 0x6a, 0x6c, 0x1e, 0xb1, 0xc3, 0x84,
+ 0x88, 0x97, 0xe9, 0x51, 0xdc, 0x73, 0x4a, 0xf9, 0x1e, 0x5c, 0xf0, 0xd0, 0xeb, 0x62, 0x40, 0xcb,
+ 0xc5, 0x8d, 0xc2, 0x66, 0x69, 0xbb, 0xa2, 0x1d, 0xbd, 0xc8, 0xb5, 0xbd, 0xc4, 0x04, 0x33, 0x22,
+ 0xe8, 0xf6, 0x5f, 0x45, 0x28, 0x84, 0xad, 0xef, 0x09, 0x2c, 0xa6, 0x5e, 0x80, 0x57, 0xe3, 0xdb,
+ 0xa7, 0xde, 0x94, 0x95, 0x1b, 0x27, 0xba, 0x27, 0x9d, 0x36, 0xa7, 0x3e, 0x83, 0xb5, 0xcc, 0x17,
+ 0xe6, 0xf5, 0x54, 0x80, 0x2c, 0x50, 0xe5, 0xf6, 0x19, 0x40, 0xb1, 0xb3, 0x9e, 0xc0, 0x62, 0xea,
+ 0x9d, 0x99, 0xce, 0x22, 0xe9, 0x9e, 0xca, 0xe2, 0x98, 0x27, 0x66, 0x4e, 0xfd, 0x56, 0x81, 0x2b,
+ 0x27, 0xbe, 0x30, 0xd3, 0x4c, 0x4f, 0x02, 0x57, 0xee, 0x9e, 0x03, 0x1c, 0x23, 0xe1, 0xc0, 0x6a,
+ 0xd6, 0x5b, 0xa1, 0x7e, 0x62, 0x34, 0x8e, 0xa9, 0x7c, 0x72, 0x3a, 0x26, 0x76, 0xd0, 0x57, 0xb0,
+ 0xd4, 0x46, 0x96, 0x98, 0xfe, 0x97, 0x53, 0x01, 0xe2, 0xce, 0xca, 0xf5, 0x13, 0x9c, 0x47, 0x61,
+ 0x9b, 0xc6, 0x9b, 0x0f, 0x55, 0xe5, 0xdd, 0x87, 0xaa, 0xf2, 0xc7, 0x87, 0xaa, 0xf2, 0xc3, 0xc7,
+ 0x6a, 0xee, 0xdd, 0xc7, 0x6a, 0xee, 0xb7, 0x8f, 0xd5, 0xdc, 0xd7, 0xf7, 0x63, 0x7d, 0x70, 0x80,
+ 0x8e, 0x33, 0x7e, 0x36, 0x8a, 0xfe, 0xfb, 0x6b, 0x88, 0x7f, 0x6e, 0x74, 0x8f, 0xd8, 0xc3, 0x3e,
+ 0xea, 0x87, 0x91, 0x5d, 0x8c, 0xb5, 0xee, 0x2c, 0x7f, 0x11, 0xdd, 0xfd, 0x37, 0x00, 0x00, 0xff,
+ 0xff, 0x83, 0xc2, 0xd3, 0xe2, 0x96, 0x0e, 0x00, 0x00,
+}
+
+func (this *SendToCosmosEvent) Equal(that interface{}) bool {
+ if that == nil {
+ return this == nil
+ }
+
+ that1, ok := that.(*SendToCosmosEvent)
+ if !ok {
+ that2, ok := that.(SendToCosmosEvent)
+ if ok {
+ that1 = &that2
+ } else {
+ return false
+ }
+ }
+ if that1 == nil {
+ return this == nil
+ } else if this == nil {
+ return false
+ }
+ if this.EventNonce != that1.EventNonce {
+ return false
+ }
+ if this.TokenContract != that1.TokenContract {
+ return false
+ }
+ if !this.Amount.Equal(that1.Amount) {
+ return false
+ }
+ if this.EthereumSender != that1.EthereumSender {
+ return false
+ }
+ if this.CosmosReceiver != that1.CosmosReceiver {
+ return false
+ }
+ if this.EthereumHeight != that1.EthereumHeight {
+ return false
+ }
+ return true
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// MsgClient is the client API for Msg service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type MsgClient interface {
+ SendToEthereum(ctx context.Context, in *MsgSendToEthereum, opts ...grpc.CallOption) (*MsgSendToEthereumResponse, error)
+ CancelSendToEthereum(ctx context.Context, in *MsgCancelSendToEthereum, opts ...grpc.CallOption) (*MsgCancelSendToEthereumResponse, error)
+ RequestBatchTx(ctx context.Context, in *MsgRequestBatchTx, opts ...grpc.CallOption) (*MsgRequestBatchTxResponse, error)
+ SubmitEthereumTxConfirmation(ctx context.Context, in *MsgSubmitEthereumTxConfirmation, opts ...grpc.CallOption) (*MsgSubmitEthereumTxConfirmationResponse, error)
+ SubmitEthereumEvent(ctx context.Context, in *MsgSubmitEthereumEvent, opts ...grpc.CallOption) (*MsgSubmitEthereumEventResponse, error)
+ SetDelegateKeys(ctx context.Context, in *MsgDelegateKeys, opts ...grpc.CallOption) (*MsgDelegateKeysResponse, error)
+}
+
+type msgClient struct {
+ cc grpc1.ClientConn
+}
+
+func NewMsgClient(cc grpc1.ClientConn) MsgClient {
+ return &msgClient{cc}
+}
+
+func (c *msgClient) SendToEthereum(ctx context.Context, in *MsgSendToEthereum, opts ...grpc.CallOption) (*MsgSendToEthereumResponse, error) {
+ out := new(MsgSendToEthereumResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Msg/SendToEthereum", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *msgClient) CancelSendToEthereum(ctx context.Context, in *MsgCancelSendToEthereum, opts ...grpc.CallOption) (*MsgCancelSendToEthereumResponse, error) {
+ out := new(MsgCancelSendToEthereumResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Msg/CancelSendToEthereum", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *msgClient) RequestBatchTx(ctx context.Context, in *MsgRequestBatchTx, opts ...grpc.CallOption) (*MsgRequestBatchTxResponse, error) {
+ out := new(MsgRequestBatchTxResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Msg/RequestBatchTx", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *msgClient) SubmitEthereumTxConfirmation(ctx context.Context, in *MsgSubmitEthereumTxConfirmation, opts ...grpc.CallOption) (*MsgSubmitEthereumTxConfirmationResponse, error) {
+ out := new(MsgSubmitEthereumTxConfirmationResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Msg/SubmitEthereumTxConfirmation", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *msgClient) SubmitEthereumEvent(ctx context.Context, in *MsgSubmitEthereumEvent, opts ...grpc.CallOption) (*MsgSubmitEthereumEventResponse, error) {
+ out := new(MsgSubmitEthereumEventResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Msg/SubmitEthereumEvent", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *msgClient) SetDelegateKeys(ctx context.Context, in *MsgDelegateKeys, opts ...grpc.CallOption) (*MsgDelegateKeysResponse, error) {
+ out := new(MsgDelegateKeysResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Msg/SetDelegateKeys", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// MsgServer is the server API for Msg service.
+type MsgServer interface {
+ SendToEthereum(context.Context, *MsgSendToEthereum) (*MsgSendToEthereumResponse, error)
+ CancelSendToEthereum(context.Context, *MsgCancelSendToEthereum) (*MsgCancelSendToEthereumResponse, error)
+ RequestBatchTx(context.Context, *MsgRequestBatchTx) (*MsgRequestBatchTxResponse, error)
+ SubmitEthereumTxConfirmation(context.Context, *MsgSubmitEthereumTxConfirmation) (*MsgSubmitEthereumTxConfirmationResponse, error)
+ SubmitEthereumEvent(context.Context, *MsgSubmitEthereumEvent) (*MsgSubmitEthereumEventResponse, error)
+ SetDelegateKeys(context.Context, *MsgDelegateKeys) (*MsgDelegateKeysResponse, error)
+}
+
+// UnimplementedMsgServer can be embedded to have forward compatible implementations.
+type UnimplementedMsgServer struct {
+}
+
+func (*UnimplementedMsgServer) SendToEthereum(ctx context.Context, req *MsgSendToEthereum) (*MsgSendToEthereumResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SendToEthereum not implemented")
+}
+func (*UnimplementedMsgServer) CancelSendToEthereum(ctx context.Context, req *MsgCancelSendToEthereum) (*MsgCancelSendToEthereumResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method CancelSendToEthereum not implemented")
+}
+func (*UnimplementedMsgServer) RequestBatchTx(ctx context.Context, req *MsgRequestBatchTx) (*MsgRequestBatchTxResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method RequestBatchTx not implemented")
+}
+func (*UnimplementedMsgServer) SubmitEthereumTxConfirmation(ctx context.Context, req *MsgSubmitEthereumTxConfirmation) (*MsgSubmitEthereumTxConfirmationResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SubmitEthereumTxConfirmation not implemented")
+}
+func (*UnimplementedMsgServer) SubmitEthereumEvent(ctx context.Context, req *MsgSubmitEthereumEvent) (*MsgSubmitEthereumEventResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SubmitEthereumEvent not implemented")
+}
+func (*UnimplementedMsgServer) SetDelegateKeys(ctx context.Context, req *MsgDelegateKeys) (*MsgDelegateKeysResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SetDelegateKeys not implemented")
+}
+
+func RegisterMsgServer(s grpc1.Server, srv MsgServer) {
+ s.RegisterService(&_Msg_serviceDesc, srv)
+}
+
+func _Msg_SendToEthereum_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(MsgSendToEthereum)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(MsgServer).SendToEthereum(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Msg/SendToEthereum",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(MsgServer).SendToEthereum(ctx, req.(*MsgSendToEthereum))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Msg_CancelSendToEthereum_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(MsgCancelSendToEthereum)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(MsgServer).CancelSendToEthereum(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Msg/CancelSendToEthereum",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(MsgServer).CancelSendToEthereum(ctx, req.(*MsgCancelSendToEthereum))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Msg_RequestBatchTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(MsgRequestBatchTx)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(MsgServer).RequestBatchTx(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Msg/RequestBatchTx",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(MsgServer).RequestBatchTx(ctx, req.(*MsgRequestBatchTx))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Msg_SubmitEthereumTxConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(MsgSubmitEthereumTxConfirmation)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(MsgServer).SubmitEthereumTxConfirmation(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Msg/SubmitEthereumTxConfirmation",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(MsgServer).SubmitEthereumTxConfirmation(ctx, req.(*MsgSubmitEthereumTxConfirmation))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Msg_SubmitEthereumEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(MsgSubmitEthereumEvent)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(MsgServer).SubmitEthereumEvent(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Msg/SubmitEthereumEvent",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(MsgServer).SubmitEthereumEvent(ctx, req.(*MsgSubmitEthereumEvent))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Msg_SetDelegateKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(MsgDelegateKeys)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(MsgServer).SetDelegateKeys(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Msg/SetDelegateKeys",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(MsgServer).SetDelegateKeys(ctx, req.(*MsgDelegateKeys))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _Msg_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "gravity.v1.Msg",
+ HandlerType: (*MsgServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "SendToEthereum",
+ Handler: _Msg_SendToEthereum_Handler,
+ },
+ {
+ MethodName: "CancelSendToEthereum",
+ Handler: _Msg_CancelSendToEthereum_Handler,
+ },
+ {
+ MethodName: "RequestBatchTx",
+ Handler: _Msg_RequestBatchTx_Handler,
+ },
+ {
+ MethodName: "SubmitEthereumTxConfirmation",
+ Handler: _Msg_SubmitEthereumTxConfirmation_Handler,
+ },
+ {
+ MethodName: "SubmitEthereumEvent",
+ Handler: _Msg_SubmitEthereumEvent_Handler,
+ },
+ {
+ MethodName: "SetDelegateKeys",
+ Handler: _Msg_SetDelegateKeys_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "gravity/v1/msgs.proto",
+}
+
+func (m *MsgSendToEthereum) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgSendToEthereum) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgSendToEthereum) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ {
+ size, err := m.BridgeFee.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintMsgs(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x22
+ {
+ size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintMsgs(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
+ if len(m.EthereumRecipient) > 0 {
+ i -= len(m.EthereumRecipient)
+ copy(dAtA[i:], m.EthereumRecipient)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.EthereumRecipient)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.Sender) > 0 {
+ i -= len(m.Sender)
+ copy(dAtA[i:], m.Sender)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Sender)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgSendToEthereumResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgSendToEthereumResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgSendToEthereumResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Id != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.Id))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgCancelSendToEthereum) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgCancelSendToEthereum) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgCancelSendToEthereum) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Sender) > 0 {
+ i -= len(m.Sender)
+ copy(dAtA[i:], m.Sender)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Sender)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.Id != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.Id))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgCancelSendToEthereumResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgCancelSendToEthereumResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgCancelSendToEthereumResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgRequestBatchTx) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgRequestBatchTx) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgRequestBatchTx) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signer) > 0 {
+ i -= len(m.Signer)
+ copy(dAtA[i:], m.Signer)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.Denom) > 0 {
+ i -= len(m.Denom)
+ copy(dAtA[i:], m.Denom)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Denom)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgRequestBatchTxResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgRequestBatchTxResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgRequestBatchTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgSubmitEthereumTxConfirmation) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgSubmitEthereumTxConfirmation) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgSubmitEthereumTxConfirmation) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signer) > 0 {
+ i -= len(m.Signer)
+ copy(dAtA[i:], m.Signer)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.Confirmation != nil {
+ {
+ size, err := m.Confirmation.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintMsgs(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ContractCallTxConfirmation) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ContractCallTxConfirmation) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ContractCallTxConfirmation) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signature) > 0 {
+ i -= len(m.Signature)
+ copy(dAtA[i:], m.Signature)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signature)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.EthereumSigner) > 0 {
+ i -= len(m.EthereumSigner)
+ copy(dAtA[i:], m.EthereumSigner)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.EthereumSigner)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if m.InvalidationNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.InvalidationNonce))
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.InvalidationScope) > 0 {
+ i -= len(m.InvalidationScope)
+ copy(dAtA[i:], m.InvalidationScope)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.InvalidationScope)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTxConfirmation) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTxConfirmation) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTxConfirmation) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signature) > 0 {
+ i -= len(m.Signature)
+ copy(dAtA[i:], m.Signature)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signature)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.EthereumSigner) > 0 {
+ i -= len(m.EthereumSigner)
+ copy(dAtA[i:], m.EthereumSigner)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.EthereumSigner)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if m.BatchNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.BatchNonce))
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.TokenContract) > 0 {
+ i -= len(m.TokenContract)
+ copy(dAtA[i:], m.TokenContract)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.TokenContract)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *SignerSetTxConfirmation) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SignerSetTxConfirmation) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SignerSetTxConfirmation) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signature) > 0 {
+ i -= len(m.Signature)
+ copy(dAtA[i:], m.Signature)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signature)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if len(m.EthereumSigner) > 0 {
+ i -= len(m.EthereumSigner)
+ copy(dAtA[i:], m.EthereumSigner)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.EthereumSigner)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.SignerSetNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.SignerSetNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgSubmitEthereumTxConfirmationResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgSubmitEthereumTxConfirmationResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgSubmitEthereumTxConfirmationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgSubmitEthereumEvent) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgSubmitEthereumEvent) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgSubmitEthereumEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signer) > 0 {
+ i -= len(m.Signer)
+ copy(dAtA[i:], m.Signer)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.Event != nil {
+ {
+ size, err := m.Event.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintMsgs(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgSubmitEthereumEventResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgSubmitEthereumEventResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgSubmitEthereumEventResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgDelegateKeys) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgDelegateKeys) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgDelegateKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.EthSignature) > 0 {
+ i -= len(m.EthSignature)
+ copy(dAtA[i:], m.EthSignature)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.EthSignature)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.EthereumAddress) > 0 {
+ i -= len(m.EthereumAddress)
+ copy(dAtA[i:], m.EthereumAddress)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.EthereumAddress)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if len(m.OrchestratorAddress) > 0 {
+ i -= len(m.OrchestratorAddress)
+ copy(dAtA[i:], m.OrchestratorAddress)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.OrchestratorAddress)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.ValidatorAddress) > 0 {
+ i -= len(m.ValidatorAddress)
+ copy(dAtA[i:], m.ValidatorAddress)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.ValidatorAddress)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgDelegateKeysResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgDelegateKeysResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgDelegateKeysResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *DelegateKeysSignMsg) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DelegateKeysSignMsg) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DelegateKeysSignMsg) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Nonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.Nonce))
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.ValidatorAddress) > 0 {
+ i -= len(m.ValidatorAddress)
+ copy(dAtA[i:], m.ValidatorAddress)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.ValidatorAddress)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *SendToCosmosEvent) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SendToCosmosEvent) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SendToCosmosEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.EthereumHeight != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EthereumHeight))
+ i--
+ dAtA[i] = 0x30
+ }
+ if len(m.CosmosReceiver) > 0 {
+ i -= len(m.CosmosReceiver)
+ copy(dAtA[i:], m.CosmosReceiver)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.CosmosReceiver)))
+ i--
+ dAtA[i] = 0x2a
+ }
+ if len(m.EthereumSender) > 0 {
+ i -= len(m.EthereumSender)
+ copy(dAtA[i:], m.EthereumSender)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.EthereumSender)))
+ i--
+ dAtA[i] = 0x22
+ }
+ {
+ size := m.Amount.Size()
+ i -= size
+ if _, err := m.Amount.MarshalTo(dAtA[i:]); err != nil {
+ return 0, err
+ }
+ i = encodeVarintMsgs(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
+ if len(m.TokenContract) > 0 {
+ i -= len(m.TokenContract)
+ copy(dAtA[i:], m.TokenContract)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.TokenContract)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.EventNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EventNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchExecutedEvent) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchExecutedEvent) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchExecutedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.BatchNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.BatchNonce))
+ i--
+ dAtA[i] = 0x20
+ }
+ if m.EthereumHeight != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EthereumHeight))
+ i--
+ dAtA[i] = 0x18
+ }
+ if m.EventNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EventNonce))
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.TokenContract) > 0 {
+ i -= len(m.TokenContract)
+ copy(dAtA[i:], m.TokenContract)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.TokenContract)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ContractCallExecutedEvent) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ContractCallExecutedEvent) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ContractCallExecutedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.EthereumHeight != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EthereumHeight))
+ i--
+ dAtA[i] = 0x20
+ }
+ if m.InvalidationNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.InvalidationNonce))
+ i--
+ dAtA[i] = 0x18
+ }
+ if len(m.InvalidationScope) > 0 {
+ i -= len(m.InvalidationScope)
+ copy(dAtA[i:], m.InvalidationScope)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.InvalidationScope)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.EventNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EventNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ERC20DeployedEvent) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ERC20DeployedEvent) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ERC20DeployedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.EthereumHeight != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EthereumHeight))
+ i--
+ dAtA[i] = 0x38
+ }
+ if m.Erc20Decimals != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.Erc20Decimals))
+ i--
+ dAtA[i] = 0x30
+ }
+ if len(m.Erc20Symbol) > 0 {
+ i -= len(m.Erc20Symbol)
+ copy(dAtA[i:], m.Erc20Symbol)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Erc20Symbol)))
+ i--
+ dAtA[i] = 0x2a
+ }
+ if len(m.Erc20Name) > 0 {
+ i -= len(m.Erc20Name)
+ copy(dAtA[i:], m.Erc20Name)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.Erc20Name)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.TokenContract) > 0 {
+ i -= len(m.TokenContract)
+ copy(dAtA[i:], m.TokenContract)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.TokenContract)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if len(m.CosmosDenom) > 0 {
+ i -= len(m.CosmosDenom)
+ copy(dAtA[i:], m.CosmosDenom)
+ i = encodeVarintMsgs(dAtA, i, uint64(len(m.CosmosDenom)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.EventNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EventNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *SignerSetTxExecutedEvent) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SignerSetTxExecutedEvent) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SignerSetTxExecutedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Members) > 0 {
+ for iNdEx := len(m.Members) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Members[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintMsgs(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x22
+ }
+ }
+ if m.EthereumHeight != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EthereumHeight))
+ i--
+ dAtA[i] = 0x18
+ }
+ if m.SignerSetTxNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.SignerSetTxNonce))
+ i--
+ dAtA[i] = 0x10
+ }
+ if m.EventNonce != 0 {
+ i = encodeVarintMsgs(dAtA, i, uint64(m.EventNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func encodeVarintMsgs(dAtA []byte, offset int, v uint64) int {
+ offset -= sovMsgs(v)
+ base := offset
+ for v >= 1<<7 {
+ dAtA[offset] = uint8(v&0x7f | 0x80)
+ v >>= 7
+ offset++
+ }
+ dAtA[offset] = uint8(v)
+ return base
+}
+func (m *MsgSendToEthereum) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Sender)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.EthereumRecipient)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = m.Amount.Size()
+ n += 1 + l + sovMsgs(uint64(l))
+ l = m.BridgeFee.Size()
+ n += 1 + l + sovMsgs(uint64(l))
+ return n
+}
+
+func (m *MsgSendToEthereumResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Id != 0 {
+ n += 1 + sovMsgs(uint64(m.Id))
+ }
+ return n
+}
+
+func (m *MsgCancelSendToEthereum) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Id != 0 {
+ n += 1 + sovMsgs(uint64(m.Id))
+ }
+ l = len(m.Sender)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ return n
+}
+
+func (m *MsgCancelSendToEthereumResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *MsgRequestBatchTx) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Denom)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.Signer)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ return n
+}
+
+func (m *MsgRequestBatchTxResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *MsgSubmitEthereumTxConfirmation) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Confirmation != nil {
+ l = m.Confirmation.Size()
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.Signer)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ return n
+}
+
+func (m *ContractCallTxConfirmation) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.InvalidationScope)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ if m.InvalidationNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.InvalidationNonce))
+ }
+ l = len(m.EthereumSigner)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.Signature)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ return n
+}
+
+func (m *BatchTxConfirmation) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.TokenContract)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ if m.BatchNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.BatchNonce))
+ }
+ l = len(m.EthereumSigner)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.Signature)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ return n
+}
+
+func (m *SignerSetTxConfirmation) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.SignerSetNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.SignerSetNonce))
+ }
+ l = len(m.EthereumSigner)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.Signature)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ return n
+}
+
+func (m *MsgSubmitEthereumTxConfirmationResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *MsgSubmitEthereumEvent) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Event != nil {
+ l = m.Event.Size()
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.Signer)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ return n
+}
+
+func (m *MsgSubmitEthereumEventResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *MsgDelegateKeys) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.ValidatorAddress)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.OrchestratorAddress)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.EthereumAddress)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.EthSignature)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ return n
+}
+
+func (m *MsgDelegateKeysResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *DelegateKeysSignMsg) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.ValidatorAddress)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ if m.Nonce != 0 {
+ n += 1 + sovMsgs(uint64(m.Nonce))
+ }
+ return n
+}
+
+func (m *SendToCosmosEvent) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.EventNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.EventNonce))
+ }
+ l = len(m.TokenContract)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = m.Amount.Size()
+ n += 1 + l + sovMsgs(uint64(l))
+ l = len(m.EthereumSender)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.CosmosReceiver)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ if m.EthereumHeight != 0 {
+ n += 1 + sovMsgs(uint64(m.EthereumHeight))
+ }
+ return n
+}
+
+func (m *BatchExecutedEvent) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.TokenContract)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ if m.EventNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.EventNonce))
+ }
+ if m.EthereumHeight != 0 {
+ n += 1 + sovMsgs(uint64(m.EthereumHeight))
+ }
+ if m.BatchNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.BatchNonce))
+ }
+ return n
+}
+
+func (m *ContractCallExecutedEvent) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.EventNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.EventNonce))
+ }
+ l = len(m.InvalidationScope)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ if m.InvalidationNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.InvalidationNonce))
+ }
+ if m.EthereumHeight != 0 {
+ n += 1 + sovMsgs(uint64(m.EthereumHeight))
+ }
+ return n
+}
+
+func (m *ERC20DeployedEvent) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.EventNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.EventNonce))
+ }
+ l = len(m.CosmosDenom)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.TokenContract)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.Erc20Name)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ l = len(m.Erc20Symbol)
+ if l > 0 {
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ if m.Erc20Decimals != 0 {
+ n += 1 + sovMsgs(uint64(m.Erc20Decimals))
+ }
+ if m.EthereumHeight != 0 {
+ n += 1 + sovMsgs(uint64(m.EthereumHeight))
+ }
+ return n
+}
+
+func (m *SignerSetTxExecutedEvent) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.EventNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.EventNonce))
+ }
+ if m.SignerSetTxNonce != 0 {
+ n += 1 + sovMsgs(uint64(m.SignerSetTxNonce))
+ }
+ if m.EthereumHeight != 0 {
+ n += 1 + sovMsgs(uint64(m.EthereumHeight))
+ }
+ if len(m.Members) > 0 {
+ for _, e := range m.Members {
+ l = e.Size()
+ n += 1 + l + sovMsgs(uint64(l))
+ }
+ }
+ return n
+}
+
+func sovMsgs(x uint64) (n int) {
+ return (math_bits.Len64(x|1) + 6) / 7
+}
+func sozMsgs(x uint64) (n int) {
+ return sovMsgs(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *MsgSendToEthereum) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgSendToEthereum: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgSendToEthereum: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Sender = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumRecipient", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumRecipient = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BridgeFee", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.BridgeFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgSendToEthereumResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgSendToEthereumResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgSendToEthereumResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType)
+ }
+ m.Id = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Id |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgCancelSendToEthereum) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgCancelSendToEthereum: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgCancelSendToEthereum: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType)
+ }
+ m.Id = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Id |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Sender = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgCancelSendToEthereumResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgCancelSendToEthereumResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgCancelSendToEthereumResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgRequestBatchTx) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgRequestBatchTx: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgRequestBatchTx: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Denom = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signer = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgRequestBatchTxResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgRequestBatchTxResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgRequestBatchTxResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgSubmitEthereumTxConfirmation) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgSubmitEthereumTxConfirmation: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgSubmitEthereumTxConfirmation: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Confirmation", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Confirmation == nil {
+ m.Confirmation = &types1.Any{}
+ }
+ if err := m.Confirmation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signer = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ContractCallTxConfirmation) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ContractCallTxConfirmation: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ContractCallTxConfirmation: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationScope", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.InvalidationScope = append(m.InvalidationScope[:0], dAtA[iNdEx:postIndex]...)
+ if m.InvalidationScope == nil {
+ m.InvalidationScope = []byte{}
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationNonce", wireType)
+ }
+ m.InvalidationNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.InvalidationNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumSigner", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumSigner = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...)
+ if m.Signature == nil {
+ m.Signature = []byte{}
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTxConfirmation) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTxConfirmation: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTxConfirmation: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field TokenContract", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.TokenContract = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BatchNonce", wireType)
+ }
+ m.BatchNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.BatchNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumSigner", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumSigner = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...)
+ if m.Signature == nil {
+ m.Signature = []byte{}
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SignerSetTxConfirmation) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SignerSetTxConfirmation: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SignerSetTxConfirmation: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SignerSetNonce", wireType)
+ }
+ m.SignerSetNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.SignerSetNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumSigner", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumSigner = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...)
+ if m.Signature == nil {
+ m.Signature = []byte{}
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgSubmitEthereumTxConfirmationResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgSubmitEthereumTxConfirmationResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgSubmitEthereumTxConfirmationResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgSubmitEthereumEvent) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgSubmitEthereumEvent: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgSubmitEthereumEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Event == nil {
+ m.Event = &types1.Any{}
+ }
+ if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signer = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgSubmitEthereumEventResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgSubmitEthereumEventResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgSubmitEthereumEventResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgDelegateKeys) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgDelegateKeys: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgDelegateKeys: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ValidatorAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field OrchestratorAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.OrchestratorAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthSignature", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthSignature = append(m.EthSignature[:0], dAtA[iNdEx:postIndex]...)
+ if m.EthSignature == nil {
+ m.EthSignature = []byte{}
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgDelegateKeysResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgDelegateKeysResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgDelegateKeysResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DelegateKeysSignMsg) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DelegateKeysSignMsg: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DelegateKeysSignMsg: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ValidatorAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Nonce", wireType)
+ }
+ m.Nonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Nonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SendToCosmosEvent) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SendToCosmosEvent: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SendToCosmosEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EventNonce", wireType)
+ }
+ m.EventNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EventNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field TokenContract", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.TokenContract = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumSender", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumSender = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 5:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CosmosReceiver", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.CosmosReceiver = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 6:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumHeight", wireType)
+ }
+ m.EthereumHeight = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EthereumHeight |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchExecutedEvent) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchExecutedEvent: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchExecutedEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field TokenContract", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.TokenContract = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EventNonce", wireType)
+ }
+ m.EventNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EventNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 3:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumHeight", wireType)
+ }
+ m.EthereumHeight = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EthereumHeight |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 4:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BatchNonce", wireType)
+ }
+ m.BatchNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.BatchNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ContractCallExecutedEvent) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ContractCallExecutedEvent: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ContractCallExecutedEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EventNonce", wireType)
+ }
+ m.EventNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EventNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationScope", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.InvalidationScope = append(m.InvalidationScope[:0], dAtA[iNdEx:postIndex]...)
+ if m.InvalidationScope == nil {
+ m.InvalidationScope = []byte{}
+ }
+ iNdEx = postIndex
+ case 3:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationNonce", wireType)
+ }
+ m.InvalidationNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.InvalidationNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 4:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumHeight", wireType)
+ }
+ m.EthereumHeight = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EthereumHeight |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ERC20DeployedEvent) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ERC20DeployedEvent: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ERC20DeployedEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EventNonce", wireType)
+ }
+ m.EventNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EventNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CosmosDenom", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.CosmosDenom = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field TokenContract", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.TokenContract = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20Name", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Erc20Name = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 5:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20Symbol", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Erc20Symbol = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 6:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20Decimals", wireType)
+ }
+ m.Erc20Decimals = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Erc20Decimals |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 7:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumHeight", wireType)
+ }
+ m.EthereumHeight = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EthereumHeight |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SignerSetTxExecutedEvent) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SignerSetTxExecutedEvent: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SignerSetTxExecutedEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EventNonce", wireType)
+ }
+ m.EventNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EventNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SignerSetTxNonce", wireType)
+ }
+ m.SignerSetTxNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.SignerSetTxNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 3:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumHeight", wireType)
+ }
+ m.EthereumHeight = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EthereumHeight |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Members", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Members = append(m.Members, &EthereumSigner{})
+ if err := m.Members[len(m.Members)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipMsgs(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthMsgs
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func skipMsgs(dAtA []byte) (n int, err error) {
+ l := len(dAtA)
+ iNdEx := 0
+ depth := 0
+ for iNdEx < l {
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ wireType := int(wire & 0x7)
+ switch wireType {
+ case 0:
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ iNdEx++
+ if dAtA[iNdEx-1] < 0x80 {
+ break
+ }
+ }
+ case 1:
+ iNdEx += 8
+ case 2:
+ var length int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowMsgs
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ length |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if length < 0 {
+ return 0, ErrInvalidLengthMsgs
+ }
+ iNdEx += length
+ case 3:
+ depth++
+ case 4:
+ if depth == 0 {
+ return 0, ErrUnexpectedEndOfGroupMsgs
+ }
+ depth--
+ case 5:
+ iNdEx += 4
+ default:
+ return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+ }
+ if iNdEx < 0 {
+ return 0, ErrInvalidLengthMsgs
+ }
+ if depth == 0 {
+ return iNdEx, nil
+ }
+ }
+ return 0, io.ErrUnexpectedEOF
+}
+
+var (
+ ErrInvalidLengthMsgs = fmt.Errorf("proto: negative length found during unmarshaling")
+ ErrIntOverflowMsgs = fmt.Errorf("proto: integer overflow")
+ ErrUnexpectedEndOfGroupMsgs = fmt.Errorf("proto: unexpected end of group")
+)
diff --git a/module/x/gravity/types/msgs_test.go b/module/x/gravity/types/msgs_test.go
new file mode 100644
index 0000000..f2b70dc
--- /dev/null
+++ b/module/x/gravity/types/msgs_test.go
@@ -0,0 +1,80 @@
+package types_test
+
+import (
+ "bytes"
+ "testing"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/stretchr/testify/assert"
+
+ "github.com/cosmos/gravity-bridge/module/app"
+ "github.com/cosmos/gravity-bridge/module/x/gravity/types"
+)
+
+func TestValidateMsgDelegateKeys(t *testing.T) {
+ app.SetAddressConfig()
+
+ var (
+ ethAddress = "0xb462864E395d88d6bc7C5dd5F3F5eb4cc2599255"
+ cosmosAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, app.MaxAddrLen)
+ valAddress sdk.ValAddress = bytes.Repeat([]byte{0x1}, app.MaxAddrLen)
+ )
+ specs := map[string]struct {
+ srcCosmosAddr sdk.AccAddress
+ srcValAddr sdk.ValAddress
+ srcETHAddr string
+ expErr bool
+ }{
+ "all good": {
+ srcCosmosAddr: cosmosAddress,
+ srcValAddr: valAddress,
+ srcETHAddr: ethAddress,
+ },
+ "empty validator address": {
+ srcETHAddr: ethAddress,
+ srcCosmosAddr: cosmosAddress,
+ expErr: true,
+ },
+ "invalid validator address": {
+ srcValAddr: []byte{0x1},
+ srcCosmosAddr: cosmosAddress,
+ srcETHAddr: ethAddress,
+ expErr: true,
+ },
+ "empty cosmos address": {
+ srcValAddr: valAddress,
+ srcETHAddr: ethAddress,
+ expErr: true,
+ },
+ "invalid cosmos address": {
+ srcCosmosAddr: []byte{0x1},
+ srcValAddr: valAddress,
+ srcETHAddr: ethAddress,
+ expErr: true,
+ },
+ "empty eth address": {
+ srcValAddr: valAddress,
+ srcCosmosAddr: cosmosAddress,
+ expErr: true,
+ },
+ "invalid eth address": {
+ srcValAddr: valAddress,
+ srcCosmosAddr: cosmosAddress,
+ srcETHAddr: "invalid",
+ expErr: true,
+ },
+ }
+ for msg, spec := range specs {
+ t.Run(msg, func(t *testing.T) {
+ msg := types.NewMsgDelegateKeys(spec.srcValAddr, spec.srcCosmosAddr, spec.srcETHAddr, []byte{0x1})
+ err := msg.ValidateBasic()
+ if spec.expErr {
+ assert.Error(t, err)
+ return
+ }
+
+ assert.NoError(t, err)
+ })
+ }
+
+}
diff --git a/module/x/gravity/types/outgoing_tx.go b/module/x/gravity/types/outgoing_tx.go
new file mode 100644
index 0000000..c4d4fa6
--- /dev/null
+++ b/module/x/gravity/types/outgoing_tx.go
@@ -0,0 +1,208 @@
+package types
+
+import (
+ "math/big"
+ "strings"
+
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ gethcommon "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+var (
+ _ OutgoingTx = &SignerSetTx{}
+ _ OutgoingTx = &BatchTx{}
+ _ OutgoingTx = &ContractCallTx{}
+)
+
+const (
+ _ = iota
+ SignerSetTxPrefixByte
+ BatchTxPrefixByte
+ ContractCallTxPrefixByte
+)
+
+///////////////////
+// GetStoreIndex //
+///////////////////
+
+// TODO: do we need a prefix byte for the different types?
+func (sstx *SignerSetTx) GetStoreIndex() []byte {
+ return MakeSignerSetTxKey(sstx.Nonce)
+}
+
+func (btx *BatchTx) GetStoreIndex() []byte {
+ return MakeBatchTxKey(gethcommon.HexToAddress(btx.TokenContract), btx.BatchNonce)
+}
+
+func (cctx *ContractCallTx) GetStoreIndex() []byte {
+ return MakeContractCallTxKey(cctx.InvalidationScope.Bytes(), cctx.InvalidationNonce)
+}
+
+///////////////////
+// GetCheckpoint //
+///////////////////
+
+func (sstx *SignerSetTx) GetCosmosHeight() uint64 {
+ return sstx.Height
+}
+
+func (btx *BatchTx) GetCosmosHeight() uint64 {
+ return btx.Height
+}
+
+func (cctx *ContractCallTx) GetCosmosHeight() uint64 {
+ return cctx.Height
+}
+
+///////////////////
+// GetCheckpoint //
+///////////////////
+
+// GetCheckpoint returns the checkpoint
+func (u SignerSetTx) GetCheckpoint(gravityID []byte) []byte {
+
+ // the contract argument is not a arbitrary length array but a fixed length 32 byte
+ // array, therefore we have to utf8 encode the string (the default in this case) and
+ // then copy the variable length encoded data into a fixed length array. This function
+ // will panic if gravityId is too long to fit in 32 bytes
+ gravityIDFixed, err := byteArrayToFixByteArray(gravityID)
+ if err != nil {
+ panic(err)
+ }
+
+ checkpointBytes := []uint8("checkpoint")
+ var checkpoint [32]uint8
+ copy(checkpoint[:], checkpointBytes[:])
+
+ memberAddresses := make([]gethcommon.Address, len(u.Signers))
+ convertedPowers := make([]*big.Int, len(u.Signers))
+ for i, m := range u.Signers {
+ memberAddresses[i] = gethcommon.HexToAddress(m.EthereumAddress)
+ convertedPowers[i] = big.NewInt(int64(m.Power))
+ }
+ // the word 'checkpoint' needs to be the same as the 'name' above in the checkpointAbiJson
+ // but other than that it's a constant that has no impact on the output. This is because
+ // it gets encoded as a function name which we must then discard.
+ args := []interface{}{
+ gravityIDFixed,
+ checkpoint,
+ big.NewInt(int64(u.Nonce)),
+ memberAddresses,
+ convertedPowers,
+ }
+
+ return packCall(SignerSetTxCheckpointABIJSON, "checkpoint", args)
+}
+
+// GetCheckpoint gets the checkpoint signature from the given outgoing tx batch
+func (b BatchTx) GetCheckpoint(gravityID []byte) []byte {
+
+ // the contract argument is not a arbitrary length array but a fixed length 32 byte
+ // array, therefore we have to utf8 encode the string (the default in this case) and
+ // then copy the variable length encoded data into a fixed length array. This function
+ // will panic if gravityId is too long to fit in 32 bytes
+ gravityIDFixed, err := byteArrayToFixByteArray(gravityID)
+ if err != nil {
+ panic(err)
+ }
+
+ // Create the methodName argument which salts the signature
+ methodNameBytes := []uint8("transactionBatch")
+ var batchMethodName [32]uint8
+ copy(batchMethodName[:], methodNameBytes[:])
+
+ // Run through the elements of the batch and serialize them
+ txAmounts := make([]*big.Int, len(b.Transactions))
+ txDestinations := make([]gethcommon.Address, len(b.Transactions))
+ txFees := make([]*big.Int, len(b.Transactions))
+ for i, tx := range b.Transactions {
+ txAmounts[i] = tx.Erc20Token.Amount.BigInt()
+ txDestinations[i] = gethcommon.HexToAddress(tx.EthereumRecipient)
+ txFees[i] = tx.Erc20Fee.Amount.BigInt()
+ }
+
+ // the methodName needs to be the same as the 'name' above in the checkpointAbiJson
+ // but other than that it's a constant that has no impact on the output. This is because
+ // it gets encoded as a function name which we must then discard.
+ args := []interface{}{
+ gravityIDFixed,
+ batchMethodName,
+ txAmounts,
+ txDestinations,
+ txFees,
+ big.NewInt(int64(b.BatchNonce)),
+ gethcommon.HexToAddress(b.TokenContract),
+ big.NewInt(int64(b.Timeout)),
+ }
+
+ return packCall(BatchTxCheckpointABIJSON, "submitBatch", args)
+}
+
+// GetCheckpoint gets the checkpoint signature from the given outgoing tx batch
+func (c ContractCallTx) GetCheckpoint(gravityID []byte) []byte {
+
+ // Create the methodName argument which salts the signature
+ methodNameBytes := []uint8("logicCall")
+ var logicCallMethodName [32]uint8
+ copy(logicCallMethodName[:], methodNameBytes[:])
+
+ // the contract argument is not a arbitrary length array but a fixed length 32 byte
+ // array, therefore we have to utf8 encode the string (the default in this case) and
+ // then copy the variable length encoded data into a fixed length array. This function
+ // will panic if gravityId is too long to fit in 32 bytes
+ gravityIDFixed, err := byteArrayToFixByteArray(gravityID)
+ if err != nil {
+ panic(err)
+ }
+
+ // Run through the elements of the logic call and serialize them
+ transferAmounts := make([]*big.Int, len(c.Tokens))
+ transferTokenContracts := make([]gethcommon.Address, len(c.Tokens))
+ feeAmounts := make([]*big.Int, len(c.Fees))
+ feeTokenContracts := make([]gethcommon.Address, len(c.Fees))
+ for i, coin := range c.Tokens {
+ transferAmounts[i] = coin.Amount.BigInt()
+ transferTokenContracts[i] = gethcommon.HexToAddress(coin.Contract)
+ }
+ for i, coin := range c.Fees {
+ feeAmounts[i] = coin.Amount.BigInt()
+ feeTokenContracts[i] = gethcommon.HexToAddress(coin.Contract)
+ }
+ payload := make([]byte, len(c.Payload))
+ copy(payload, c.Payload)
+ var invalidationId [32]byte
+ copy(invalidationId[:], c.InvalidationScope[:])
+
+ // the methodName needs to be the same as the 'name' above in the checkpointAbiJson
+ // but other than that it's a constant that has no impact on the output. This is because
+ // it gets encoded as a function name which we must then discard.
+ args := []interface{}{
+ gravityIDFixed,
+ logicCallMethodName,
+ transferAmounts,
+ transferTokenContracts,
+ feeAmounts,
+ feeTokenContracts,
+ gethcommon.HexToAddress(c.Address),
+ payload,
+ big.NewInt(int64(c.Timeout)),
+ invalidationId,
+ big.NewInt(int64(c.InvalidationNonce)),
+ }
+
+ return packCall(ContractCallTxABIJSON, "checkpoint", args)
+}
+
+func packCall(abiString, method string, args []interface{}) []byte {
+ encodedCall, err := abi.JSON(strings.NewReader(abiString))
+ if err != nil {
+ panic(sdkerrors.Wrap(err, "bad ABI definition in code"))
+ }
+ abiEncodedCall, err := encodedCall.Pack(method, args...)
+ if err != nil {
+ panic(sdkerrors.Wrap(err, "packing checkpoint"))
+ }
+ return crypto.Keccak256Hash(abiEncodedCall[4:]).Bytes()
+}
diff --git a/module/x/gravity/types/query.pb.go b/module/x/gravity/types/query.pb.go
new file mode 100644
index 0000000..c65e3f6
--- /dev/null
+++ b/module/x/gravity/types/query.pb.go
@@ -0,0 +1,10486 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: gravity/v1/query.proto
+
+package types
+
+import (
+ context "context"
+ fmt "fmt"
+ github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
+ types "github.com/cosmos/cosmos-sdk/types"
+ query "github.com/cosmos/cosmos-sdk/types/query"
+ _ "github.com/gogo/protobuf/gogoproto"
+ grpc1 "github.com/gogo/protobuf/grpc"
+ proto "github.com/gogo/protobuf/proto"
+ _ "google.golang.org/genproto/googleapis/api/annotations"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+ io "io"
+ math "math"
+ math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// rpc Params
+type ParamsRequest struct {
+}
+
+func (m *ParamsRequest) Reset() { *m = ParamsRequest{} }
+func (m *ParamsRequest) String() string { return proto.CompactTextString(m) }
+func (*ParamsRequest) ProtoMessage() {}
+func (*ParamsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{0}
+}
+func (m *ParamsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ParamsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ParamsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ParamsRequest.Merge(m, src)
+}
+func (m *ParamsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *ParamsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_ParamsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ParamsRequest proto.InternalMessageInfo
+
+type ParamsResponse struct {
+ Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
+}
+
+func (m *ParamsResponse) Reset() { *m = ParamsResponse{} }
+func (m *ParamsResponse) String() string { return proto.CompactTextString(m) }
+func (*ParamsResponse) ProtoMessage() {}
+func (*ParamsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{1}
+}
+func (m *ParamsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ParamsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ParamsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ParamsResponse.Merge(m, src)
+}
+func (m *ParamsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *ParamsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_ParamsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ParamsResponse proto.InternalMessageInfo
+
+func (m *ParamsResponse) GetParams() Params {
+ if m != nil {
+ return m.Params
+ }
+ return Params{}
+}
+
+// rpc SignerSetTx
+type SignerSetTxRequest struct {
+ SignerSetNonce uint64 `protobuf:"varint,1,opt,name=signer_set_nonce,json=signerSetNonce,proto3" json:"signer_set_nonce,omitempty"`
+}
+
+func (m *SignerSetTxRequest) Reset() { *m = SignerSetTxRequest{} }
+func (m *SignerSetTxRequest) String() string { return proto.CompactTextString(m) }
+func (*SignerSetTxRequest) ProtoMessage() {}
+func (*SignerSetTxRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{2}
+}
+func (m *SignerSetTxRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SignerSetTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SignerSetTxRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SignerSetTxRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SignerSetTxRequest.Merge(m, src)
+}
+func (m *SignerSetTxRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *SignerSetTxRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_SignerSetTxRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignerSetTxRequest proto.InternalMessageInfo
+
+func (m *SignerSetTxRequest) GetSignerSetNonce() uint64 {
+ if m != nil {
+ return m.SignerSetNonce
+ }
+ return 0
+}
+
+type LatestSignerSetTxRequest struct {
+}
+
+func (m *LatestSignerSetTxRequest) Reset() { *m = LatestSignerSetTxRequest{} }
+func (m *LatestSignerSetTxRequest) String() string { return proto.CompactTextString(m) }
+func (*LatestSignerSetTxRequest) ProtoMessage() {}
+func (*LatestSignerSetTxRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{3}
+}
+func (m *LatestSignerSetTxRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *LatestSignerSetTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_LatestSignerSetTxRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *LatestSignerSetTxRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LatestSignerSetTxRequest.Merge(m, src)
+}
+func (m *LatestSignerSetTxRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *LatestSignerSetTxRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_LatestSignerSetTxRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LatestSignerSetTxRequest proto.InternalMessageInfo
+
+type SignerSetTxResponse struct {
+ SignerSet *SignerSetTx `protobuf:"bytes,1,opt,name=signer_set,json=signerSet,proto3" json:"signer_set,omitempty"`
+}
+
+func (m *SignerSetTxResponse) Reset() { *m = SignerSetTxResponse{} }
+func (m *SignerSetTxResponse) String() string { return proto.CompactTextString(m) }
+func (*SignerSetTxResponse) ProtoMessage() {}
+func (*SignerSetTxResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{4}
+}
+func (m *SignerSetTxResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SignerSetTxResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SignerSetTxResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SignerSetTxResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SignerSetTxResponse.Merge(m, src)
+}
+func (m *SignerSetTxResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *SignerSetTxResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_SignerSetTxResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignerSetTxResponse proto.InternalMessageInfo
+
+func (m *SignerSetTxResponse) GetSignerSet() *SignerSetTx {
+ if m != nil {
+ return m.SignerSet
+ }
+ return nil
+}
+
+// rpc BatchTx
+type BatchTxRequest struct {
+ TokenContract string `protobuf:"bytes,1,opt,name=token_contract,json=tokenContract,proto3" json:"token_contract,omitempty"`
+ BatchNonce uint64 `protobuf:"varint,2,opt,name=batch_nonce,json=batchNonce,proto3" json:"batch_nonce,omitempty"`
+}
+
+func (m *BatchTxRequest) Reset() { *m = BatchTxRequest{} }
+func (m *BatchTxRequest) String() string { return proto.CompactTextString(m) }
+func (*BatchTxRequest) ProtoMessage() {}
+func (*BatchTxRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{5}
+}
+func (m *BatchTxRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTxRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTxRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTxRequest.Merge(m, src)
+}
+func (m *BatchTxRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTxRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTxRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTxRequest proto.InternalMessageInfo
+
+func (m *BatchTxRequest) GetTokenContract() string {
+ if m != nil {
+ return m.TokenContract
+ }
+ return ""
+}
+
+func (m *BatchTxRequest) GetBatchNonce() uint64 {
+ if m != nil {
+ return m.BatchNonce
+ }
+ return 0
+}
+
+type BatchTxResponse struct {
+ Batch *BatchTx `protobuf:"bytes,1,opt,name=batch,proto3" json:"batch,omitempty"`
+}
+
+func (m *BatchTxResponse) Reset() { *m = BatchTxResponse{} }
+func (m *BatchTxResponse) String() string { return proto.CompactTextString(m) }
+func (*BatchTxResponse) ProtoMessage() {}
+func (*BatchTxResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{6}
+}
+func (m *BatchTxResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTxResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTxResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTxResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTxResponse.Merge(m, src)
+}
+func (m *BatchTxResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTxResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTxResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTxResponse proto.InternalMessageInfo
+
+func (m *BatchTxResponse) GetBatch() *BatchTx {
+ if m != nil {
+ return m.Batch
+ }
+ return nil
+}
+
+// rpc ContractCallTx
+type ContractCallTxRequest struct {
+ InvalidationScope []byte `protobuf:"bytes,1,opt,name=invalidation_scope,json=invalidationScope,proto3" json:"invalidation_scope,omitempty"`
+ InvalidationNonce uint64 `protobuf:"varint,2,opt,name=invalidation_nonce,json=invalidationNonce,proto3" json:"invalidation_nonce,omitempty"`
+}
+
+func (m *ContractCallTxRequest) Reset() { *m = ContractCallTxRequest{} }
+func (m *ContractCallTxRequest) String() string { return proto.CompactTextString(m) }
+func (*ContractCallTxRequest) ProtoMessage() {}
+func (*ContractCallTxRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{7}
+}
+func (m *ContractCallTxRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ContractCallTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ContractCallTxRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ContractCallTxRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ContractCallTxRequest.Merge(m, src)
+}
+func (m *ContractCallTxRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *ContractCallTxRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_ContractCallTxRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ContractCallTxRequest proto.InternalMessageInfo
+
+func (m *ContractCallTxRequest) GetInvalidationScope() []byte {
+ if m != nil {
+ return m.InvalidationScope
+ }
+ return nil
+}
+
+func (m *ContractCallTxRequest) GetInvalidationNonce() uint64 {
+ if m != nil {
+ return m.InvalidationNonce
+ }
+ return 0
+}
+
+type ContractCallTxResponse struct {
+ LogicCall *ContractCallTx `protobuf:"bytes,1,opt,name=logic_call,json=logicCall,proto3" json:"logic_call,omitempty"`
+}
+
+func (m *ContractCallTxResponse) Reset() { *m = ContractCallTxResponse{} }
+func (m *ContractCallTxResponse) String() string { return proto.CompactTextString(m) }
+func (*ContractCallTxResponse) ProtoMessage() {}
+func (*ContractCallTxResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{8}
+}
+func (m *ContractCallTxResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ContractCallTxResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ContractCallTxResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ContractCallTxResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ContractCallTxResponse.Merge(m, src)
+}
+func (m *ContractCallTxResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *ContractCallTxResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_ContractCallTxResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ContractCallTxResponse proto.InternalMessageInfo
+
+func (m *ContractCallTxResponse) GetLogicCall() *ContractCallTx {
+ if m != nil {
+ return m.LogicCall
+ }
+ return nil
+}
+
+// rpc SignerSetTxConfirmations
+type SignerSetTxConfirmationsRequest struct {
+ SignerSetNonce uint64 `protobuf:"varint,1,opt,name=signer_set_nonce,json=signerSetNonce,proto3" json:"signer_set_nonce,omitempty"`
+}
+
+func (m *SignerSetTxConfirmationsRequest) Reset() { *m = SignerSetTxConfirmationsRequest{} }
+func (m *SignerSetTxConfirmationsRequest) String() string { return proto.CompactTextString(m) }
+func (*SignerSetTxConfirmationsRequest) ProtoMessage() {}
+func (*SignerSetTxConfirmationsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{9}
+}
+func (m *SignerSetTxConfirmationsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SignerSetTxConfirmationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SignerSetTxConfirmationsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SignerSetTxConfirmationsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SignerSetTxConfirmationsRequest.Merge(m, src)
+}
+func (m *SignerSetTxConfirmationsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *SignerSetTxConfirmationsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_SignerSetTxConfirmationsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignerSetTxConfirmationsRequest proto.InternalMessageInfo
+
+func (m *SignerSetTxConfirmationsRequest) GetSignerSetNonce() uint64 {
+ if m != nil {
+ return m.SignerSetNonce
+ }
+ return 0
+}
+
+type SignerSetTxConfirmationsResponse struct {
+ Signatures []*SignerSetTxConfirmation `protobuf:"bytes,1,rep,name=signatures,proto3" json:"signatures,omitempty"`
+}
+
+func (m *SignerSetTxConfirmationsResponse) Reset() { *m = SignerSetTxConfirmationsResponse{} }
+func (m *SignerSetTxConfirmationsResponse) String() string { return proto.CompactTextString(m) }
+func (*SignerSetTxConfirmationsResponse) ProtoMessage() {}
+func (*SignerSetTxConfirmationsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{10}
+}
+func (m *SignerSetTxConfirmationsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SignerSetTxConfirmationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SignerSetTxConfirmationsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SignerSetTxConfirmationsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SignerSetTxConfirmationsResponse.Merge(m, src)
+}
+func (m *SignerSetTxConfirmationsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *SignerSetTxConfirmationsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_SignerSetTxConfirmationsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignerSetTxConfirmationsResponse proto.InternalMessageInfo
+
+func (m *SignerSetTxConfirmationsResponse) GetSignatures() []*SignerSetTxConfirmation {
+ if m != nil {
+ return m.Signatures
+ }
+ return nil
+}
+
+// rpc SignerSetTxs
+type SignerSetTxsRequest struct {
+ Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
+}
+
+func (m *SignerSetTxsRequest) Reset() { *m = SignerSetTxsRequest{} }
+func (m *SignerSetTxsRequest) String() string { return proto.CompactTextString(m) }
+func (*SignerSetTxsRequest) ProtoMessage() {}
+func (*SignerSetTxsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{11}
+}
+func (m *SignerSetTxsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SignerSetTxsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SignerSetTxsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SignerSetTxsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SignerSetTxsRequest.Merge(m, src)
+}
+func (m *SignerSetTxsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *SignerSetTxsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_SignerSetTxsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignerSetTxsRequest proto.InternalMessageInfo
+
+func (m *SignerSetTxsRequest) GetPagination() *query.PageRequest {
+ if m != nil {
+ return m.Pagination
+ }
+ return nil
+}
+
+type SignerSetTxsResponse struct {
+ SignerSets []*SignerSetTx `protobuf:"bytes,1,rep,name=signer_sets,json=signerSets,proto3" json:"signer_sets,omitempty"`
+ Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
+}
+
+func (m *SignerSetTxsResponse) Reset() { *m = SignerSetTxsResponse{} }
+func (m *SignerSetTxsResponse) String() string { return proto.CompactTextString(m) }
+func (*SignerSetTxsResponse) ProtoMessage() {}
+func (*SignerSetTxsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{12}
+}
+func (m *SignerSetTxsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SignerSetTxsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_SignerSetTxsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *SignerSetTxsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SignerSetTxsResponse.Merge(m, src)
+}
+func (m *SignerSetTxsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *SignerSetTxsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_SignerSetTxsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignerSetTxsResponse proto.InternalMessageInfo
+
+func (m *SignerSetTxsResponse) GetSignerSets() []*SignerSetTx {
+ if m != nil {
+ return m.SignerSets
+ }
+ return nil
+}
+
+func (m *SignerSetTxsResponse) GetPagination() *query.PageResponse {
+ if m != nil {
+ return m.Pagination
+ }
+ return nil
+}
+
+// rpc BatchTxs
+type BatchTxsRequest struct {
+ Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
+}
+
+func (m *BatchTxsRequest) Reset() { *m = BatchTxsRequest{} }
+func (m *BatchTxsRequest) String() string { return proto.CompactTextString(m) }
+func (*BatchTxsRequest) ProtoMessage() {}
+func (*BatchTxsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{13}
+}
+func (m *BatchTxsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTxsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTxsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTxsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTxsRequest.Merge(m, src)
+}
+func (m *BatchTxsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTxsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTxsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTxsRequest proto.InternalMessageInfo
+
+func (m *BatchTxsRequest) GetPagination() *query.PageRequest {
+ if m != nil {
+ return m.Pagination
+ }
+ return nil
+}
+
+type BatchTxsResponse struct {
+ Batches []*BatchTx `protobuf:"bytes,1,rep,name=batches,proto3" json:"batches,omitempty"`
+ Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
+}
+
+func (m *BatchTxsResponse) Reset() { *m = BatchTxsResponse{} }
+func (m *BatchTxsResponse) String() string { return proto.CompactTextString(m) }
+func (*BatchTxsResponse) ProtoMessage() {}
+func (*BatchTxsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{14}
+}
+func (m *BatchTxsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTxsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTxsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTxsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTxsResponse.Merge(m, src)
+}
+func (m *BatchTxsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTxsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTxsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTxsResponse proto.InternalMessageInfo
+
+func (m *BatchTxsResponse) GetBatches() []*BatchTx {
+ if m != nil {
+ return m.Batches
+ }
+ return nil
+}
+
+func (m *BatchTxsResponse) GetPagination() *query.PageResponse {
+ if m != nil {
+ return m.Pagination
+ }
+ return nil
+}
+
+// rpc ContractCallTxs
+type ContractCallTxsRequest struct {
+ Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
+}
+
+func (m *ContractCallTxsRequest) Reset() { *m = ContractCallTxsRequest{} }
+func (m *ContractCallTxsRequest) String() string { return proto.CompactTextString(m) }
+func (*ContractCallTxsRequest) ProtoMessage() {}
+func (*ContractCallTxsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{15}
+}
+func (m *ContractCallTxsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ContractCallTxsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ContractCallTxsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ContractCallTxsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ContractCallTxsRequest.Merge(m, src)
+}
+func (m *ContractCallTxsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *ContractCallTxsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_ContractCallTxsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ContractCallTxsRequest proto.InternalMessageInfo
+
+func (m *ContractCallTxsRequest) GetPagination() *query.PageRequest {
+ if m != nil {
+ return m.Pagination
+ }
+ return nil
+}
+
+type ContractCallTxsResponse struct {
+ Calls []*ContractCallTx `protobuf:"bytes,1,rep,name=calls,proto3" json:"calls,omitempty"`
+ Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
+}
+
+func (m *ContractCallTxsResponse) Reset() { *m = ContractCallTxsResponse{} }
+func (m *ContractCallTxsResponse) String() string { return proto.CompactTextString(m) }
+func (*ContractCallTxsResponse) ProtoMessage() {}
+func (*ContractCallTxsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{16}
+}
+func (m *ContractCallTxsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ContractCallTxsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ContractCallTxsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ContractCallTxsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ContractCallTxsResponse.Merge(m, src)
+}
+func (m *ContractCallTxsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *ContractCallTxsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_ContractCallTxsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ContractCallTxsResponse proto.InternalMessageInfo
+
+func (m *ContractCallTxsResponse) GetCalls() []*ContractCallTx {
+ if m != nil {
+ return m.Calls
+ }
+ return nil
+}
+
+func (m *ContractCallTxsResponse) GetPagination() *query.PageResponse {
+ if m != nil {
+ return m.Pagination
+ }
+ return nil
+}
+
+// rpc UnsignedSignerSetTxs
+type UnsignedSignerSetTxsRequest struct {
+ // NOTE: this is an sdk.AccAddress and can represent either the
+ // orchestartor address or the cooresponding validator address
+ Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
+}
+
+func (m *UnsignedSignerSetTxsRequest) Reset() { *m = UnsignedSignerSetTxsRequest{} }
+func (m *UnsignedSignerSetTxsRequest) String() string { return proto.CompactTextString(m) }
+func (*UnsignedSignerSetTxsRequest) ProtoMessage() {}
+func (*UnsignedSignerSetTxsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{17}
+}
+func (m *UnsignedSignerSetTxsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *UnsignedSignerSetTxsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_UnsignedSignerSetTxsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *UnsignedSignerSetTxsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UnsignedSignerSetTxsRequest.Merge(m, src)
+}
+func (m *UnsignedSignerSetTxsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *UnsignedSignerSetTxsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_UnsignedSignerSetTxsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UnsignedSignerSetTxsRequest proto.InternalMessageInfo
+
+func (m *UnsignedSignerSetTxsRequest) GetAddress() string {
+ if m != nil {
+ return m.Address
+ }
+ return ""
+}
+
+type UnsignedSignerSetTxsResponse struct {
+ SignerSets []*SignerSetTx `protobuf:"bytes,1,rep,name=signer_sets,json=signerSets,proto3" json:"signer_sets,omitempty"`
+}
+
+func (m *UnsignedSignerSetTxsResponse) Reset() { *m = UnsignedSignerSetTxsResponse{} }
+func (m *UnsignedSignerSetTxsResponse) String() string { return proto.CompactTextString(m) }
+func (*UnsignedSignerSetTxsResponse) ProtoMessage() {}
+func (*UnsignedSignerSetTxsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{18}
+}
+func (m *UnsignedSignerSetTxsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *UnsignedSignerSetTxsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_UnsignedSignerSetTxsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *UnsignedSignerSetTxsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UnsignedSignerSetTxsResponse.Merge(m, src)
+}
+func (m *UnsignedSignerSetTxsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *UnsignedSignerSetTxsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_UnsignedSignerSetTxsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UnsignedSignerSetTxsResponse proto.InternalMessageInfo
+
+func (m *UnsignedSignerSetTxsResponse) GetSignerSets() []*SignerSetTx {
+ if m != nil {
+ return m.SignerSets
+ }
+ return nil
+}
+
+type UnsignedBatchTxsRequest struct {
+ // NOTE: this is an sdk.AccAddress and can represent either the
+ // orchestrator address or the cooresponding validator address
+ Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
+}
+
+func (m *UnsignedBatchTxsRequest) Reset() { *m = UnsignedBatchTxsRequest{} }
+func (m *UnsignedBatchTxsRequest) String() string { return proto.CompactTextString(m) }
+func (*UnsignedBatchTxsRequest) ProtoMessage() {}
+func (*UnsignedBatchTxsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{19}
+}
+func (m *UnsignedBatchTxsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *UnsignedBatchTxsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_UnsignedBatchTxsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *UnsignedBatchTxsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UnsignedBatchTxsRequest.Merge(m, src)
+}
+func (m *UnsignedBatchTxsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *UnsignedBatchTxsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_UnsignedBatchTxsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UnsignedBatchTxsRequest proto.InternalMessageInfo
+
+func (m *UnsignedBatchTxsRequest) GetAddress() string {
+ if m != nil {
+ return m.Address
+ }
+ return ""
+}
+
+type UnsignedBatchTxsResponse struct {
+ // Note these are returned with the signature empty
+ Batches []*BatchTx `protobuf:"bytes,1,rep,name=batches,proto3" json:"batches,omitempty"`
+}
+
+func (m *UnsignedBatchTxsResponse) Reset() { *m = UnsignedBatchTxsResponse{} }
+func (m *UnsignedBatchTxsResponse) String() string { return proto.CompactTextString(m) }
+func (*UnsignedBatchTxsResponse) ProtoMessage() {}
+func (*UnsignedBatchTxsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{20}
+}
+func (m *UnsignedBatchTxsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *UnsignedBatchTxsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_UnsignedBatchTxsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *UnsignedBatchTxsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UnsignedBatchTxsResponse.Merge(m, src)
+}
+func (m *UnsignedBatchTxsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *UnsignedBatchTxsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_UnsignedBatchTxsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UnsignedBatchTxsResponse proto.InternalMessageInfo
+
+func (m *UnsignedBatchTxsResponse) GetBatches() []*BatchTx {
+ if m != nil {
+ return m.Batches
+ }
+ return nil
+}
+
+// rpc UnsignedContractCallTxs
+type UnsignedContractCallTxsRequest struct {
+ Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
+}
+
+func (m *UnsignedContractCallTxsRequest) Reset() { *m = UnsignedContractCallTxsRequest{} }
+func (m *UnsignedContractCallTxsRequest) String() string { return proto.CompactTextString(m) }
+func (*UnsignedContractCallTxsRequest) ProtoMessage() {}
+func (*UnsignedContractCallTxsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{21}
+}
+func (m *UnsignedContractCallTxsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *UnsignedContractCallTxsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_UnsignedContractCallTxsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *UnsignedContractCallTxsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UnsignedContractCallTxsRequest.Merge(m, src)
+}
+func (m *UnsignedContractCallTxsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *UnsignedContractCallTxsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_UnsignedContractCallTxsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UnsignedContractCallTxsRequest proto.InternalMessageInfo
+
+func (m *UnsignedContractCallTxsRequest) GetAddress() string {
+ if m != nil {
+ return m.Address
+ }
+ return ""
+}
+
+type UnsignedContractCallTxsResponse struct {
+ Calls []*ContractCallTx `protobuf:"bytes,1,rep,name=calls,proto3" json:"calls,omitempty"`
+}
+
+func (m *UnsignedContractCallTxsResponse) Reset() { *m = UnsignedContractCallTxsResponse{} }
+func (m *UnsignedContractCallTxsResponse) String() string { return proto.CompactTextString(m) }
+func (*UnsignedContractCallTxsResponse) ProtoMessage() {}
+func (*UnsignedContractCallTxsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{22}
+}
+func (m *UnsignedContractCallTxsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *UnsignedContractCallTxsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_UnsignedContractCallTxsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *UnsignedContractCallTxsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UnsignedContractCallTxsResponse.Merge(m, src)
+}
+func (m *UnsignedContractCallTxsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *UnsignedContractCallTxsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_UnsignedContractCallTxsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UnsignedContractCallTxsResponse proto.InternalMessageInfo
+
+func (m *UnsignedContractCallTxsResponse) GetCalls() []*ContractCallTx {
+ if m != nil {
+ return m.Calls
+ }
+ return nil
+}
+
+type BatchTxFeesRequest struct {
+}
+
+func (m *BatchTxFeesRequest) Reset() { *m = BatchTxFeesRequest{} }
+func (m *BatchTxFeesRequest) String() string { return proto.CompactTextString(m) }
+func (*BatchTxFeesRequest) ProtoMessage() {}
+func (*BatchTxFeesRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{23}
+}
+func (m *BatchTxFeesRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTxFeesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTxFeesRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTxFeesRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTxFeesRequest.Merge(m, src)
+}
+func (m *BatchTxFeesRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTxFeesRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTxFeesRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTxFeesRequest proto.InternalMessageInfo
+
+type BatchTxFeesResponse struct {
+ Fees github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=fees,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"fees"`
+}
+
+func (m *BatchTxFeesResponse) Reset() { *m = BatchTxFeesResponse{} }
+func (m *BatchTxFeesResponse) String() string { return proto.CompactTextString(m) }
+func (*BatchTxFeesResponse) ProtoMessage() {}
+func (*BatchTxFeesResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{24}
+}
+func (m *BatchTxFeesResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTxFeesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTxFeesResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTxFeesResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTxFeesResponse.Merge(m, src)
+}
+func (m *BatchTxFeesResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTxFeesResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTxFeesResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTxFeesResponse proto.InternalMessageInfo
+
+func (m *BatchTxFeesResponse) GetFees() github_com_cosmos_cosmos_sdk_types.Coins {
+ if m != nil {
+ return m.Fees
+ }
+ return nil
+}
+
+type ContractCallTxConfirmationsRequest struct {
+ InvalidationScope []byte `protobuf:"bytes,1,opt,name=invalidation_scope,json=invalidationScope,proto3" json:"invalidation_scope,omitempty"`
+ InvalidationNonce uint64 `protobuf:"varint,2,opt,name=invalidation_nonce,json=invalidationNonce,proto3" json:"invalidation_nonce,omitempty"`
+}
+
+func (m *ContractCallTxConfirmationsRequest) Reset() { *m = ContractCallTxConfirmationsRequest{} }
+func (m *ContractCallTxConfirmationsRequest) String() string { return proto.CompactTextString(m) }
+func (*ContractCallTxConfirmationsRequest) ProtoMessage() {}
+func (*ContractCallTxConfirmationsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{25}
+}
+func (m *ContractCallTxConfirmationsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ContractCallTxConfirmationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ContractCallTxConfirmationsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ContractCallTxConfirmationsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ContractCallTxConfirmationsRequest.Merge(m, src)
+}
+func (m *ContractCallTxConfirmationsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *ContractCallTxConfirmationsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_ContractCallTxConfirmationsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ContractCallTxConfirmationsRequest proto.InternalMessageInfo
+
+func (m *ContractCallTxConfirmationsRequest) GetInvalidationScope() []byte {
+ if m != nil {
+ return m.InvalidationScope
+ }
+ return nil
+}
+
+func (m *ContractCallTxConfirmationsRequest) GetInvalidationNonce() uint64 {
+ if m != nil {
+ return m.InvalidationNonce
+ }
+ return 0
+}
+
+type ContractCallTxConfirmationsResponse struct {
+ Signatures []*ContractCallTxConfirmation `protobuf:"bytes,1,rep,name=signatures,proto3" json:"signatures,omitempty"`
+}
+
+func (m *ContractCallTxConfirmationsResponse) Reset() { *m = ContractCallTxConfirmationsResponse{} }
+func (m *ContractCallTxConfirmationsResponse) String() string { return proto.CompactTextString(m) }
+func (*ContractCallTxConfirmationsResponse) ProtoMessage() {}
+func (*ContractCallTxConfirmationsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{26}
+}
+func (m *ContractCallTxConfirmationsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ContractCallTxConfirmationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ContractCallTxConfirmationsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ContractCallTxConfirmationsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ContractCallTxConfirmationsResponse.Merge(m, src)
+}
+func (m *ContractCallTxConfirmationsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *ContractCallTxConfirmationsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_ContractCallTxConfirmationsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ContractCallTxConfirmationsResponse proto.InternalMessageInfo
+
+func (m *ContractCallTxConfirmationsResponse) GetSignatures() []*ContractCallTxConfirmation {
+ if m != nil {
+ return m.Signatures
+ }
+ return nil
+}
+
+type BatchTxConfirmationsRequest struct {
+ BatchNonce uint64 `protobuf:"varint,1,opt,name=batch_nonce,json=batchNonce,proto3" json:"batch_nonce,omitempty"`
+ TokenContract string `protobuf:"bytes,2,opt,name=token_contract,json=tokenContract,proto3" json:"token_contract,omitempty"`
+}
+
+func (m *BatchTxConfirmationsRequest) Reset() { *m = BatchTxConfirmationsRequest{} }
+func (m *BatchTxConfirmationsRequest) String() string { return proto.CompactTextString(m) }
+func (*BatchTxConfirmationsRequest) ProtoMessage() {}
+func (*BatchTxConfirmationsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{27}
+}
+func (m *BatchTxConfirmationsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTxConfirmationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTxConfirmationsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTxConfirmationsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTxConfirmationsRequest.Merge(m, src)
+}
+func (m *BatchTxConfirmationsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTxConfirmationsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTxConfirmationsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTxConfirmationsRequest proto.InternalMessageInfo
+
+func (m *BatchTxConfirmationsRequest) GetBatchNonce() uint64 {
+ if m != nil {
+ return m.BatchNonce
+ }
+ return 0
+}
+
+func (m *BatchTxConfirmationsRequest) GetTokenContract() string {
+ if m != nil {
+ return m.TokenContract
+ }
+ return ""
+}
+
+type BatchTxConfirmationsResponse struct {
+ Signatures []*BatchTxConfirmation `protobuf:"bytes,1,rep,name=signatures,proto3" json:"signatures,omitempty"`
+}
+
+func (m *BatchTxConfirmationsResponse) Reset() { *m = BatchTxConfirmationsResponse{} }
+func (m *BatchTxConfirmationsResponse) String() string { return proto.CompactTextString(m) }
+func (*BatchTxConfirmationsResponse) ProtoMessage() {}
+func (*BatchTxConfirmationsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{28}
+}
+func (m *BatchTxConfirmationsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchTxConfirmationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchTxConfirmationsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchTxConfirmationsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchTxConfirmationsResponse.Merge(m, src)
+}
+func (m *BatchTxConfirmationsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchTxConfirmationsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchTxConfirmationsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchTxConfirmationsResponse proto.InternalMessageInfo
+
+func (m *BatchTxConfirmationsResponse) GetSignatures() []*BatchTxConfirmation {
+ if m != nil {
+ return m.Signatures
+ }
+ return nil
+}
+
+type LastSubmittedEthereumEventRequest struct {
+ Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
+}
+
+func (m *LastSubmittedEthereumEventRequest) Reset() { *m = LastSubmittedEthereumEventRequest{} }
+func (m *LastSubmittedEthereumEventRequest) String() string { return proto.CompactTextString(m) }
+func (*LastSubmittedEthereumEventRequest) ProtoMessage() {}
+func (*LastSubmittedEthereumEventRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{29}
+}
+func (m *LastSubmittedEthereumEventRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *LastSubmittedEthereumEventRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_LastSubmittedEthereumEventRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *LastSubmittedEthereumEventRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LastSubmittedEthereumEventRequest.Merge(m, src)
+}
+func (m *LastSubmittedEthereumEventRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *LastSubmittedEthereumEventRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_LastSubmittedEthereumEventRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LastSubmittedEthereumEventRequest proto.InternalMessageInfo
+
+func (m *LastSubmittedEthereumEventRequest) GetAddress() string {
+ if m != nil {
+ return m.Address
+ }
+ return ""
+}
+
+type LastSubmittedEthereumEventResponse struct {
+ EventNonce uint64 `protobuf:"varint,1,opt,name=event_nonce,json=eventNonce,proto3" json:"event_nonce,omitempty"`
+}
+
+func (m *LastSubmittedEthereumEventResponse) Reset() { *m = LastSubmittedEthereumEventResponse{} }
+func (m *LastSubmittedEthereumEventResponse) String() string { return proto.CompactTextString(m) }
+func (*LastSubmittedEthereumEventResponse) ProtoMessage() {}
+func (*LastSubmittedEthereumEventResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{30}
+}
+func (m *LastSubmittedEthereumEventResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *LastSubmittedEthereumEventResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_LastSubmittedEthereumEventResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *LastSubmittedEthereumEventResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LastSubmittedEthereumEventResponse.Merge(m, src)
+}
+func (m *LastSubmittedEthereumEventResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *LastSubmittedEthereumEventResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_LastSubmittedEthereumEventResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LastSubmittedEthereumEventResponse proto.InternalMessageInfo
+
+func (m *LastSubmittedEthereumEventResponse) GetEventNonce() uint64 {
+ if m != nil {
+ return m.EventNonce
+ }
+ return 0
+}
+
+type ERC20ToDenomRequest struct {
+ Erc20 string `protobuf:"bytes,1,opt,name=erc20,proto3" json:"erc20,omitempty"`
+}
+
+func (m *ERC20ToDenomRequest) Reset() { *m = ERC20ToDenomRequest{} }
+func (m *ERC20ToDenomRequest) String() string { return proto.CompactTextString(m) }
+func (*ERC20ToDenomRequest) ProtoMessage() {}
+func (*ERC20ToDenomRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{31}
+}
+func (m *ERC20ToDenomRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ERC20ToDenomRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ERC20ToDenomRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ERC20ToDenomRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ERC20ToDenomRequest.Merge(m, src)
+}
+func (m *ERC20ToDenomRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *ERC20ToDenomRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_ERC20ToDenomRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ERC20ToDenomRequest proto.InternalMessageInfo
+
+func (m *ERC20ToDenomRequest) GetErc20() string {
+ if m != nil {
+ return m.Erc20
+ }
+ return ""
+}
+
+type ERC20ToDenomResponse struct {
+ Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
+ CosmosOriginated bool `protobuf:"varint,2,opt,name=cosmos_originated,json=cosmosOriginated,proto3" json:"cosmos_originated,omitempty"`
+}
+
+func (m *ERC20ToDenomResponse) Reset() { *m = ERC20ToDenomResponse{} }
+func (m *ERC20ToDenomResponse) String() string { return proto.CompactTextString(m) }
+func (*ERC20ToDenomResponse) ProtoMessage() {}
+func (*ERC20ToDenomResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{32}
+}
+func (m *ERC20ToDenomResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ERC20ToDenomResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ERC20ToDenomResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ERC20ToDenomResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ERC20ToDenomResponse.Merge(m, src)
+}
+func (m *ERC20ToDenomResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *ERC20ToDenomResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_ERC20ToDenomResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ERC20ToDenomResponse proto.InternalMessageInfo
+
+func (m *ERC20ToDenomResponse) GetDenom() string {
+ if m != nil {
+ return m.Denom
+ }
+ return ""
+}
+
+func (m *ERC20ToDenomResponse) GetCosmosOriginated() bool {
+ if m != nil {
+ return m.CosmosOriginated
+ }
+ return false
+}
+
+type DenomToERC20ParamsRequest struct {
+ Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
+}
+
+func (m *DenomToERC20ParamsRequest) Reset() { *m = DenomToERC20ParamsRequest{} }
+func (m *DenomToERC20ParamsRequest) String() string { return proto.CompactTextString(m) }
+func (*DenomToERC20ParamsRequest) ProtoMessage() {}
+func (*DenomToERC20ParamsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{33}
+}
+func (m *DenomToERC20ParamsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DenomToERC20ParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DenomToERC20ParamsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DenomToERC20ParamsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DenomToERC20ParamsRequest.Merge(m, src)
+}
+func (m *DenomToERC20ParamsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *DenomToERC20ParamsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_DenomToERC20ParamsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DenomToERC20ParamsRequest proto.InternalMessageInfo
+
+func (m *DenomToERC20ParamsRequest) GetDenom() string {
+ if m != nil {
+ return m.Denom
+ }
+ return ""
+}
+
+type DenomToERC20ParamsResponse struct {
+ BaseDenom string `protobuf:"bytes,1,opt,name=base_denom,json=baseDenom,proto3" json:"base_denom,omitempty"`
+ Erc20Name string `protobuf:"bytes,2,opt,name=erc20_name,json=erc20Name,proto3" json:"erc20_name,omitempty"`
+ Erc20Symbol string `protobuf:"bytes,3,opt,name=erc20_symbol,json=erc20Symbol,proto3" json:"erc20_symbol,omitempty"`
+ Erc20Decimals uint64 `protobuf:"varint,4,opt,name=erc20_decimals,json=erc20Decimals,proto3" json:"erc20_decimals,omitempty"`
+}
+
+func (m *DenomToERC20ParamsResponse) Reset() { *m = DenomToERC20ParamsResponse{} }
+func (m *DenomToERC20ParamsResponse) String() string { return proto.CompactTextString(m) }
+func (*DenomToERC20ParamsResponse) ProtoMessage() {}
+func (*DenomToERC20ParamsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{34}
+}
+func (m *DenomToERC20ParamsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DenomToERC20ParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DenomToERC20ParamsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DenomToERC20ParamsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DenomToERC20ParamsResponse.Merge(m, src)
+}
+func (m *DenomToERC20ParamsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *DenomToERC20ParamsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_DenomToERC20ParamsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DenomToERC20ParamsResponse proto.InternalMessageInfo
+
+func (m *DenomToERC20ParamsResponse) GetBaseDenom() string {
+ if m != nil {
+ return m.BaseDenom
+ }
+ return ""
+}
+
+func (m *DenomToERC20ParamsResponse) GetErc20Name() string {
+ if m != nil {
+ return m.Erc20Name
+ }
+ return ""
+}
+
+func (m *DenomToERC20ParamsResponse) GetErc20Symbol() string {
+ if m != nil {
+ return m.Erc20Symbol
+ }
+ return ""
+}
+
+func (m *DenomToERC20ParamsResponse) GetErc20Decimals() uint64 {
+ if m != nil {
+ return m.Erc20Decimals
+ }
+ return 0
+}
+
+type DenomToERC20Request struct {
+ Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
+}
+
+func (m *DenomToERC20Request) Reset() { *m = DenomToERC20Request{} }
+func (m *DenomToERC20Request) String() string { return proto.CompactTextString(m) }
+func (*DenomToERC20Request) ProtoMessage() {}
+func (*DenomToERC20Request) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{35}
+}
+func (m *DenomToERC20Request) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DenomToERC20Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DenomToERC20Request.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DenomToERC20Request) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DenomToERC20Request.Merge(m, src)
+}
+func (m *DenomToERC20Request) XXX_Size() int {
+ return m.Size()
+}
+func (m *DenomToERC20Request) XXX_DiscardUnknown() {
+ xxx_messageInfo_DenomToERC20Request.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DenomToERC20Request proto.InternalMessageInfo
+
+func (m *DenomToERC20Request) GetDenom() string {
+ if m != nil {
+ return m.Denom
+ }
+ return ""
+}
+
+type DenomToERC20Response struct {
+ Erc20 string `protobuf:"bytes,1,opt,name=erc20,proto3" json:"erc20,omitempty"`
+ CosmosOriginated bool `protobuf:"varint,2,opt,name=cosmos_originated,json=cosmosOriginated,proto3" json:"cosmos_originated,omitempty"`
+}
+
+func (m *DenomToERC20Response) Reset() { *m = DenomToERC20Response{} }
+func (m *DenomToERC20Response) String() string { return proto.CompactTextString(m) }
+func (*DenomToERC20Response) ProtoMessage() {}
+func (*DenomToERC20Response) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{36}
+}
+func (m *DenomToERC20Response) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DenomToERC20Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DenomToERC20Response.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DenomToERC20Response) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DenomToERC20Response.Merge(m, src)
+}
+func (m *DenomToERC20Response) XXX_Size() int {
+ return m.Size()
+}
+func (m *DenomToERC20Response) XXX_DiscardUnknown() {
+ xxx_messageInfo_DenomToERC20Response.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DenomToERC20Response proto.InternalMessageInfo
+
+func (m *DenomToERC20Response) GetErc20() string {
+ if m != nil {
+ return m.Erc20
+ }
+ return ""
+}
+
+func (m *DenomToERC20Response) GetCosmosOriginated() bool {
+ if m != nil {
+ return m.CosmosOriginated
+ }
+ return false
+}
+
+type DelegateKeysByValidatorRequest struct {
+ ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
+}
+
+func (m *DelegateKeysByValidatorRequest) Reset() { *m = DelegateKeysByValidatorRequest{} }
+func (m *DelegateKeysByValidatorRequest) String() string { return proto.CompactTextString(m) }
+func (*DelegateKeysByValidatorRequest) ProtoMessage() {}
+func (*DelegateKeysByValidatorRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{37}
+}
+func (m *DelegateKeysByValidatorRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DelegateKeysByValidatorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DelegateKeysByValidatorRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DelegateKeysByValidatorRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DelegateKeysByValidatorRequest.Merge(m, src)
+}
+func (m *DelegateKeysByValidatorRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *DelegateKeysByValidatorRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_DelegateKeysByValidatorRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DelegateKeysByValidatorRequest proto.InternalMessageInfo
+
+func (m *DelegateKeysByValidatorRequest) GetValidatorAddress() string {
+ if m != nil {
+ return m.ValidatorAddress
+ }
+ return ""
+}
+
+type DelegateKeysByValidatorResponse struct {
+ EthAddress string `protobuf:"bytes,1,opt,name=eth_address,json=ethAddress,proto3" json:"eth_address,omitempty"`
+ OrchestratorAddress string `protobuf:"bytes,2,opt,name=orchestrator_address,json=orchestratorAddress,proto3" json:"orchestrator_address,omitempty"`
+}
+
+func (m *DelegateKeysByValidatorResponse) Reset() { *m = DelegateKeysByValidatorResponse{} }
+func (m *DelegateKeysByValidatorResponse) String() string { return proto.CompactTextString(m) }
+func (*DelegateKeysByValidatorResponse) ProtoMessage() {}
+func (*DelegateKeysByValidatorResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{38}
+}
+func (m *DelegateKeysByValidatorResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DelegateKeysByValidatorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DelegateKeysByValidatorResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DelegateKeysByValidatorResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DelegateKeysByValidatorResponse.Merge(m, src)
+}
+func (m *DelegateKeysByValidatorResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *DelegateKeysByValidatorResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_DelegateKeysByValidatorResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DelegateKeysByValidatorResponse proto.InternalMessageInfo
+
+func (m *DelegateKeysByValidatorResponse) GetEthAddress() string {
+ if m != nil {
+ return m.EthAddress
+ }
+ return ""
+}
+
+func (m *DelegateKeysByValidatorResponse) GetOrchestratorAddress() string {
+ if m != nil {
+ return m.OrchestratorAddress
+ }
+ return ""
+}
+
+type DelegateKeysByEthereumSignerRequest struct {
+ EthereumSigner string `protobuf:"bytes,1,opt,name=ethereum_signer,json=ethereumSigner,proto3" json:"ethereum_signer,omitempty"`
+}
+
+func (m *DelegateKeysByEthereumSignerRequest) Reset() { *m = DelegateKeysByEthereumSignerRequest{} }
+func (m *DelegateKeysByEthereumSignerRequest) String() string { return proto.CompactTextString(m) }
+func (*DelegateKeysByEthereumSignerRequest) ProtoMessage() {}
+func (*DelegateKeysByEthereumSignerRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{39}
+}
+func (m *DelegateKeysByEthereumSignerRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DelegateKeysByEthereumSignerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DelegateKeysByEthereumSignerRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DelegateKeysByEthereumSignerRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DelegateKeysByEthereumSignerRequest.Merge(m, src)
+}
+func (m *DelegateKeysByEthereumSignerRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *DelegateKeysByEthereumSignerRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_DelegateKeysByEthereumSignerRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DelegateKeysByEthereumSignerRequest proto.InternalMessageInfo
+
+func (m *DelegateKeysByEthereumSignerRequest) GetEthereumSigner() string {
+ if m != nil {
+ return m.EthereumSigner
+ }
+ return ""
+}
+
+type DelegateKeysByEthereumSignerResponse struct {
+ ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
+ OrchestratorAddress string `protobuf:"bytes,2,opt,name=orchestrator_address,json=orchestratorAddress,proto3" json:"orchestrator_address,omitempty"`
+}
+
+func (m *DelegateKeysByEthereumSignerResponse) Reset() { *m = DelegateKeysByEthereumSignerResponse{} }
+func (m *DelegateKeysByEthereumSignerResponse) String() string { return proto.CompactTextString(m) }
+func (*DelegateKeysByEthereumSignerResponse) ProtoMessage() {}
+func (*DelegateKeysByEthereumSignerResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{40}
+}
+func (m *DelegateKeysByEthereumSignerResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DelegateKeysByEthereumSignerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DelegateKeysByEthereumSignerResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DelegateKeysByEthereumSignerResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DelegateKeysByEthereumSignerResponse.Merge(m, src)
+}
+func (m *DelegateKeysByEthereumSignerResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *DelegateKeysByEthereumSignerResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_DelegateKeysByEthereumSignerResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DelegateKeysByEthereumSignerResponse proto.InternalMessageInfo
+
+func (m *DelegateKeysByEthereumSignerResponse) GetValidatorAddress() string {
+ if m != nil {
+ return m.ValidatorAddress
+ }
+ return ""
+}
+
+func (m *DelegateKeysByEthereumSignerResponse) GetOrchestratorAddress() string {
+ if m != nil {
+ return m.OrchestratorAddress
+ }
+ return ""
+}
+
+type DelegateKeysByOrchestratorRequest struct {
+ OrchestratorAddress string `protobuf:"bytes,1,opt,name=orchestrator_address,json=orchestratorAddress,proto3" json:"orchestrator_address,omitempty"`
+}
+
+func (m *DelegateKeysByOrchestratorRequest) Reset() { *m = DelegateKeysByOrchestratorRequest{} }
+func (m *DelegateKeysByOrchestratorRequest) String() string { return proto.CompactTextString(m) }
+func (*DelegateKeysByOrchestratorRequest) ProtoMessage() {}
+func (*DelegateKeysByOrchestratorRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{41}
+}
+func (m *DelegateKeysByOrchestratorRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DelegateKeysByOrchestratorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DelegateKeysByOrchestratorRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DelegateKeysByOrchestratorRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DelegateKeysByOrchestratorRequest.Merge(m, src)
+}
+func (m *DelegateKeysByOrchestratorRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *DelegateKeysByOrchestratorRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_DelegateKeysByOrchestratorRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DelegateKeysByOrchestratorRequest proto.InternalMessageInfo
+
+func (m *DelegateKeysByOrchestratorRequest) GetOrchestratorAddress() string {
+ if m != nil {
+ return m.OrchestratorAddress
+ }
+ return ""
+}
+
+type DelegateKeysByOrchestratorResponse struct {
+ ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
+ EthereumSigner string `protobuf:"bytes,2,opt,name=ethereum_signer,json=ethereumSigner,proto3" json:"ethereum_signer,omitempty"`
+}
+
+func (m *DelegateKeysByOrchestratorResponse) Reset() { *m = DelegateKeysByOrchestratorResponse{} }
+func (m *DelegateKeysByOrchestratorResponse) String() string { return proto.CompactTextString(m) }
+func (*DelegateKeysByOrchestratorResponse) ProtoMessage() {}
+func (*DelegateKeysByOrchestratorResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{42}
+}
+func (m *DelegateKeysByOrchestratorResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DelegateKeysByOrchestratorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DelegateKeysByOrchestratorResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DelegateKeysByOrchestratorResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DelegateKeysByOrchestratorResponse.Merge(m, src)
+}
+func (m *DelegateKeysByOrchestratorResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *DelegateKeysByOrchestratorResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_DelegateKeysByOrchestratorResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DelegateKeysByOrchestratorResponse proto.InternalMessageInfo
+
+func (m *DelegateKeysByOrchestratorResponse) GetValidatorAddress() string {
+ if m != nil {
+ return m.ValidatorAddress
+ }
+ return ""
+}
+
+func (m *DelegateKeysByOrchestratorResponse) GetEthereumSigner() string {
+ if m != nil {
+ return m.EthereumSigner
+ }
+ return ""
+}
+
+type DelegateKeysRequest struct {
+}
+
+func (m *DelegateKeysRequest) Reset() { *m = DelegateKeysRequest{} }
+func (m *DelegateKeysRequest) String() string { return proto.CompactTextString(m) }
+func (*DelegateKeysRequest) ProtoMessage() {}
+func (*DelegateKeysRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{43}
+}
+func (m *DelegateKeysRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DelegateKeysRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DelegateKeysRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DelegateKeysRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DelegateKeysRequest.Merge(m, src)
+}
+func (m *DelegateKeysRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *DelegateKeysRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_DelegateKeysRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DelegateKeysRequest proto.InternalMessageInfo
+
+type DelegateKeysResponse struct {
+ DelegateKeys []*MsgDelegateKeys `protobuf:"bytes,1,rep,name=delegate_keys,json=delegateKeys,proto3" json:"delegate_keys,omitempty"`
+}
+
+func (m *DelegateKeysResponse) Reset() { *m = DelegateKeysResponse{} }
+func (m *DelegateKeysResponse) String() string { return proto.CompactTextString(m) }
+func (*DelegateKeysResponse) ProtoMessage() {}
+func (*DelegateKeysResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{44}
+}
+func (m *DelegateKeysResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *DelegateKeysResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_DelegateKeysResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *DelegateKeysResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DelegateKeysResponse.Merge(m, src)
+}
+func (m *DelegateKeysResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *DelegateKeysResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_DelegateKeysResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DelegateKeysResponse proto.InternalMessageInfo
+
+func (m *DelegateKeysResponse) GetDelegateKeys() []*MsgDelegateKeys {
+ if m != nil {
+ return m.DelegateKeys
+ }
+ return nil
+}
+
+// NOTE: if there is no sender address, return all
+type BatchedSendToEthereumsRequest struct {
+ SenderAddress string `protobuf:"bytes,1,opt,name=sender_address,json=senderAddress,proto3" json:"sender_address,omitempty"`
+}
+
+func (m *BatchedSendToEthereumsRequest) Reset() { *m = BatchedSendToEthereumsRequest{} }
+func (m *BatchedSendToEthereumsRequest) String() string { return proto.CompactTextString(m) }
+func (*BatchedSendToEthereumsRequest) ProtoMessage() {}
+func (*BatchedSendToEthereumsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{45}
+}
+func (m *BatchedSendToEthereumsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchedSendToEthereumsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchedSendToEthereumsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchedSendToEthereumsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchedSendToEthereumsRequest.Merge(m, src)
+}
+func (m *BatchedSendToEthereumsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchedSendToEthereumsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchedSendToEthereumsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchedSendToEthereumsRequest proto.InternalMessageInfo
+
+func (m *BatchedSendToEthereumsRequest) GetSenderAddress() string {
+ if m != nil {
+ return m.SenderAddress
+ }
+ return ""
+}
+
+type BatchedSendToEthereumsResponse struct {
+ SendToEthereums []*SendToEthereum `protobuf:"bytes,1,rep,name=send_to_ethereums,json=sendToEthereums,proto3" json:"send_to_ethereums,omitempty"`
+}
+
+func (m *BatchedSendToEthereumsResponse) Reset() { *m = BatchedSendToEthereumsResponse{} }
+func (m *BatchedSendToEthereumsResponse) String() string { return proto.CompactTextString(m) }
+func (*BatchedSendToEthereumsResponse) ProtoMessage() {}
+func (*BatchedSendToEthereumsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{46}
+}
+func (m *BatchedSendToEthereumsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *BatchedSendToEthereumsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_BatchedSendToEthereumsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *BatchedSendToEthereumsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BatchedSendToEthereumsResponse.Merge(m, src)
+}
+func (m *BatchedSendToEthereumsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *BatchedSendToEthereumsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_BatchedSendToEthereumsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BatchedSendToEthereumsResponse proto.InternalMessageInfo
+
+func (m *BatchedSendToEthereumsResponse) GetSendToEthereums() []*SendToEthereum {
+ if m != nil {
+ return m.SendToEthereums
+ }
+ return nil
+}
+
+type UnbatchedSendToEthereumsRequest struct {
+ SenderAddress string `protobuf:"bytes,1,opt,name=sender_address,json=senderAddress,proto3" json:"sender_address,omitempty"`
+ Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
+}
+
+func (m *UnbatchedSendToEthereumsRequest) Reset() { *m = UnbatchedSendToEthereumsRequest{} }
+func (m *UnbatchedSendToEthereumsRequest) String() string { return proto.CompactTextString(m) }
+func (*UnbatchedSendToEthereumsRequest) ProtoMessage() {}
+func (*UnbatchedSendToEthereumsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{47}
+}
+func (m *UnbatchedSendToEthereumsRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *UnbatchedSendToEthereumsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_UnbatchedSendToEthereumsRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *UnbatchedSendToEthereumsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UnbatchedSendToEthereumsRequest.Merge(m, src)
+}
+func (m *UnbatchedSendToEthereumsRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *UnbatchedSendToEthereumsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_UnbatchedSendToEthereumsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UnbatchedSendToEthereumsRequest proto.InternalMessageInfo
+
+func (m *UnbatchedSendToEthereumsRequest) GetSenderAddress() string {
+ if m != nil {
+ return m.SenderAddress
+ }
+ return ""
+}
+
+func (m *UnbatchedSendToEthereumsRequest) GetPagination() *query.PageRequest {
+ if m != nil {
+ return m.Pagination
+ }
+ return nil
+}
+
+type UnbatchedSendToEthereumsResponse struct {
+ SendToEthereums []*SendToEthereum `protobuf:"bytes,1,rep,name=send_to_ethereums,json=sendToEthereums,proto3" json:"send_to_ethereums,omitempty"`
+ Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
+}
+
+func (m *UnbatchedSendToEthereumsResponse) Reset() { *m = UnbatchedSendToEthereumsResponse{} }
+func (m *UnbatchedSendToEthereumsResponse) String() string { return proto.CompactTextString(m) }
+func (*UnbatchedSendToEthereumsResponse) ProtoMessage() {}
+func (*UnbatchedSendToEthereumsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_29a9d4192703013c, []int{48}
+}
+func (m *UnbatchedSendToEthereumsResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *UnbatchedSendToEthereumsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_UnbatchedSendToEthereumsResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *UnbatchedSendToEthereumsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UnbatchedSendToEthereumsResponse.Merge(m, src)
+}
+func (m *UnbatchedSendToEthereumsResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *UnbatchedSendToEthereumsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_UnbatchedSendToEthereumsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UnbatchedSendToEthereumsResponse proto.InternalMessageInfo
+
+func (m *UnbatchedSendToEthereumsResponse) GetSendToEthereums() []*SendToEthereum {
+ if m != nil {
+ return m.SendToEthereums
+ }
+ return nil
+}
+
+func (m *UnbatchedSendToEthereumsResponse) GetPagination() *query.PageResponse {
+ if m != nil {
+ return m.Pagination
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*ParamsRequest)(nil), "gravity.v1.ParamsRequest")
+ proto.RegisterType((*ParamsResponse)(nil), "gravity.v1.ParamsResponse")
+ proto.RegisterType((*SignerSetTxRequest)(nil), "gravity.v1.SignerSetTxRequest")
+ proto.RegisterType((*LatestSignerSetTxRequest)(nil), "gravity.v1.LatestSignerSetTxRequest")
+ proto.RegisterType((*SignerSetTxResponse)(nil), "gravity.v1.SignerSetTxResponse")
+ proto.RegisterType((*BatchTxRequest)(nil), "gravity.v1.BatchTxRequest")
+ proto.RegisterType((*BatchTxResponse)(nil), "gravity.v1.BatchTxResponse")
+ proto.RegisterType((*ContractCallTxRequest)(nil), "gravity.v1.ContractCallTxRequest")
+ proto.RegisterType((*ContractCallTxResponse)(nil), "gravity.v1.ContractCallTxResponse")
+ proto.RegisterType((*SignerSetTxConfirmationsRequest)(nil), "gravity.v1.SignerSetTxConfirmationsRequest")
+ proto.RegisterType((*SignerSetTxConfirmationsResponse)(nil), "gravity.v1.SignerSetTxConfirmationsResponse")
+ proto.RegisterType((*SignerSetTxsRequest)(nil), "gravity.v1.SignerSetTxsRequest")
+ proto.RegisterType((*SignerSetTxsResponse)(nil), "gravity.v1.SignerSetTxsResponse")
+ proto.RegisterType((*BatchTxsRequest)(nil), "gravity.v1.BatchTxsRequest")
+ proto.RegisterType((*BatchTxsResponse)(nil), "gravity.v1.BatchTxsResponse")
+ proto.RegisterType((*ContractCallTxsRequest)(nil), "gravity.v1.ContractCallTxsRequest")
+ proto.RegisterType((*ContractCallTxsResponse)(nil), "gravity.v1.ContractCallTxsResponse")
+ proto.RegisterType((*UnsignedSignerSetTxsRequest)(nil), "gravity.v1.UnsignedSignerSetTxsRequest")
+ proto.RegisterType((*UnsignedSignerSetTxsResponse)(nil), "gravity.v1.UnsignedSignerSetTxsResponse")
+ proto.RegisterType((*UnsignedBatchTxsRequest)(nil), "gravity.v1.UnsignedBatchTxsRequest")
+ proto.RegisterType((*UnsignedBatchTxsResponse)(nil), "gravity.v1.UnsignedBatchTxsResponse")
+ proto.RegisterType((*UnsignedContractCallTxsRequest)(nil), "gravity.v1.UnsignedContractCallTxsRequest")
+ proto.RegisterType((*UnsignedContractCallTxsResponse)(nil), "gravity.v1.UnsignedContractCallTxsResponse")
+ proto.RegisterType((*BatchTxFeesRequest)(nil), "gravity.v1.BatchTxFeesRequest")
+ proto.RegisterType((*BatchTxFeesResponse)(nil), "gravity.v1.BatchTxFeesResponse")
+ proto.RegisterType((*ContractCallTxConfirmationsRequest)(nil), "gravity.v1.ContractCallTxConfirmationsRequest")
+ proto.RegisterType((*ContractCallTxConfirmationsResponse)(nil), "gravity.v1.ContractCallTxConfirmationsResponse")
+ proto.RegisterType((*BatchTxConfirmationsRequest)(nil), "gravity.v1.BatchTxConfirmationsRequest")
+ proto.RegisterType((*BatchTxConfirmationsResponse)(nil), "gravity.v1.BatchTxConfirmationsResponse")
+ proto.RegisterType((*LastSubmittedEthereumEventRequest)(nil), "gravity.v1.LastSubmittedEthereumEventRequest")
+ proto.RegisterType((*LastSubmittedEthereumEventResponse)(nil), "gravity.v1.LastSubmittedEthereumEventResponse")
+ proto.RegisterType((*ERC20ToDenomRequest)(nil), "gravity.v1.ERC20ToDenomRequest")
+ proto.RegisterType((*ERC20ToDenomResponse)(nil), "gravity.v1.ERC20ToDenomResponse")
+ proto.RegisterType((*DenomToERC20ParamsRequest)(nil), "gravity.v1.DenomToERC20ParamsRequest")
+ proto.RegisterType((*DenomToERC20ParamsResponse)(nil), "gravity.v1.DenomToERC20ParamsResponse")
+ proto.RegisterType((*DenomToERC20Request)(nil), "gravity.v1.DenomToERC20Request")
+ proto.RegisterType((*DenomToERC20Response)(nil), "gravity.v1.DenomToERC20Response")
+ proto.RegisterType((*DelegateKeysByValidatorRequest)(nil), "gravity.v1.DelegateKeysByValidatorRequest")
+ proto.RegisterType((*DelegateKeysByValidatorResponse)(nil), "gravity.v1.DelegateKeysByValidatorResponse")
+ proto.RegisterType((*DelegateKeysByEthereumSignerRequest)(nil), "gravity.v1.DelegateKeysByEthereumSignerRequest")
+ proto.RegisterType((*DelegateKeysByEthereumSignerResponse)(nil), "gravity.v1.DelegateKeysByEthereumSignerResponse")
+ proto.RegisterType((*DelegateKeysByOrchestratorRequest)(nil), "gravity.v1.DelegateKeysByOrchestratorRequest")
+ proto.RegisterType((*DelegateKeysByOrchestratorResponse)(nil), "gravity.v1.DelegateKeysByOrchestratorResponse")
+ proto.RegisterType((*DelegateKeysRequest)(nil), "gravity.v1.DelegateKeysRequest")
+ proto.RegisterType((*DelegateKeysResponse)(nil), "gravity.v1.DelegateKeysResponse")
+ proto.RegisterType((*BatchedSendToEthereumsRequest)(nil), "gravity.v1.BatchedSendToEthereumsRequest")
+ proto.RegisterType((*BatchedSendToEthereumsResponse)(nil), "gravity.v1.BatchedSendToEthereumsResponse")
+ proto.RegisterType((*UnbatchedSendToEthereumsRequest)(nil), "gravity.v1.UnbatchedSendToEthereumsRequest")
+ proto.RegisterType((*UnbatchedSendToEthereumsResponse)(nil), "gravity.v1.UnbatchedSendToEthereumsResponse")
+}
+
+func init() { proto.RegisterFile("gravity/v1/query.proto", fileDescriptor_29a9d4192703013c) }
+
+var fileDescriptor_29a9d4192703013c = []byte{
+ // 1760 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xcb, 0x6f, 0xdb, 0x46,
+ 0x1a, 0x17, 0x1d, 0x3b, 0x89, 0x3f, 0xbf, 0xc7, 0x4a, 0xa2, 0xc8, 0x8e, 0x64, 0x8f, 0xf3, 0x70,
+ 0xe2, 0xb5, 0x64, 0x3b, 0xc0, 0x6e, 0x76, 0xb1, 0xaf, 0xf8, 0x15, 0x2c, 0xf2, 0x5c, 0xc9, 0x1b,
+ 0xc4, 0x8b, 0x5d, 0xb0, 0x94, 0x38, 0xa1, 0x59, 0x4b, 0xa4, 0x42, 0x52, 0x6a, 0x54, 0xa0, 0x40,
+ 0xd1, 0x02, 0x3d, 0xf4, 0x94, 0x43, 0x2f, 0xbd, 0xf7, 0xd4, 0x6b, 0xff, 0x89, 0x1c, 0x73, 0xec,
+ 0xa9, 0x2d, 0x9c, 0x7f, 0xa4, 0xe0, 0x70, 0x48, 0xcd, 0x50, 0x43, 0x4a, 0x71, 0xdd, 0x53, 0xa2,
+ 0xef, 0xf1, 0xfb, 0x1e, 0xfc, 0xcd, 0xf0, 0xfb, 0x68, 0xb8, 0x6c, 0x38, 0x5a, 0xc7, 0xf4, 0xba,
+ 0xe5, 0xce, 0x66, 0xf9, 0x55, 0x9b, 0x38, 0xdd, 0x52, 0xcb, 0xb1, 0x3d, 0x1b, 0x01, 0x93, 0x97,
+ 0x3a, 0x9b, 0xf9, 0x3b, 0x75, 0xdb, 0x6d, 0xda, 0x6e, 0xb9, 0xa6, 0xb9, 0x24, 0x30, 0x2a, 0x77,
+ 0x36, 0x6b, 0xc4, 0xd3, 0x36, 0xcb, 0x2d, 0xcd, 0x30, 0x2d, 0xcd, 0x33, 0x6d, 0x2b, 0xf0, 0xcb,
+ 0x17, 0x78, 0xdb, 0xd0, 0xaa, 0x6e, 0x9b, 0xa1, 0x3e, 0x6b, 0xd8, 0x86, 0x4d, 0xff, 0x5b, 0xf6,
+ 0xff, 0xc7, 0xa4, 0x8b, 0x86, 0x6d, 0x1b, 0x0d, 0x52, 0xd6, 0x5a, 0x66, 0x59, 0xb3, 0x2c, 0xdb,
+ 0xa3, 0x90, 0x2e, 0xd3, 0xe6, 0xb8, 0x1c, 0x0d, 0x62, 0x11, 0xd7, 0x94, 0x6a, 0x58, 0xc2, 0x81,
+ 0xe6, 0x12, 0xa7, 0x69, 0xba, 0x06, 0x73, 0xc0, 0x33, 0x30, 0xf5, 0x4c, 0x73, 0xb4, 0xa6, 0x5b,
+ 0x21, 0xaf, 0xda, 0xc4, 0xf5, 0xf0, 0x36, 0x4c, 0x87, 0x02, 0xb7, 0x65, 0x5b, 0x2e, 0x41, 0x1b,
+ 0x70, 0xbe, 0x45, 0x25, 0x39, 0x65, 0x49, 0x59, 0x9d, 0xd8, 0x42, 0xa5, 0x5e, 0x2b, 0x4a, 0x81,
+ 0xed, 0xf6, 0xe8, 0xdb, 0x9f, 0x8a, 0x99, 0x0a, 0xb3, 0xc3, 0x7f, 0x07, 0x54, 0x35, 0x0d, 0x8b,
+ 0x38, 0x55, 0xe2, 0x1d, 0xbc, 0x66, 0xc8, 0x68, 0x15, 0x66, 0x5d, 0x2a, 0x55, 0x5d, 0xe2, 0xa9,
+ 0x96, 0x6d, 0xd5, 0x09, 0x45, 0x1c, 0xad, 0x4c, 0xbb, 0xa1, 0xf5, 0x13, 0x5f, 0x8a, 0xf3, 0x90,
+ 0x7b, 0xa4, 0x79, 0xc4, 0xf5, 0xfa, 0x51, 0xf0, 0x63, 0x98, 0x17, 0xa4, 0x2c, 0xc9, 0x3f, 0x02,
+ 0xf4, 0xc0, 0x59, 0xa2, 0x57, 0xf8, 0x44, 0x79, 0xa7, 0xf1, 0x28, 0x1e, 0x7e, 0x01, 0xd3, 0xdb,
+ 0x9a, 0x57, 0x3f, 0xea, 0xa5, 0x79, 0x03, 0xa6, 0x3d, 0xfb, 0x98, 0x58, 0x6a, 0xdd, 0xb6, 0x3c,
+ 0x47, 0xab, 0x07, 0x68, 0xe3, 0x95, 0x29, 0x2a, 0xdd, 0x61, 0x42, 0x54, 0x84, 0x89, 0x9a, 0xef,
+ 0xc8, 0x0a, 0x19, 0xa1, 0x85, 0x00, 0x15, 0x05, 0x45, 0xfc, 0x15, 0x66, 0x22, 0x64, 0x96, 0xe4,
+ 0x6d, 0x18, 0xa3, 0x06, 0x2c, 0xbf, 0x79, 0x3e, 0xbf, 0xd0, 0x36, 0xb0, 0xc0, 0x6d, 0xb8, 0x14,
+ 0x86, 0xda, 0xd1, 0x1a, 0x8d, 0x5e, 0x7a, 0xeb, 0x80, 0x4c, 0xab, 0xa3, 0x35, 0x4c, 0x9d, 0x52,
+ 0x42, 0x75, 0xeb, 0x76, 0x2b, 0xe8, 0xe3, 0x64, 0x65, 0x8e, 0xd7, 0x54, 0x7d, 0x45, 0x9f, 0x39,
+ 0x9f, 0xad, 0x60, 0x1e, 0x24, 0x5d, 0x85, 0xcb, 0xf1, 0xb0, 0x2c, 0xf7, 0x3f, 0x03, 0x34, 0x6c,
+ 0xc3, 0xac, 0xab, 0x75, 0xad, 0xd1, 0x60, 0x05, 0xe4, 0xf9, 0x02, 0x62, 0x7e, 0xe3, 0xd4, 0xda,
+ 0xff, 0x81, 0x1f, 0x42, 0x91, 0xeb, 0xfe, 0x8e, 0x6d, 0xbd, 0x34, 0x9d, 0x66, 0x40, 0xe8, 0x0f,
+ 0xe7, 0x86, 0x01, 0x4b, 0xc9, 0x60, 0x2c, 0xd7, 0x9d, 0x80, 0x0c, 0x9a, 0xd7, 0x76, 0x88, 0xcf,
+ 0xda, 0x73, 0xab, 0x13, 0x5b, 0x2b, 0x09, 0x64, 0xe0, 0x11, 0x2a, 0x9c, 0x1b, 0xfe, 0xbf, 0x40,
+ 0xb4, 0x28, 0xd3, 0x7d, 0x80, 0xde, 0x19, 0x67, 0x7d, 0xb8, 0x59, 0x0a, 0x0e, 0x79, 0xc9, 0x3f,
+ 0xe4, 0xa5, 0xe0, 0xd6, 0x60, 0x47, 0xbd, 0xf4, 0x4c, 0x33, 0x08, 0xf3, 0xad, 0x70, 0x9e, 0xf8,
+ 0x5b, 0x05, 0xb2, 0x22, 0x3e, 0x4b, 0xfe, 0x1e, 0x4c, 0xf4, 0x5a, 0x11, 0x66, 0x9f, 0x48, 0x65,
+ 0x88, 0xda, 0xe3, 0xa2, 0x07, 0x42, 0x6a, 0x23, 0x34, 0xb5, 0x5b, 0x03, 0x53, 0x0b, 0xc2, 0x0a,
+ 0xb9, 0x1d, 0x46, 0xd4, 0x3d, 0xf3, 0xb2, 0xbf, 0x56, 0x60, 0xb6, 0x87, 0xcd, 0x4a, 0x5e, 0x87,
+ 0x0b, 0x94, 0xf5, 0xd1, 0xc3, 0x92, 0x9e, 0x8c, 0xd0, 0xe6, 0xec, 0xea, 0xfc, 0x28, 0xce, 0xf6,
+ 0x33, 0x2f, 0xf7, 0x1b, 0x05, 0xae, 0xf4, 0x85, 0x88, 0xee, 0xd5, 0x31, 0xff, 0x2c, 0x85, 0x35,
+ 0xa7, 0x1d, 0xa6, 0xc0, 0xf0, 0xec, 0x0a, 0xff, 0x13, 0x2c, 0xfc, 0xc7, 0xa2, 0xcc, 0xd1, 0x65,
+ 0x1c, 0xcf, 0xc1, 0x05, 0x4d, 0xd7, 0x1d, 0xe2, 0xba, 0xec, 0xee, 0x0b, 0x7f, 0xe2, 0x17, 0xb0,
+ 0x28, 0x77, 0xfc, 0xad, 0xe4, 0xc5, 0x77, 0xe1, 0x4a, 0x88, 0x1c, 0xe7, 0x5e, 0x72, 0x3a, 0xff,
+ 0x82, 0x5c, 0xbf, 0xd3, 0xa9, 0x48, 0x85, 0xff, 0x02, 0x85, 0x10, 0x2a, 0x81, 0x13, 0xc9, 0x69,
+ 0x54, 0xa1, 0x98, 0xe8, 0x7b, 0xda, 0x87, 0x8d, 0xb3, 0x80, 0x58, 0x92, 0xfb, 0x84, 0x44, 0xaf,
+ 0xe7, 0x0e, 0xcc, 0x0b, 0x52, 0x06, 0xaf, 0xc2, 0xe8, 0x4b, 0x12, 0x55, 0x7a, 0x55, 0xe0, 0x44,
+ 0xc8, 0x86, 0x1d, 0xdb, 0xb4, 0xb6, 0x37, 0xfc, 0x17, 0xf5, 0xf7, 0x3f, 0x17, 0x57, 0x0d, 0xd3,
+ 0x3b, 0x6a, 0xd7, 0x4a, 0x75, 0xbb, 0x59, 0x66, 0x13, 0x4a, 0xf0, 0xcf, 0xba, 0xab, 0x1f, 0x97,
+ 0xbd, 0x6e, 0x8b, 0xb8, 0xd4, 0xc1, 0xad, 0x50, 0x60, 0xfc, 0x85, 0x02, 0x58, 0xcc, 0x53, 0x7a,
+ 0x8f, 0xff, 0xbe, 0x6f, 0xa7, 0x26, 0xac, 0xa4, 0xe6, 0xc0, 0x9a, 0xb1, 0x2f, 0xb9, 0xfe, 0x6f,
+ 0x26, 0x37, 0x3c, 0xf1, 0x0d, 0x40, 0x60, 0x81, 0xf5, 0x5a, 0x5a, 0x6b, 0x6c, 0x02, 0x50, 0xe2,
+ 0x13, 0x80, 0x64, 0x92, 0x18, 0x91, 0x4c, 0x12, 0x58, 0x85, 0x45, 0x79, 0x18, 0x56, 0xce, 0x3f,
+ 0x24, 0xe5, 0x14, 0x25, 0x5c, 0x4e, 0xac, 0xe3, 0x6f, 0xb0, 0xfc, 0x48, 0x73, 0xbd, 0x6a, 0xbb,
+ 0xd6, 0x34, 0x3d, 0x8f, 0xe8, 0x7b, 0xde, 0x11, 0x71, 0x48, 0xbb, 0xb9, 0xd7, 0x21, 0x96, 0x37,
+ 0x98, 0xdd, 0x7b, 0x80, 0xd3, 0xdc, 0x59, 0x96, 0x45, 0x98, 0x20, 0xbe, 0x40, 0xec, 0x06, 0x15,
+ 0x05, 0x0f, 0x6f, 0x0d, 0xe6, 0xf7, 0x2a, 0x3b, 0x5b, 0x1b, 0x07, 0xf6, 0x2e, 0xb1, 0xec, 0x66,
+ 0x18, 0x37, 0x0b, 0x63, 0xc4, 0xa9, 0x6f, 0x6d, 0xb0, 0xa8, 0xc1, 0x0f, 0x7c, 0x08, 0x59, 0xd1,
+ 0x98, 0x45, 0xc9, 0xc2, 0x98, 0xee, 0x0b, 0x42, 0x6b, 0xfa, 0x03, 0xad, 0xc1, 0x5c, 0x40, 0x5e,
+ 0xd5, 0x76, 0x4c, 0x7a, 0xc9, 0x11, 0x9d, 0xf6, 0xfa, 0x62, 0x65, 0x36, 0x50, 0x3c, 0x8d, 0xe4,
+ 0x78, 0x13, 0xae, 0x52, 0xcc, 0x03, 0x9b, 0x46, 0x10, 0xa6, 0x5f, 0x39, 0x3e, 0xfe, 0x4e, 0x81,
+ 0xbc, 0xcc, 0x87, 0x25, 0x75, 0x0d, 0xc0, 0x3f, 0x68, 0x2a, 0xef, 0x39, 0xee, 0x4b, 0xa8, 0x8f,
+ 0xaf, 0xa6, 0x45, 0xa9, 0x96, 0xd6, 0x24, 0x8c, 0x02, 0xe3, 0x54, 0xf2, 0x44, 0x6b, 0x12, 0xb4,
+ 0x0c, 0x93, 0x81, 0xda, 0xed, 0x36, 0x6b, 0x76, 0x23, 0x77, 0x8e, 0x1a, 0x4c, 0x50, 0x59, 0x95,
+ 0x8a, 0x7c, 0x22, 0x05, 0x26, 0x3a, 0xa9, 0x9b, 0x4d, 0xad, 0xe1, 0xe6, 0x46, 0x69, 0x7b, 0xa7,
+ 0xa8, 0x74, 0x97, 0x09, 0xfd, 0x0e, 0xf3, 0x59, 0xa6, 0xd7, 0x74, 0x08, 0x59, 0xd1, 0xb8, 0xd7,
+ 0xe1, 0xfe, 0xe7, 0xf1, 0x61, 0x1d, 0x7e, 0x0c, 0x85, 0x5d, 0xd2, 0x20, 0x86, 0xe6, 0x91, 0x87,
+ 0xa4, 0xeb, 0x6e, 0x77, 0x9f, 0x07, 0xe7, 0xd8, 0x76, 0xc2, 0x94, 0xd6, 0x60, 0xae, 0x13, 0xca,
+ 0x54, 0x91, 0x76, 0xb3, 0x91, 0xe2, 0x3e, 0xe3, 0x5f, 0x1b, 0x8a, 0x89, 0x70, 0x1c, 0xf9, 0xbc,
+ 0xa3, 0x18, 0x12, 0x10, 0xef, 0x88, 0x61, 0xa0, 0x4d, 0xc8, 0xda, 0x8e, 0x7f, 0xcf, 0x7b, 0x8e,
+ 0x10, 0x33, 0x78, 0x1a, 0xf3, 0xbc, 0x2e, 0x0c, 0xfb, 0x04, 0x56, 0xc4, 0xb0, 0x21, 0xef, 0x83,
+ 0x37, 0x58, 0x58, 0xca, 0x2d, 0x98, 0x21, 0x4c, 0xa1, 0x06, 0xaf, 0x33, 0x16, 0x7e, 0x9a, 0x08,
+ 0xf6, 0xf8, 0x2b, 0x05, 0xae, 0xa7, 0x03, 0xb2, 0x62, 0x3e, 0xa4, 0x39, 0xa7, 0x29, 0xec, 0x39,
+ 0x2c, 0x8b, 0x79, 0x3c, 0xe5, 0x8c, 0xc2, 0xb2, 0x92, 0x70, 0x95, 0x64, 0xdc, 0x4f, 0x01, 0xa7,
+ 0xe1, 0x9e, 0xa6, 0x3a, 0x49, 0x73, 0x47, 0xa4, 0xcd, 0xbd, 0xe4, 0x53, 0xbf, 0x17, 0x3b, 0x7c,
+ 0x5b, 0xbe, 0xf0, 0x49, 0xce, 0x8b, 0x59, 0x12, 0xff, 0x84, 0x29, 0x9d, 0xc9, 0xd5, 0x63, 0xd2,
+ 0x0d, 0x6f, 0xd5, 0x05, 0xfe, 0x56, 0x7d, 0xec, 0x1a, 0x82, 0xef, 0xa4, 0xce, 0xfd, 0xc2, 0xfb,
+ 0x70, 0x8d, 0x5e, 0xbb, 0x44, 0xaf, 0x12, 0x4b, 0x3f, 0xb0, 0xc3, 0x67, 0xe9, 0x72, 0x6b, 0xa4,
+ 0x4b, 0x2c, 0x9d, 0xc4, 0x8b, 0x9c, 0x0a, 0xa4, 0x61, 0xd3, 0x8e, 0xa0, 0x90, 0x84, 0x13, 0xbd,
+ 0xcd, 0xe6, 0x7c, 0x17, 0xd5, 0xb3, 0xd5, 0xb0, 0x68, 0xe9, 0x14, 0x21, 0xfa, 0x57, 0x66, 0x5c,
+ 0x11, 0x0f, 0xbf, 0x51, 0xfc, 0x29, 0xa5, 0x76, 0x06, 0x49, 0xc7, 0xa6, 0xe3, 0x91, 0x53, 0x4f,
+ 0xc7, 0x3f, 0x28, 0xb0, 0x94, 0x9c, 0xd2, 0xd9, 0xd6, 0x7f, 0x66, 0xc3, 0xf3, 0xd6, 0xc9, 0x3c,
+ 0x8c, 0xfd, 0xdb, 0x37, 0x45, 0xf7, 0xe1, 0x7c, 0xf0, 0x2a, 0x40, 0x57, 0xfb, 0xbf, 0x89, 0xb0,
+ 0x82, 0xf3, 0x79, 0x99, 0x2a, 0x80, 0xc5, 0x19, 0xf4, 0x0c, 0x26, 0xb8, 0x89, 0x18, 0x15, 0x92,
+ 0x46, 0x65, 0x06, 0x56, 0x4c, 0xd4, 0x47, 0x88, 0xff, 0x83, 0xb9, 0xbe, 0x8f, 0x27, 0xe8, 0x3a,
+ 0xef, 0x97, 0xf4, 0x6d, 0x65, 0x18, 0xf4, 0x5d, 0xb8, 0xc0, 0xc6, 0x0d, 0x94, 0x97, 0xcd, 0xd3,
+ 0x0c, 0x69, 0x41, 0xaa, 0x8b, 0x50, 0x0e, 0x61, 0x5a, 0x9c, 0xc1, 0xd0, 0x72, 0xca, 0x40, 0xcc,
+ 0x30, 0x71, 0x9a, 0x49, 0x04, 0x5d, 0x85, 0x49, 0x7e, 0x33, 0x41, 0x49, 0x35, 0x45, 0xcf, 0x67,
+ 0x29, 0xd9, 0x20, 0x02, 0x7d, 0x00, 0x17, 0xc3, 0xfd, 0x02, 0xc9, 0x4a, 0x8b, 0xc0, 0x16, 0xe5,
+ 0x4a, 0xee, 0xe1, 0xcc, 0xc4, 0x36, 0x04, 0x94, 0x52, 0x56, 0x04, 0xbb, 0x92, 0x6a, 0x13, 0xa1,
+ 0x7f, 0x02, 0xb9, 0xa4, 0x6f, 0x23, 0x68, 0x6d, 0x88, 0xef, 0x1f, 0x51, 0xbc, 0x3f, 0x0c, 0x67,
+ 0x1c, 0x05, 0x3e, 0x86, 0xac, 0x6c, 0x84, 0x45, 0xb7, 0x06, 0x8c, 0xa9, 0x51, 0xc0, 0xd5, 0xc1,
+ 0x86, 0x51, 0xb0, 0xcf, 0x15, 0x58, 0x48, 0x59, 0x03, 0x50, 0x69, 0xb8, 0x51, 0x3f, 0x8a, 0x5d,
+ 0x1e, 0xda, 0x9e, 0xaf, 0x57, 0xb6, 0x06, 0x8b, 0xf5, 0xa6, 0x6c, 0xd8, 0x62, 0xbd, 0x69, 0x1b,
+ 0x35, 0xce, 0x20, 0x15, 0x66, 0xe3, 0x4b, 0x2e, 0x5a, 0x91, 0xf9, 0xc7, 0xc9, 0x78, 0x3d, 0xdd,
+ 0x28, 0x0a, 0xe0, 0xf5, 0x56, 0xef, 0x38, 0x39, 0xef, 0xc8, 0x20, 0x12, 0x48, 0xba, 0x36, 0x94,
+ 0x6d, 0x14, 0xf5, 0x33, 0xc8, 0x27, 0xaf, 0x15, 0x68, 0x5d, 0xbc, 0xb0, 0x06, 0x6c, 0x2f, 0xf9,
+ 0xd2, 0xb0, 0xe6, 0xfc, 0xc5, 0xcb, 0x2d, 0xd2, 0xe2, 0xc5, 0xdb, 0xbf, 0x77, 0xe7, 0x8b, 0x89,
+ 0x7a, 0xfe, 0xe6, 0xe1, 0x77, 0x16, 0xf1, 0xe6, 0x91, 0xac, 0x3e, 0xe2, 0xcd, 0x23, 0x5b, 0x77,
+ 0x70, 0x06, 0x11, 0x40, 0xfd, 0x9b, 0x07, 0xba, 0xc1, 0x7b, 0x26, 0x6e, 0x33, 0xf9, 0x9b, 0x83,
+ 0xcc, 0xf8, 0xdc, 0x79, 0xbd, 0x98, 0xbb, 0x64, 0xa9, 0x10, 0x73, 0x97, 0x2d, 0x12, 0x38, 0x83,
+ 0x5e, 0xc1, 0x65, 0xf9, 0x6c, 0x83, 0x6e, 0xf7, 0x75, 0x33, 0x69, 0x24, 0xc9, 0xdf, 0x19, 0xc6,
+ 0x94, 0xbf, 0x01, 0x93, 0x06, 0x0a, 0x14, 0xe3, 0x67, 0xea, 0x24, 0x24, 0xde, 0x80, 0x83, 0x66,
+ 0x94, 0xe0, 0x0c, 0x25, 0x2c, 0x29, 0xe2, 0x19, 0x4a, 0x5f, 0x8c, 0xc4, 0x33, 0x34, 0x60, 0xeb,
+ 0xc1, 0x19, 0xf4, 0xa5, 0x02, 0x8b, 0x69, 0x3b, 0x05, 0x2a, 0x27, 0xe3, 0x49, 0xd7, 0x99, 0xfc,
+ 0xc6, 0xf0, 0x0e, 0xfc, 0x49, 0x4e, 0x1e, 0xfc, 0xc5, 0x93, 0x3c, 0x70, 0xf1, 0x10, 0x4f, 0xf2,
+ 0xe0, 0x7d, 0x22, 0xe4, 0x6e, 0xcf, 0x2e, 0xce, 0xdd, 0xbe, 0xad, 0x20, 0xce, 0xdd, 0xfe, 0xfd,
+ 0x00, 0x67, 0xb6, 0x2b, 0x6f, 0x4f, 0x0a, 0xca, 0xbb, 0x93, 0x82, 0xf2, 0xcb, 0x49, 0x41, 0x79,
+ 0xf3, 0xbe, 0x90, 0x79, 0xf7, 0xbe, 0x90, 0xf9, 0xf1, 0x7d, 0x21, 0xf3, 0xdf, 0x7b, 0xdc, 0x97,
+ 0xb3, 0x16, 0x31, 0x8c, 0xee, 0xc7, 0x9d, 0xf0, 0x4f, 0x6d, 0xeb, 0x35, 0xc7, 0xd4, 0x0d, 0x52,
+ 0x6e, 0xda, 0x7a, 0xbb, 0x41, 0xca, 0xaf, 0x43, 0x79, 0xf0, 0x3d, 0xad, 0x76, 0x9e, 0xfe, 0xc9,
+ 0xed, 0xee, 0xaf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xee, 0xe5, 0x39, 0x0f, 0x63, 0x1c, 0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// QueryClient is the client API for Query service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type QueryClient interface {
+ // Module parameters query
+ Params(ctx context.Context, in *ParamsRequest, opts ...grpc.CallOption) (*ParamsResponse, error)
+ // get info on individual outgoing data
+ SignerSetTx(ctx context.Context, in *SignerSetTxRequest, opts ...grpc.CallOption) (*SignerSetTxResponse, error)
+ LatestSignerSetTx(ctx context.Context, in *LatestSignerSetTxRequest, opts ...grpc.CallOption) (*SignerSetTxResponse, error)
+ BatchTx(ctx context.Context, in *BatchTxRequest, opts ...grpc.CallOption) (*BatchTxResponse, error)
+ ContractCallTx(ctx context.Context, in *ContractCallTxRequest, opts ...grpc.CallOption) (*ContractCallTxResponse, error)
+ // get collections of outgoing traffic from the bridge
+ SignerSetTxs(ctx context.Context, in *SignerSetTxsRequest, opts ...grpc.CallOption) (*SignerSetTxsResponse, error)
+ BatchTxs(ctx context.Context, in *BatchTxsRequest, opts ...grpc.CallOption) (*BatchTxsResponse, error)
+ ContractCallTxs(ctx context.Context, in *ContractCallTxsRequest, opts ...grpc.CallOption) (*ContractCallTxsResponse, error)
+ // TODO: can/should we group these into one endpoint?
+ SignerSetTxConfirmations(ctx context.Context, in *SignerSetTxConfirmationsRequest, opts ...grpc.CallOption) (*SignerSetTxConfirmationsResponse, error)
+ BatchTxConfirmations(ctx context.Context, in *BatchTxConfirmationsRequest, opts ...grpc.CallOption) (*BatchTxConfirmationsResponse, error)
+ ContractCallTxConfirmations(ctx context.Context, in *ContractCallTxConfirmationsRequest, opts ...grpc.CallOption) (*ContractCallTxConfirmationsResponse, error)
+ // pending ethereum signature queries for orchestrators to figure out which
+ // signatures they are missing
+ // TODO: can/should we group this into one endpoint?
+ UnsignedSignerSetTxs(ctx context.Context, in *UnsignedSignerSetTxsRequest, opts ...grpc.CallOption) (*UnsignedSignerSetTxsResponse, error)
+ UnsignedBatchTxs(ctx context.Context, in *UnsignedBatchTxsRequest, opts ...grpc.CallOption) (*UnsignedBatchTxsResponse, error)
+ UnsignedContractCallTxs(ctx context.Context, in *UnsignedContractCallTxsRequest, opts ...grpc.CallOption) (*UnsignedContractCallTxsResponse, error)
+ LastSubmittedEthereumEvent(ctx context.Context, in *LastSubmittedEthereumEventRequest, opts ...grpc.CallOption) (*LastSubmittedEthereumEventResponse, error)
+ // Queries the fees for all pending batches, results are returned in sdk.Coin
+ // (fee_amount_int)(contract_address) style
+ BatchTxFees(ctx context.Context, in *BatchTxFeesRequest, opts ...grpc.CallOption) (*BatchTxFeesResponse, error)
+ // Query for info about denoms tracked by gravity
+ ERC20ToDenom(ctx context.Context, in *ERC20ToDenomRequest, opts ...grpc.CallOption) (*ERC20ToDenomResponse, error)
+ // DenomToERC20Params implements a query that allows ERC-20 parameter information
+ // to be retrieved by a Cosmos base denomination.
+ DenomToERC20Params(ctx context.Context, in *DenomToERC20ParamsRequest, opts ...grpc.CallOption) (*DenomToERC20ParamsResponse, error)
+ // Query for info about denoms tracked by gravity
+ DenomToERC20(ctx context.Context, in *DenomToERC20Request, opts ...grpc.CallOption) (*DenomToERC20Response, error)
+ // Query for batch send to ethereums
+ BatchedSendToEthereums(ctx context.Context, in *BatchedSendToEthereumsRequest, opts ...grpc.CallOption) (*BatchedSendToEthereumsResponse, error)
+ // Query for unbatched send to ethereums
+ UnbatchedSendToEthereums(ctx context.Context, in *UnbatchedSendToEthereumsRequest, opts ...grpc.CallOption) (*UnbatchedSendToEthereumsResponse, error)
+ // delegate keys
+ DelegateKeysByValidator(ctx context.Context, in *DelegateKeysByValidatorRequest, opts ...grpc.CallOption) (*DelegateKeysByValidatorResponse, error)
+ DelegateKeysByEthereumSigner(ctx context.Context, in *DelegateKeysByEthereumSignerRequest, opts ...grpc.CallOption) (*DelegateKeysByEthereumSignerResponse, error)
+ DelegateKeysByOrchestrator(ctx context.Context, in *DelegateKeysByOrchestratorRequest, opts ...grpc.CallOption) (*DelegateKeysByOrchestratorResponse, error)
+ DelegateKeys(ctx context.Context, in *DelegateKeysRequest, opts ...grpc.CallOption) (*DelegateKeysResponse, error)
+}
+
+type queryClient struct {
+ cc grpc1.ClientConn
+}
+
+func NewQueryClient(cc grpc1.ClientConn) QueryClient {
+ return &queryClient{cc}
+}
+
+func (c *queryClient) Params(ctx context.Context, in *ParamsRequest, opts ...grpc.CallOption) (*ParamsResponse, error) {
+ out := new(ParamsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/Params", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) SignerSetTx(ctx context.Context, in *SignerSetTxRequest, opts ...grpc.CallOption) (*SignerSetTxResponse, error) {
+ out := new(SignerSetTxResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/SignerSetTx", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) LatestSignerSetTx(ctx context.Context, in *LatestSignerSetTxRequest, opts ...grpc.CallOption) (*SignerSetTxResponse, error) {
+ out := new(SignerSetTxResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/LatestSignerSetTx", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) BatchTx(ctx context.Context, in *BatchTxRequest, opts ...grpc.CallOption) (*BatchTxResponse, error) {
+ out := new(BatchTxResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/BatchTx", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) ContractCallTx(ctx context.Context, in *ContractCallTxRequest, opts ...grpc.CallOption) (*ContractCallTxResponse, error) {
+ out := new(ContractCallTxResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/ContractCallTx", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) SignerSetTxs(ctx context.Context, in *SignerSetTxsRequest, opts ...grpc.CallOption) (*SignerSetTxsResponse, error) {
+ out := new(SignerSetTxsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/SignerSetTxs", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) BatchTxs(ctx context.Context, in *BatchTxsRequest, opts ...grpc.CallOption) (*BatchTxsResponse, error) {
+ out := new(BatchTxsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/BatchTxs", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) ContractCallTxs(ctx context.Context, in *ContractCallTxsRequest, opts ...grpc.CallOption) (*ContractCallTxsResponse, error) {
+ out := new(ContractCallTxsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/ContractCallTxs", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) SignerSetTxConfirmations(ctx context.Context, in *SignerSetTxConfirmationsRequest, opts ...grpc.CallOption) (*SignerSetTxConfirmationsResponse, error) {
+ out := new(SignerSetTxConfirmationsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/SignerSetTxConfirmations", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) BatchTxConfirmations(ctx context.Context, in *BatchTxConfirmationsRequest, opts ...grpc.CallOption) (*BatchTxConfirmationsResponse, error) {
+ out := new(BatchTxConfirmationsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/BatchTxConfirmations", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) ContractCallTxConfirmations(ctx context.Context, in *ContractCallTxConfirmationsRequest, opts ...grpc.CallOption) (*ContractCallTxConfirmationsResponse, error) {
+ out := new(ContractCallTxConfirmationsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/ContractCallTxConfirmations", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) UnsignedSignerSetTxs(ctx context.Context, in *UnsignedSignerSetTxsRequest, opts ...grpc.CallOption) (*UnsignedSignerSetTxsResponse, error) {
+ out := new(UnsignedSignerSetTxsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/UnsignedSignerSetTxs", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) UnsignedBatchTxs(ctx context.Context, in *UnsignedBatchTxsRequest, opts ...grpc.CallOption) (*UnsignedBatchTxsResponse, error) {
+ out := new(UnsignedBatchTxsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/UnsignedBatchTxs", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) UnsignedContractCallTxs(ctx context.Context, in *UnsignedContractCallTxsRequest, opts ...grpc.CallOption) (*UnsignedContractCallTxsResponse, error) {
+ out := new(UnsignedContractCallTxsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/UnsignedContractCallTxs", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) LastSubmittedEthereumEvent(ctx context.Context, in *LastSubmittedEthereumEventRequest, opts ...grpc.CallOption) (*LastSubmittedEthereumEventResponse, error) {
+ out := new(LastSubmittedEthereumEventResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/LastSubmittedEthereumEvent", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) BatchTxFees(ctx context.Context, in *BatchTxFeesRequest, opts ...grpc.CallOption) (*BatchTxFeesResponse, error) {
+ out := new(BatchTxFeesResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/BatchTxFees", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) ERC20ToDenom(ctx context.Context, in *ERC20ToDenomRequest, opts ...grpc.CallOption) (*ERC20ToDenomResponse, error) {
+ out := new(ERC20ToDenomResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/ERC20ToDenom", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) DenomToERC20Params(ctx context.Context, in *DenomToERC20ParamsRequest, opts ...grpc.CallOption) (*DenomToERC20ParamsResponse, error) {
+ out := new(DenomToERC20ParamsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/DenomToERC20Params", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) DenomToERC20(ctx context.Context, in *DenomToERC20Request, opts ...grpc.CallOption) (*DenomToERC20Response, error) {
+ out := new(DenomToERC20Response)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/DenomToERC20", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) BatchedSendToEthereums(ctx context.Context, in *BatchedSendToEthereumsRequest, opts ...grpc.CallOption) (*BatchedSendToEthereumsResponse, error) {
+ out := new(BatchedSendToEthereumsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/BatchedSendToEthereums", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) UnbatchedSendToEthereums(ctx context.Context, in *UnbatchedSendToEthereumsRequest, opts ...grpc.CallOption) (*UnbatchedSendToEthereumsResponse, error) {
+ out := new(UnbatchedSendToEthereumsResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/UnbatchedSendToEthereums", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) DelegateKeysByValidator(ctx context.Context, in *DelegateKeysByValidatorRequest, opts ...grpc.CallOption) (*DelegateKeysByValidatorResponse, error) {
+ out := new(DelegateKeysByValidatorResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/DelegateKeysByValidator", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) DelegateKeysByEthereumSigner(ctx context.Context, in *DelegateKeysByEthereumSignerRequest, opts ...grpc.CallOption) (*DelegateKeysByEthereumSignerResponse, error) {
+ out := new(DelegateKeysByEthereumSignerResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/DelegateKeysByEthereumSigner", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) DelegateKeysByOrchestrator(ctx context.Context, in *DelegateKeysByOrchestratorRequest, opts ...grpc.CallOption) (*DelegateKeysByOrchestratorResponse, error) {
+ out := new(DelegateKeysByOrchestratorResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/DelegateKeysByOrchestrator", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *queryClient) DelegateKeys(ctx context.Context, in *DelegateKeysRequest, opts ...grpc.CallOption) (*DelegateKeysResponse, error) {
+ out := new(DelegateKeysResponse)
+ err := c.cc.Invoke(ctx, "/gravity.v1.Query/DelegateKeys", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// QueryServer is the server API for Query service.
+type QueryServer interface {
+ // Module parameters query
+ Params(context.Context, *ParamsRequest) (*ParamsResponse, error)
+ // get info on individual outgoing data
+ SignerSetTx(context.Context, *SignerSetTxRequest) (*SignerSetTxResponse, error)
+ LatestSignerSetTx(context.Context, *LatestSignerSetTxRequest) (*SignerSetTxResponse, error)
+ BatchTx(context.Context, *BatchTxRequest) (*BatchTxResponse, error)
+ ContractCallTx(context.Context, *ContractCallTxRequest) (*ContractCallTxResponse, error)
+ // get collections of outgoing traffic from the bridge
+ SignerSetTxs(context.Context, *SignerSetTxsRequest) (*SignerSetTxsResponse, error)
+ BatchTxs(context.Context, *BatchTxsRequest) (*BatchTxsResponse, error)
+ ContractCallTxs(context.Context, *ContractCallTxsRequest) (*ContractCallTxsResponse, error)
+ // TODO: can/should we group these into one endpoint?
+ SignerSetTxConfirmations(context.Context, *SignerSetTxConfirmationsRequest) (*SignerSetTxConfirmationsResponse, error)
+ BatchTxConfirmations(context.Context, *BatchTxConfirmationsRequest) (*BatchTxConfirmationsResponse, error)
+ ContractCallTxConfirmations(context.Context, *ContractCallTxConfirmationsRequest) (*ContractCallTxConfirmationsResponse, error)
+ // pending ethereum signature queries for orchestrators to figure out which
+ // signatures they are missing
+ // TODO: can/should we group this into one endpoint?
+ UnsignedSignerSetTxs(context.Context, *UnsignedSignerSetTxsRequest) (*UnsignedSignerSetTxsResponse, error)
+ UnsignedBatchTxs(context.Context, *UnsignedBatchTxsRequest) (*UnsignedBatchTxsResponse, error)
+ UnsignedContractCallTxs(context.Context, *UnsignedContractCallTxsRequest) (*UnsignedContractCallTxsResponse, error)
+ LastSubmittedEthereumEvent(context.Context, *LastSubmittedEthereumEventRequest) (*LastSubmittedEthereumEventResponse, error)
+ // Queries the fees for all pending batches, results are returned in sdk.Coin
+ // (fee_amount_int)(contract_address) style
+ BatchTxFees(context.Context, *BatchTxFeesRequest) (*BatchTxFeesResponse, error)
+ // Query for info about denoms tracked by gravity
+ ERC20ToDenom(context.Context, *ERC20ToDenomRequest) (*ERC20ToDenomResponse, error)
+ // DenomToERC20Params implements a query that allows ERC-20 parameter information
+ // to be retrieved by a Cosmos base denomination.
+ DenomToERC20Params(context.Context, *DenomToERC20ParamsRequest) (*DenomToERC20ParamsResponse, error)
+ // Query for info about denoms tracked by gravity
+ DenomToERC20(context.Context, *DenomToERC20Request) (*DenomToERC20Response, error)
+ // Query for batch send to ethereums
+ BatchedSendToEthereums(context.Context, *BatchedSendToEthereumsRequest) (*BatchedSendToEthereumsResponse, error)
+ // Query for unbatched send to ethereums
+ UnbatchedSendToEthereums(context.Context, *UnbatchedSendToEthereumsRequest) (*UnbatchedSendToEthereumsResponse, error)
+ // delegate keys
+ DelegateKeysByValidator(context.Context, *DelegateKeysByValidatorRequest) (*DelegateKeysByValidatorResponse, error)
+ DelegateKeysByEthereumSigner(context.Context, *DelegateKeysByEthereumSignerRequest) (*DelegateKeysByEthereumSignerResponse, error)
+ DelegateKeysByOrchestrator(context.Context, *DelegateKeysByOrchestratorRequest) (*DelegateKeysByOrchestratorResponse, error)
+ DelegateKeys(context.Context, *DelegateKeysRequest) (*DelegateKeysResponse, error)
+}
+
+// UnimplementedQueryServer can be embedded to have forward compatible implementations.
+type UnimplementedQueryServer struct {
+}
+
+func (*UnimplementedQueryServer) Params(ctx context.Context, req *ParamsRequest) (*ParamsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method Params not implemented")
+}
+func (*UnimplementedQueryServer) SignerSetTx(ctx context.Context, req *SignerSetTxRequest) (*SignerSetTxResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SignerSetTx not implemented")
+}
+func (*UnimplementedQueryServer) LatestSignerSetTx(ctx context.Context, req *LatestSignerSetTxRequest) (*SignerSetTxResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method LatestSignerSetTx not implemented")
+}
+func (*UnimplementedQueryServer) BatchTx(ctx context.Context, req *BatchTxRequest) (*BatchTxResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method BatchTx not implemented")
+}
+func (*UnimplementedQueryServer) ContractCallTx(ctx context.Context, req *ContractCallTxRequest) (*ContractCallTxResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method ContractCallTx not implemented")
+}
+func (*UnimplementedQueryServer) SignerSetTxs(ctx context.Context, req *SignerSetTxsRequest) (*SignerSetTxsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SignerSetTxs not implemented")
+}
+func (*UnimplementedQueryServer) BatchTxs(ctx context.Context, req *BatchTxsRequest) (*BatchTxsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method BatchTxs not implemented")
+}
+func (*UnimplementedQueryServer) ContractCallTxs(ctx context.Context, req *ContractCallTxsRequest) (*ContractCallTxsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method ContractCallTxs not implemented")
+}
+func (*UnimplementedQueryServer) SignerSetTxConfirmations(ctx context.Context, req *SignerSetTxConfirmationsRequest) (*SignerSetTxConfirmationsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SignerSetTxConfirmations not implemented")
+}
+func (*UnimplementedQueryServer) BatchTxConfirmations(ctx context.Context, req *BatchTxConfirmationsRequest) (*BatchTxConfirmationsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method BatchTxConfirmations not implemented")
+}
+func (*UnimplementedQueryServer) ContractCallTxConfirmations(ctx context.Context, req *ContractCallTxConfirmationsRequest) (*ContractCallTxConfirmationsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method ContractCallTxConfirmations not implemented")
+}
+func (*UnimplementedQueryServer) UnsignedSignerSetTxs(ctx context.Context, req *UnsignedSignerSetTxsRequest) (*UnsignedSignerSetTxsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method UnsignedSignerSetTxs not implemented")
+}
+func (*UnimplementedQueryServer) UnsignedBatchTxs(ctx context.Context, req *UnsignedBatchTxsRequest) (*UnsignedBatchTxsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method UnsignedBatchTxs not implemented")
+}
+func (*UnimplementedQueryServer) UnsignedContractCallTxs(ctx context.Context, req *UnsignedContractCallTxsRequest) (*UnsignedContractCallTxsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method UnsignedContractCallTxs not implemented")
+}
+func (*UnimplementedQueryServer) LastSubmittedEthereumEvent(ctx context.Context, req *LastSubmittedEthereumEventRequest) (*LastSubmittedEthereumEventResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method LastSubmittedEthereumEvent not implemented")
+}
+func (*UnimplementedQueryServer) BatchTxFees(ctx context.Context, req *BatchTxFeesRequest) (*BatchTxFeesResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method BatchTxFees not implemented")
+}
+func (*UnimplementedQueryServer) ERC20ToDenom(ctx context.Context, req *ERC20ToDenomRequest) (*ERC20ToDenomResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method ERC20ToDenom not implemented")
+}
+func (*UnimplementedQueryServer) DenomToERC20Params(ctx context.Context, req *DenomToERC20ParamsRequest) (*DenomToERC20ParamsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method DenomToERC20Params not implemented")
+}
+func (*UnimplementedQueryServer) DenomToERC20(ctx context.Context, req *DenomToERC20Request) (*DenomToERC20Response, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method DenomToERC20 not implemented")
+}
+func (*UnimplementedQueryServer) BatchedSendToEthereums(ctx context.Context, req *BatchedSendToEthereumsRequest) (*BatchedSendToEthereumsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method BatchedSendToEthereums not implemented")
+}
+func (*UnimplementedQueryServer) UnbatchedSendToEthereums(ctx context.Context, req *UnbatchedSendToEthereumsRequest) (*UnbatchedSendToEthereumsResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method UnbatchedSendToEthereums not implemented")
+}
+func (*UnimplementedQueryServer) DelegateKeysByValidator(ctx context.Context, req *DelegateKeysByValidatorRequest) (*DelegateKeysByValidatorResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method DelegateKeysByValidator not implemented")
+}
+func (*UnimplementedQueryServer) DelegateKeysByEthereumSigner(ctx context.Context, req *DelegateKeysByEthereumSignerRequest) (*DelegateKeysByEthereumSignerResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method DelegateKeysByEthereumSigner not implemented")
+}
+func (*UnimplementedQueryServer) DelegateKeysByOrchestrator(ctx context.Context, req *DelegateKeysByOrchestratorRequest) (*DelegateKeysByOrchestratorResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method DelegateKeysByOrchestrator not implemented")
+}
+func (*UnimplementedQueryServer) DelegateKeys(ctx context.Context, req *DelegateKeysRequest) (*DelegateKeysResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method DelegateKeys not implemented")
+}
+
+func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
+ s.RegisterService(&_Query_serviceDesc, srv)
+}
+
+func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ParamsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).Params(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/Params",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).Params(ctx, req.(*ParamsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_SignerSetTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SignerSetTxRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).SignerSetTx(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/SignerSetTx",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).SignerSetTx(ctx, req.(*SignerSetTxRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_LatestSignerSetTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(LatestSignerSetTxRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).LatestSignerSetTx(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/LatestSignerSetTx",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).LatestSignerSetTx(ctx, req.(*LatestSignerSetTxRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_BatchTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(BatchTxRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).BatchTx(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/BatchTx",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).BatchTx(ctx, req.(*BatchTxRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_ContractCallTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ContractCallTxRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).ContractCallTx(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/ContractCallTx",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).ContractCallTx(ctx, req.(*ContractCallTxRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_SignerSetTxs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SignerSetTxsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).SignerSetTxs(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/SignerSetTxs",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).SignerSetTxs(ctx, req.(*SignerSetTxsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_BatchTxs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(BatchTxsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).BatchTxs(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/BatchTxs",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).BatchTxs(ctx, req.(*BatchTxsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_ContractCallTxs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ContractCallTxsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).ContractCallTxs(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/ContractCallTxs",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).ContractCallTxs(ctx, req.(*ContractCallTxsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_SignerSetTxConfirmations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SignerSetTxConfirmationsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).SignerSetTxConfirmations(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/SignerSetTxConfirmations",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).SignerSetTxConfirmations(ctx, req.(*SignerSetTxConfirmationsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_BatchTxConfirmations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(BatchTxConfirmationsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).BatchTxConfirmations(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/BatchTxConfirmations",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).BatchTxConfirmations(ctx, req.(*BatchTxConfirmationsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_ContractCallTxConfirmations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ContractCallTxConfirmationsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).ContractCallTxConfirmations(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/ContractCallTxConfirmations",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).ContractCallTxConfirmations(ctx, req.(*ContractCallTxConfirmationsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_UnsignedSignerSetTxs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(UnsignedSignerSetTxsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).UnsignedSignerSetTxs(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/UnsignedSignerSetTxs",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).UnsignedSignerSetTxs(ctx, req.(*UnsignedSignerSetTxsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_UnsignedBatchTxs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(UnsignedBatchTxsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).UnsignedBatchTxs(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/UnsignedBatchTxs",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).UnsignedBatchTxs(ctx, req.(*UnsignedBatchTxsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_UnsignedContractCallTxs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(UnsignedContractCallTxsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).UnsignedContractCallTxs(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/UnsignedContractCallTxs",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).UnsignedContractCallTxs(ctx, req.(*UnsignedContractCallTxsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_LastSubmittedEthereumEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(LastSubmittedEthereumEventRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).LastSubmittedEthereumEvent(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/LastSubmittedEthereumEvent",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).LastSubmittedEthereumEvent(ctx, req.(*LastSubmittedEthereumEventRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_BatchTxFees_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(BatchTxFeesRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).BatchTxFees(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/BatchTxFees",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).BatchTxFees(ctx, req.(*BatchTxFeesRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_ERC20ToDenom_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ERC20ToDenomRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).ERC20ToDenom(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/ERC20ToDenom",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).ERC20ToDenom(ctx, req.(*ERC20ToDenomRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_DenomToERC20Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DenomToERC20ParamsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).DenomToERC20Params(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/DenomToERC20Params",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).DenomToERC20Params(ctx, req.(*DenomToERC20ParamsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_DenomToERC20_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DenomToERC20Request)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).DenomToERC20(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/DenomToERC20",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).DenomToERC20(ctx, req.(*DenomToERC20Request))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_BatchedSendToEthereums_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(BatchedSendToEthereumsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).BatchedSendToEthereums(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/BatchedSendToEthereums",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).BatchedSendToEthereums(ctx, req.(*BatchedSendToEthereumsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_UnbatchedSendToEthereums_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(UnbatchedSendToEthereumsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).UnbatchedSendToEthereums(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/UnbatchedSendToEthereums",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).UnbatchedSendToEthereums(ctx, req.(*UnbatchedSendToEthereumsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_DelegateKeysByValidator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DelegateKeysByValidatorRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).DelegateKeysByValidator(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/DelegateKeysByValidator",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).DelegateKeysByValidator(ctx, req.(*DelegateKeysByValidatorRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_DelegateKeysByEthereumSigner_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DelegateKeysByEthereumSignerRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).DelegateKeysByEthereumSigner(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/DelegateKeysByEthereumSigner",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).DelegateKeysByEthereumSigner(ctx, req.(*DelegateKeysByEthereumSignerRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_DelegateKeysByOrchestrator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DelegateKeysByOrchestratorRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).DelegateKeysByOrchestrator(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/DelegateKeysByOrchestrator",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).DelegateKeysByOrchestrator(ctx, req.(*DelegateKeysByOrchestratorRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Query_DelegateKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DelegateKeysRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).DelegateKeys(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gravity.v1.Query/DelegateKeys",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).DelegateKeys(ctx, req.(*DelegateKeysRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _Query_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "gravity.v1.Query",
+ HandlerType: (*QueryServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "Params",
+ Handler: _Query_Params_Handler,
+ },
+ {
+ MethodName: "SignerSetTx",
+ Handler: _Query_SignerSetTx_Handler,
+ },
+ {
+ MethodName: "LatestSignerSetTx",
+ Handler: _Query_LatestSignerSetTx_Handler,
+ },
+ {
+ MethodName: "BatchTx",
+ Handler: _Query_BatchTx_Handler,
+ },
+ {
+ MethodName: "ContractCallTx",
+ Handler: _Query_ContractCallTx_Handler,
+ },
+ {
+ MethodName: "SignerSetTxs",
+ Handler: _Query_SignerSetTxs_Handler,
+ },
+ {
+ MethodName: "BatchTxs",
+ Handler: _Query_BatchTxs_Handler,
+ },
+ {
+ MethodName: "ContractCallTxs",
+ Handler: _Query_ContractCallTxs_Handler,
+ },
+ {
+ MethodName: "SignerSetTxConfirmations",
+ Handler: _Query_SignerSetTxConfirmations_Handler,
+ },
+ {
+ MethodName: "BatchTxConfirmations",
+ Handler: _Query_BatchTxConfirmations_Handler,
+ },
+ {
+ MethodName: "ContractCallTxConfirmations",
+ Handler: _Query_ContractCallTxConfirmations_Handler,
+ },
+ {
+ MethodName: "UnsignedSignerSetTxs",
+ Handler: _Query_UnsignedSignerSetTxs_Handler,
+ },
+ {
+ MethodName: "UnsignedBatchTxs",
+ Handler: _Query_UnsignedBatchTxs_Handler,
+ },
+ {
+ MethodName: "UnsignedContractCallTxs",
+ Handler: _Query_UnsignedContractCallTxs_Handler,
+ },
+ {
+ MethodName: "LastSubmittedEthereumEvent",
+ Handler: _Query_LastSubmittedEthereumEvent_Handler,
+ },
+ {
+ MethodName: "BatchTxFees",
+ Handler: _Query_BatchTxFees_Handler,
+ },
+ {
+ MethodName: "ERC20ToDenom",
+ Handler: _Query_ERC20ToDenom_Handler,
+ },
+ {
+ MethodName: "DenomToERC20Params",
+ Handler: _Query_DenomToERC20Params_Handler,
+ },
+ {
+ MethodName: "DenomToERC20",
+ Handler: _Query_DenomToERC20_Handler,
+ },
+ {
+ MethodName: "BatchedSendToEthereums",
+ Handler: _Query_BatchedSendToEthereums_Handler,
+ },
+ {
+ MethodName: "UnbatchedSendToEthereums",
+ Handler: _Query_UnbatchedSendToEthereums_Handler,
+ },
+ {
+ MethodName: "DelegateKeysByValidator",
+ Handler: _Query_DelegateKeysByValidator_Handler,
+ },
+ {
+ MethodName: "DelegateKeysByEthereumSigner",
+ Handler: _Query_DelegateKeysByEthereumSigner_Handler,
+ },
+ {
+ MethodName: "DelegateKeysByOrchestrator",
+ Handler: _Query_DelegateKeysByOrchestrator_Handler,
+ },
+ {
+ MethodName: "DelegateKeys",
+ Handler: _Query_DelegateKeys_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "gravity/v1/query.proto",
+}
+
+func (m *ParamsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ParamsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *ParamsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ParamsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ {
+ size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
+func (m *SignerSetTxRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SignerSetTxRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SignerSetTxRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.SignerSetNonce != 0 {
+ i = encodeVarintQuery(dAtA, i, uint64(m.SignerSetNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *LatestSignerSetTxRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *LatestSignerSetTxRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *LatestSignerSetTxRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *SignerSetTxResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SignerSetTxResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SignerSetTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.SignerSet != nil {
+ {
+ size, err := m.SignerSet.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTxRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTxRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTxRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.BatchNonce != 0 {
+ i = encodeVarintQuery(dAtA, i, uint64(m.BatchNonce))
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.TokenContract) > 0 {
+ i -= len(m.TokenContract)
+ copy(dAtA[i:], m.TokenContract)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.TokenContract)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTxResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTxResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Batch != nil {
+ {
+ size, err := m.Batch.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ContractCallTxRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ContractCallTxRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ContractCallTxRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.InvalidationNonce != 0 {
+ i = encodeVarintQuery(dAtA, i, uint64(m.InvalidationNonce))
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.InvalidationScope) > 0 {
+ i -= len(m.InvalidationScope)
+ copy(dAtA[i:], m.InvalidationScope)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.InvalidationScope)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ContractCallTxResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ContractCallTxResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ContractCallTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.LogicCall != nil {
+ {
+ size, err := m.LogicCall.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *SignerSetTxConfirmationsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SignerSetTxConfirmationsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SignerSetTxConfirmationsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.SignerSetNonce != 0 {
+ i = encodeVarintQuery(dAtA, i, uint64(m.SignerSetNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *SignerSetTxConfirmationsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SignerSetTxConfirmationsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SignerSetTxConfirmationsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signatures) > 0 {
+ for iNdEx := len(m.Signatures) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Signatures[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *SignerSetTxsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SignerSetTxsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SignerSetTxsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ {
+ size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *SignerSetTxsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SignerSetTxsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SignerSetTxsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ {
+ size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.SignerSets) > 0 {
+ for iNdEx := len(m.SignerSets) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.SignerSets[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTxsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTxsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTxsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ {
+ size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTxsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTxsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTxsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ {
+ size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.Batches) > 0 {
+ for iNdEx := len(m.Batches) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Batches[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ContractCallTxsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ContractCallTxsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ContractCallTxsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ {
+ size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ContractCallTxsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ContractCallTxsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ContractCallTxsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ {
+ size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.Calls) > 0 {
+ for iNdEx := len(m.Calls) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Calls[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *UnsignedSignerSetTxsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *UnsignedSignerSetTxsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *UnsignedSignerSetTxsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Address) > 0 {
+ i -= len(m.Address)
+ copy(dAtA[i:], m.Address)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Address)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *UnsignedSignerSetTxsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *UnsignedSignerSetTxsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *UnsignedSignerSetTxsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.SignerSets) > 0 {
+ for iNdEx := len(m.SignerSets) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.SignerSets[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *UnsignedBatchTxsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *UnsignedBatchTxsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *UnsignedBatchTxsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Address) > 0 {
+ i -= len(m.Address)
+ copy(dAtA[i:], m.Address)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Address)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *UnsignedBatchTxsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *UnsignedBatchTxsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *UnsignedBatchTxsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Batches) > 0 {
+ for iNdEx := len(m.Batches) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Batches[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *UnsignedContractCallTxsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *UnsignedContractCallTxsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *UnsignedContractCallTxsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Address) > 0 {
+ i -= len(m.Address)
+ copy(dAtA[i:], m.Address)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Address)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *UnsignedContractCallTxsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *UnsignedContractCallTxsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *UnsignedContractCallTxsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Calls) > 0 {
+ for iNdEx := len(m.Calls) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Calls[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTxFeesRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTxFeesRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTxFeesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTxFeesResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTxFeesResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTxFeesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Fees) > 0 {
+ for iNdEx := len(m.Fees) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Fees[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ContractCallTxConfirmationsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ContractCallTxConfirmationsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ContractCallTxConfirmationsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.InvalidationNonce != 0 {
+ i = encodeVarintQuery(dAtA, i, uint64(m.InvalidationNonce))
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.InvalidationScope) > 0 {
+ i -= len(m.InvalidationScope)
+ copy(dAtA[i:], m.InvalidationScope)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.InvalidationScope)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ContractCallTxConfirmationsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ContractCallTxConfirmationsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ContractCallTxConfirmationsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signatures) > 0 {
+ for iNdEx := len(m.Signatures) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Signatures[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTxConfirmationsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTxConfirmationsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTxConfirmationsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.TokenContract) > 0 {
+ i -= len(m.TokenContract)
+ copy(dAtA[i:], m.TokenContract)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.TokenContract)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.BatchNonce != 0 {
+ i = encodeVarintQuery(dAtA, i, uint64(m.BatchNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchTxConfirmationsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchTxConfirmationsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchTxConfirmationsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Signatures) > 0 {
+ for iNdEx := len(m.Signatures) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Signatures[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *LastSubmittedEthereumEventRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *LastSubmittedEthereumEventRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *LastSubmittedEthereumEventRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Address) > 0 {
+ i -= len(m.Address)
+ copy(dAtA[i:], m.Address)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Address)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *LastSubmittedEthereumEventResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *LastSubmittedEthereumEventResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *LastSubmittedEthereumEventResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.EventNonce != 0 {
+ i = encodeVarintQuery(dAtA, i, uint64(m.EventNonce))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ERC20ToDenomRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ERC20ToDenomRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ERC20ToDenomRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Erc20) > 0 {
+ i -= len(m.Erc20)
+ copy(dAtA[i:], m.Erc20)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Erc20)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *ERC20ToDenomResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ERC20ToDenomResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ERC20ToDenomResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.CosmosOriginated {
+ i--
+ if m.CosmosOriginated {
+ dAtA[i] = 1
+ } else {
+ dAtA[i] = 0
+ }
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.Denom) > 0 {
+ i -= len(m.Denom)
+ copy(dAtA[i:], m.Denom)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Denom)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DenomToERC20ParamsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DenomToERC20ParamsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DenomToERC20ParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Denom) > 0 {
+ i -= len(m.Denom)
+ copy(dAtA[i:], m.Denom)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Denom)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DenomToERC20ParamsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DenomToERC20ParamsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DenomToERC20ParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Erc20Decimals != 0 {
+ i = encodeVarintQuery(dAtA, i, uint64(m.Erc20Decimals))
+ i--
+ dAtA[i] = 0x20
+ }
+ if len(m.Erc20Symbol) > 0 {
+ i -= len(m.Erc20Symbol)
+ copy(dAtA[i:], m.Erc20Symbol)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Erc20Symbol)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if len(m.Erc20Name) > 0 {
+ i -= len(m.Erc20Name)
+ copy(dAtA[i:], m.Erc20Name)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Erc20Name)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.BaseDenom) > 0 {
+ i -= len(m.BaseDenom)
+ copy(dAtA[i:], m.BaseDenom)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.BaseDenom)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DenomToERC20Request) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DenomToERC20Request) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DenomToERC20Request) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.Denom) > 0 {
+ i -= len(m.Denom)
+ copy(dAtA[i:], m.Denom)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Denom)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DenomToERC20Response) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DenomToERC20Response) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DenomToERC20Response) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.CosmosOriginated {
+ i--
+ if m.CosmosOriginated {
+ dAtA[i] = 1
+ } else {
+ dAtA[i] = 0
+ }
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.Erc20) > 0 {
+ i -= len(m.Erc20)
+ copy(dAtA[i:], m.Erc20)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.Erc20)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DelegateKeysByValidatorRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DelegateKeysByValidatorRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DelegateKeysByValidatorRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.ValidatorAddress) > 0 {
+ i -= len(m.ValidatorAddress)
+ copy(dAtA[i:], m.ValidatorAddress)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.ValidatorAddress)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DelegateKeysByValidatorResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DelegateKeysByValidatorResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DelegateKeysByValidatorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.OrchestratorAddress) > 0 {
+ i -= len(m.OrchestratorAddress)
+ copy(dAtA[i:], m.OrchestratorAddress)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.OrchestratorAddress)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.EthAddress) > 0 {
+ i -= len(m.EthAddress)
+ copy(dAtA[i:], m.EthAddress)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.EthAddress)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DelegateKeysByEthereumSignerRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DelegateKeysByEthereumSignerRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DelegateKeysByEthereumSignerRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.EthereumSigner) > 0 {
+ i -= len(m.EthereumSigner)
+ copy(dAtA[i:], m.EthereumSigner)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.EthereumSigner)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DelegateKeysByEthereumSignerResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DelegateKeysByEthereumSignerResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DelegateKeysByEthereumSignerResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.OrchestratorAddress) > 0 {
+ i -= len(m.OrchestratorAddress)
+ copy(dAtA[i:], m.OrchestratorAddress)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.OrchestratorAddress)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.ValidatorAddress) > 0 {
+ i -= len(m.ValidatorAddress)
+ copy(dAtA[i:], m.ValidatorAddress)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.ValidatorAddress)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DelegateKeysByOrchestratorRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DelegateKeysByOrchestratorRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DelegateKeysByOrchestratorRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.OrchestratorAddress) > 0 {
+ i -= len(m.OrchestratorAddress)
+ copy(dAtA[i:], m.OrchestratorAddress)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.OrchestratorAddress)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DelegateKeysByOrchestratorResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DelegateKeysByOrchestratorResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DelegateKeysByOrchestratorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.EthereumSigner) > 0 {
+ i -= len(m.EthereumSigner)
+ copy(dAtA[i:], m.EthereumSigner)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.EthereumSigner)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.ValidatorAddress) > 0 {
+ i -= len(m.ValidatorAddress)
+ copy(dAtA[i:], m.ValidatorAddress)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.ValidatorAddress)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *DelegateKeysRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DelegateKeysRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DelegateKeysRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *DelegateKeysResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *DelegateKeysResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DelegateKeysResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.DelegateKeys) > 0 {
+ for iNdEx := len(m.DelegateKeys) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.DelegateKeys[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchedSendToEthereumsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchedSendToEthereumsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchedSendToEthereumsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.SenderAddress) > 0 {
+ i -= len(m.SenderAddress)
+ copy(dAtA[i:], m.SenderAddress)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.SenderAddress)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *BatchedSendToEthereumsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *BatchedSendToEthereumsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BatchedSendToEthereumsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.SendToEthereums) > 0 {
+ for iNdEx := len(m.SendToEthereums) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.SendToEthereums[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *UnbatchedSendToEthereumsRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *UnbatchedSendToEthereumsRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *UnbatchedSendToEthereumsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ {
+ size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.SenderAddress) > 0 {
+ i -= len(m.SenderAddress)
+ copy(dAtA[i:], m.SenderAddress)
+ i = encodeVarintQuery(dAtA, i, uint64(len(m.SenderAddress)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *UnbatchedSendToEthereumsResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *UnbatchedSendToEthereumsResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *UnbatchedSendToEthereumsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ {
+ size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ if len(m.SendToEthereums) > 0 {
+ for iNdEx := len(m.SendToEthereums) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.SendToEthereums[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
+func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
+ offset -= sovQuery(v)
+ base := offset
+ for v >= 1<<7 {
+ dAtA[offset] = uint8(v&0x7f | 0x80)
+ v >>= 7
+ offset++
+ }
+ dAtA[offset] = uint8(v)
+ return base
+}
+func (m *ParamsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *ParamsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = m.Params.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ return n
+}
+
+func (m *SignerSetTxRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.SignerSetNonce != 0 {
+ n += 1 + sovQuery(uint64(m.SignerSetNonce))
+ }
+ return n
+}
+
+func (m *LatestSignerSetTxRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *SignerSetTxResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.SignerSet != nil {
+ l = m.SignerSet.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *BatchTxRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.TokenContract)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ if m.BatchNonce != 0 {
+ n += 1 + sovQuery(uint64(m.BatchNonce))
+ }
+ return n
+}
+
+func (m *BatchTxResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Batch != nil {
+ l = m.Batch.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *ContractCallTxRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.InvalidationScope)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ if m.InvalidationNonce != 0 {
+ n += 1 + sovQuery(uint64(m.InvalidationNonce))
+ }
+ return n
+}
+
+func (m *ContractCallTxResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.LogicCall != nil {
+ l = m.LogicCall.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *SignerSetTxConfirmationsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.SignerSetNonce != 0 {
+ n += 1 + sovQuery(uint64(m.SignerSetNonce))
+ }
+ return n
+}
+
+func (m *SignerSetTxConfirmationsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Signatures) > 0 {
+ for _, e := range m.Signatures {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *SignerSetTxsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ l = m.Pagination.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *SignerSetTxsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.SignerSets) > 0 {
+ for _, e := range m.SignerSets {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ if m.Pagination != nil {
+ l = m.Pagination.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *BatchTxsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ l = m.Pagination.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *BatchTxsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Batches) > 0 {
+ for _, e := range m.Batches {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ if m.Pagination != nil {
+ l = m.Pagination.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *ContractCallTxsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Pagination != nil {
+ l = m.Pagination.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *ContractCallTxsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Calls) > 0 {
+ for _, e := range m.Calls {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ if m.Pagination != nil {
+ l = m.Pagination.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *UnsignedSignerSetTxsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Address)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *UnsignedSignerSetTxsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.SignerSets) > 0 {
+ for _, e := range m.SignerSets {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *UnsignedBatchTxsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Address)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *UnsignedBatchTxsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Batches) > 0 {
+ for _, e := range m.Batches {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *UnsignedContractCallTxsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Address)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *UnsignedContractCallTxsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Calls) > 0 {
+ for _, e := range m.Calls {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *BatchTxFeesRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *BatchTxFeesResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Fees) > 0 {
+ for _, e := range m.Fees {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *ContractCallTxConfirmationsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.InvalidationScope)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ if m.InvalidationNonce != 0 {
+ n += 1 + sovQuery(uint64(m.InvalidationNonce))
+ }
+ return n
+}
+
+func (m *ContractCallTxConfirmationsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Signatures) > 0 {
+ for _, e := range m.Signatures {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *BatchTxConfirmationsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.BatchNonce != 0 {
+ n += 1 + sovQuery(uint64(m.BatchNonce))
+ }
+ l = len(m.TokenContract)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *BatchTxConfirmationsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Signatures) > 0 {
+ for _, e := range m.Signatures {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *LastSubmittedEthereumEventRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Address)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *LastSubmittedEthereumEventResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.EventNonce != 0 {
+ n += 1 + sovQuery(uint64(m.EventNonce))
+ }
+ return n
+}
+
+func (m *ERC20ToDenomRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Erc20)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *ERC20ToDenomResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Denom)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ if m.CosmosOriginated {
+ n += 2
+ }
+ return n
+}
+
+func (m *DenomToERC20ParamsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Denom)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *DenomToERC20ParamsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.BaseDenom)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ l = len(m.Erc20Name)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ l = len(m.Erc20Symbol)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ if m.Erc20Decimals != 0 {
+ n += 1 + sovQuery(uint64(m.Erc20Decimals))
+ }
+ return n
+}
+
+func (m *DenomToERC20Request) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Denom)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *DenomToERC20Response) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Erc20)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ if m.CosmosOriginated {
+ n += 2
+ }
+ return n
+}
+
+func (m *DelegateKeysByValidatorRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.ValidatorAddress)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *DelegateKeysByValidatorResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.EthAddress)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ l = len(m.OrchestratorAddress)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *DelegateKeysByEthereumSignerRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.EthereumSigner)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *DelegateKeysByEthereumSignerResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.ValidatorAddress)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ l = len(m.OrchestratorAddress)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *DelegateKeysByOrchestratorRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.OrchestratorAddress)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *DelegateKeysByOrchestratorResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.ValidatorAddress)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ l = len(m.EthereumSigner)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *DelegateKeysRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *DelegateKeysResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.DelegateKeys) > 0 {
+ for _, e := range m.DelegateKeys {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *BatchedSendToEthereumsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.SenderAddress)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *BatchedSendToEthereumsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.SendToEthereums) > 0 {
+ for _, e := range m.SendToEthereums {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *UnbatchedSendToEthereumsRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.SenderAddress)
+ if l > 0 {
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ if m.Pagination != nil {
+ l = m.Pagination.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func (m *UnbatchedSendToEthereumsResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.SendToEthereums) > 0 {
+ for _, e := range m.SendToEthereums {
+ l = e.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ }
+ if m.Pagination != nil {
+ l = m.Pagination.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ }
+ return n
+}
+
+func sovQuery(x uint64) (n int) {
+ return (math_bits.Len64(x|1) + 6) / 7
+}
+func sozQuery(x uint64) (n int) {
+ return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *ParamsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ParamsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ParamsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ParamsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SignerSetTxRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SignerSetTxRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SignerSetTxRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SignerSetNonce", wireType)
+ }
+ m.SignerSetNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.SignerSetNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *LatestSignerSetTxRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: LatestSignerSetTxRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: LatestSignerSetTxRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SignerSetTxResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SignerSetTxResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SignerSetTxResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SignerSet", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.SignerSet == nil {
+ m.SignerSet = &SignerSetTx{}
+ }
+ if err := m.SignerSet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTxRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTxRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTxRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field TokenContract", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.TokenContract = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BatchNonce", wireType)
+ }
+ m.BatchNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.BatchNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTxResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTxResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTxResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Batch", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Batch == nil {
+ m.Batch = &BatchTx{}
+ }
+ if err := m.Batch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ContractCallTxRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ContractCallTxRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ContractCallTxRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationScope", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.InvalidationScope = append(m.InvalidationScope[:0], dAtA[iNdEx:postIndex]...)
+ if m.InvalidationScope == nil {
+ m.InvalidationScope = []byte{}
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationNonce", wireType)
+ }
+ m.InvalidationNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.InvalidationNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ContractCallTxResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ContractCallTxResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ContractCallTxResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field LogicCall", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.LogicCall == nil {
+ m.LogicCall = &ContractCallTx{}
+ }
+ if err := m.LogicCall.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SignerSetTxConfirmationsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SignerSetTxConfirmationsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SignerSetTxConfirmationsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SignerSetNonce", wireType)
+ }
+ m.SignerSetNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.SignerSetNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SignerSetTxConfirmationsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SignerSetTxConfirmationsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SignerSetTxConfirmationsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signatures", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signatures = append(m.Signatures, &SignerSetTxConfirmation{})
+ if err := m.Signatures[len(m.Signatures)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SignerSetTxsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SignerSetTxsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SignerSetTxsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Pagination == nil {
+ m.Pagination = &query.PageRequest{}
+ }
+ if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SignerSetTxsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SignerSetTxsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SignerSetTxsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SignerSets", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.SignerSets = append(m.SignerSets, &SignerSetTx{})
+ if err := m.SignerSets[len(m.SignerSets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Pagination == nil {
+ m.Pagination = &query.PageResponse{}
+ }
+ if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTxsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTxsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTxsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Pagination == nil {
+ m.Pagination = &query.PageRequest{}
+ }
+ if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTxsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTxsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTxsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Batches", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Batches = append(m.Batches, &BatchTx{})
+ if err := m.Batches[len(m.Batches)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Pagination == nil {
+ m.Pagination = &query.PageResponse{}
+ }
+ if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ContractCallTxsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ContractCallTxsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ContractCallTxsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Pagination == nil {
+ m.Pagination = &query.PageRequest{}
+ }
+ if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ContractCallTxsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ContractCallTxsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ContractCallTxsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Calls", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Calls = append(m.Calls, &ContractCallTx{})
+ if err := m.Calls[len(m.Calls)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Pagination == nil {
+ m.Pagination = &query.PageResponse{}
+ }
+ if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *UnsignedSignerSetTxsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: UnsignedSignerSetTxsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: UnsignedSignerSetTxsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Address = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *UnsignedSignerSetTxsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: UnsignedSignerSetTxsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: UnsignedSignerSetTxsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SignerSets", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.SignerSets = append(m.SignerSets, &SignerSetTx{})
+ if err := m.SignerSets[len(m.SignerSets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *UnsignedBatchTxsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: UnsignedBatchTxsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: UnsignedBatchTxsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Address = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *UnsignedBatchTxsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: UnsignedBatchTxsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: UnsignedBatchTxsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Batches", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Batches = append(m.Batches, &BatchTx{})
+ if err := m.Batches[len(m.Batches)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *UnsignedContractCallTxsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: UnsignedContractCallTxsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: UnsignedContractCallTxsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Address = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *UnsignedContractCallTxsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: UnsignedContractCallTxsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: UnsignedContractCallTxsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Calls", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Calls = append(m.Calls, &ContractCallTx{})
+ if err := m.Calls[len(m.Calls)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTxFeesRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTxFeesRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTxFeesRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTxFeesResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTxFeesResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTxFeesResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Fees", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Fees = append(m.Fees, types.Coin{})
+ if err := m.Fees[len(m.Fees)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ContractCallTxConfirmationsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ContractCallTxConfirmationsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ContractCallTxConfirmationsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationScope", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.InvalidationScope = append(m.InvalidationScope[:0], dAtA[iNdEx:postIndex]...)
+ if m.InvalidationScope == nil {
+ m.InvalidationScope = []byte{}
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InvalidationNonce", wireType)
+ }
+ m.InvalidationNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.InvalidationNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ContractCallTxConfirmationsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ContractCallTxConfirmationsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ContractCallTxConfirmationsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signatures", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signatures = append(m.Signatures, &ContractCallTxConfirmation{})
+ if err := m.Signatures[len(m.Signatures)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTxConfirmationsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTxConfirmationsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTxConfirmationsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BatchNonce", wireType)
+ }
+ m.BatchNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.BatchNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field TokenContract", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.TokenContract = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchTxConfirmationsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchTxConfirmationsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchTxConfirmationsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Signatures", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Signatures = append(m.Signatures, &BatchTxConfirmation{})
+ if err := m.Signatures[len(m.Signatures)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *LastSubmittedEthereumEventRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: LastSubmittedEthereumEventRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: LastSubmittedEthereumEventRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Address = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *LastSubmittedEthereumEventResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: LastSubmittedEthereumEventResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: LastSubmittedEthereumEventResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EventNonce", wireType)
+ }
+ m.EventNonce = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.EventNonce |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ERC20ToDenomRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ERC20ToDenomRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ERC20ToDenomRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Erc20 = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ERC20ToDenomResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ERC20ToDenomResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ERC20ToDenomResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Denom = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CosmosOriginated", wireType)
+ }
+ var v int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ m.CosmosOriginated = bool(v != 0)
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DenomToERC20ParamsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DenomToERC20ParamsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DenomToERC20ParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Denom = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DenomToERC20ParamsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DenomToERC20ParamsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DenomToERC20ParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BaseDenom", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.BaseDenom = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20Name", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Erc20Name = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20Symbol", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Erc20Symbol = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20Decimals", wireType)
+ }
+ m.Erc20Decimals = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Erc20Decimals |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DenomToERC20Request) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DenomToERC20Request: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DenomToERC20Request: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Denom = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DenomToERC20Response) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DenomToERC20Response: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DenomToERC20Response: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Erc20", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Erc20 = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CosmosOriginated", wireType)
+ }
+ var v int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ m.CosmosOriginated = bool(v != 0)
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DelegateKeysByValidatorRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DelegateKeysByValidatorRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DelegateKeysByValidatorRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ValidatorAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DelegateKeysByValidatorResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DelegateKeysByValidatorResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DelegateKeysByValidatorResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field OrchestratorAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.OrchestratorAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DelegateKeysByEthereumSignerRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DelegateKeysByEthereumSignerRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DelegateKeysByEthereumSignerRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumSigner", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumSigner = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DelegateKeysByEthereumSignerResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DelegateKeysByEthereumSignerResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DelegateKeysByEthereumSignerResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ValidatorAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field OrchestratorAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.OrchestratorAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DelegateKeysByOrchestratorRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DelegateKeysByOrchestratorRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DelegateKeysByOrchestratorRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field OrchestratorAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.OrchestratorAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DelegateKeysByOrchestratorResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DelegateKeysByOrchestratorResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DelegateKeysByOrchestratorResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ValidatorAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EthereumSigner", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.EthereumSigner = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DelegateKeysRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DelegateKeysRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DelegateKeysRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *DelegateKeysResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: DelegateKeysResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: DelegateKeysResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field DelegateKeys", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.DelegateKeys = append(m.DelegateKeys, &MsgDelegateKeys{})
+ if err := m.DelegateKeys[len(m.DelegateKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchedSendToEthereumsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchedSendToEthereumsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchedSendToEthereumsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SenderAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.SenderAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *BatchedSendToEthereumsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: BatchedSendToEthereumsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: BatchedSendToEthereumsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SendToEthereums", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.SendToEthereums = append(m.SendToEthereums, &SendToEthereum{})
+ if err := m.SendToEthereums[len(m.SendToEthereums)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *UnbatchedSendToEthereumsRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: UnbatchedSendToEthereumsRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: UnbatchedSendToEthereumsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SenderAddress", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.SenderAddress = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Pagination == nil {
+ m.Pagination = &query.PageRequest{}
+ }
+ if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *UnbatchedSendToEthereumsResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: UnbatchedSendToEthereumsResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: UnbatchedSendToEthereumsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SendToEthereums", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.SendToEthereums = append(m.SendToEthereums, &SendToEthereum{})
+ if err := m.SendToEthereums[len(m.SendToEthereums)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Pagination == nil {
+ m.Pagination = &query.PageResponse{}
+ }
+ if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func skipQuery(dAtA []byte) (n int, err error) {
+ l := len(dAtA)
+ iNdEx := 0
+ depth := 0
+ for iNdEx < l {
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ wireType := int(wire & 0x7)
+ switch wireType {
+ case 0:
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ iNdEx++
+ if dAtA[iNdEx-1] < 0x80 {
+ break
+ }
+ }
+ case 1:
+ iNdEx += 8
+ case 2:
+ var length int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ length |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if length < 0 {
+ return 0, ErrInvalidLengthQuery
+ }
+ iNdEx += length
+ case 3:
+ depth++
+ case 4:
+ if depth == 0 {
+ return 0, ErrUnexpectedEndOfGroupQuery
+ }
+ depth--
+ case 5:
+ iNdEx += 4
+ default:
+ return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+ }
+ if iNdEx < 0 {
+ return 0, ErrInvalidLengthQuery
+ }
+ if depth == 0 {
+ return iNdEx, nil
+ }
+ }
+ return 0, io.ErrUnexpectedEOF
+}
+
+var (
+ ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling")
+ ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow")
+ ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group")
+)
diff --git a/module/x/gravity/types/types.go b/module/x/gravity/types/types.go
new file mode 100644
index 0000000..b8497f9
--- /dev/null
+++ b/module/x/gravity/types/types.go
@@ -0,0 +1,125 @@
+package types
+
+import (
+ "bytes"
+ "crypto/sha256"
+ "math"
+ "sort"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/ethereum/go-ethereum/common"
+)
+
+//////////////////////////////////////
+// Ethereum Signer(S) //
+//////////////////////////////////////
+
+// ValidateBasic performs stateless checks on validity
+func (b *EthereumSigner) ValidateBasic() error {
+ if !common.IsHexAddress(b.EthereumAddress) {
+ return sdkerrors.Wrap(ErrInvalid, "ethereum address")
+ }
+ return nil
+}
+
+// EthereumSigners is the sorted set of validator data for Ethereum bridge MultiSig set
+type EthereumSigners []*EthereumSigner
+
+// Sort sorts the validators by power
+func (b EthereumSigners) Sort() {
+ sort.Slice(b, func(i, j int) bool {
+ if b[i].Power == b[j].Power {
+ // Secondary sort on eth address in case powers are equal
+ return EthereumAddrLessThan(b[i].EthereumAddress, b[j].EthereumAddress)
+ }
+ return b[i].Power > b[j].Power
+ })
+}
+
+// Hash takes the sha256sum of a representation of the signer set
+func (b EthereumSigners) Hash() []byte {
+ b.Sort()
+ var out bytes.Buffer
+ for _, s := range b {
+ out.Write(append(common.HexToAddress(s.EthereumAddress).Bytes(), sdk.Uint64ToBigEndian(s.Power)...))
+ }
+ hash := sha256.Sum256(out.Bytes())
+ return hash[:]
+}
+
+// PowerDiff returns the difference in power between two bridge validator sets
+// note this is Gravity bridge power *not* Cosmos voting power. Cosmos voting
+// power is based on the absolute number of tokens in the staking pool at any given
+// time Gravity bridge power is normalized using the equation.
+//
+// validators cosmos voting power / total cosmos voting power in this block = gravity bridge power / u32_max
+//
+// As an example if someone has 52% of the Cosmos voting power when a validator set is created their Gravity
+// bridge voting power is u32_max * .52
+//
+// Normalized voting power dramatically reduces how often we have to produce new validator set updates. For example
+// if the total on chain voting power increases by 1% due to inflation, we shouldn't have to generate a new validator
+// set, after all the validators retained their relative percentages during inflation and normalized Gravity bridge power
+// shows no difference.
+func (b EthereumSigners) PowerDiff(c EthereumSigners) float64 {
+ // loop over b and initialize the map with their powers
+ powers := map[string]int64{}
+ for _, bv := range b {
+ powers[bv.EthereumAddress] = int64(bv.Power)
+ }
+
+ // subtract c powers from powers in the map, initializing
+ // uninitialized keys with negative numbers
+ for _, es := range c {
+ if val, ok := powers[es.EthereumAddress]; ok {
+ powers[es.EthereumAddress] = val - int64(es.Power)
+ } else {
+ powers[es.EthereumAddress] = -int64(es.Power)
+ }
+ }
+
+ var delta float64
+ for _, v := range powers {
+ // NOTE: we care about the absolute value of the changes
+ delta += math.Abs(float64(v))
+ }
+
+ return math.Abs(delta / float64(math.MaxUint32))
+}
+
+// TotalPower returns the total power in the bridge validator set
+func (b EthereumSigners) TotalPower() (out uint64) {
+ for _, v := range b {
+ out += v.Power
+ }
+ return
+}
+
+// GetPowers returns only the power values for all members
+func (b EthereumSigners) GetPowers() []uint64 {
+ r := make([]uint64, len(b))
+ for i := range b {
+ r[i] = b[i].Power
+ }
+ return r
+}
+
+// NewSignerSetTx returns a new valset
+func NewSignerSetTx(nonce, height uint64, members EthereumSigners) *SignerSetTx {
+ members.Sort()
+ var mem []*EthereumSigner
+ for _, val := range members {
+ mem = append(mem, val)
+ }
+ return &SignerSetTx{Nonce: nonce, Height: height, Signers: mem}
+}
+
+// GetFees returns the total fees contained within a given batch
+func (b BatchTx) GetFees() sdk.Int {
+ sum := sdk.ZeroInt()
+ for _, t := range b.Transactions {
+ sum.Add(t.Erc20Fee.Amount)
+ }
+ return sum
+}
diff --git a/module/x/gravity/types/types_test.go b/module/x/gravity/types/types_test.go
new file mode 100644
index 0000000..e045f2a
--- /dev/null
+++ b/module/x/gravity/types/types_test.go
@@ -0,0 +1,174 @@
+package types
+
+import (
+ "bytes"
+ "encoding/hex"
+ mrand "math/rand"
+ "testing"
+
+ gethcommon "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestValsetConfirmHash(t *testing.T) {
+ powers := []uint64{3333, 3333, 3333}
+ ethAddresses := []string{
+ "0xc783df8a850f42e7F7e57013759C285caa701eB6",
+ "0xeAD9C93b79Ae7C1591b1FB5323BD777E86e150d4",
+ "0xE5904695748fe4A84b40b3fc79De2277660BD1D3",
+ }
+ members := make(EthereumSigners, len(powers))
+ for i := range powers {
+ members[i] = &EthereumSigner{
+ Power: powers[i],
+ EthereumAddress: ethAddresses[i],
+ }
+ }
+
+ var mem []*EthereumSigner
+ for _, m := range members {
+ mem = append(mem, m)
+ }
+ v := SignerSetTx{Signers: mem}
+ // TODO: this is hardcoded to foo, replace?
+ hash := v.GetCheckpoint([]byte("foo"))
+ hexHash := hex.EncodeToString(hash)
+ correctHash := "88165860d955aee7dc3e83d9d1156a5864b708841965585d206dbef6e9e1a499"
+ assert.Equal(t, correctHash, hexHash)
+}
+
+func TestEthereumSigners_PowerDiff(t *testing.T) {
+ specs := map[string]struct {
+ start EthereumSigners
+ diff EthereumSigners
+ exp float64
+ }{
+ "no diff": {
+ start: EthereumSigners{
+ {Power: 1, EthereumAddress: "0x479FFc856Cdfa0f5D1AE6Fa61915b01351A7773D"},
+ {Power: 2, EthereumAddress: "0x8E91960d704Df3fF24ECAb78AB9df1B5D9144140"},
+ {Power: 3, EthereumAddress: "0xF14879a175A2F1cEFC7c616f35b6d9c2b0Fd8326"},
+ },
+ diff: EthereumSigners{
+ {Power: 1, EthereumAddress: "0x479FFc856Cdfa0f5D1AE6Fa61915b01351A7773D"},
+ {Power: 2, EthereumAddress: "0x8E91960d704Df3fF24ECAb78AB9df1B5D9144140"},
+ {Power: 3, EthereumAddress: "0xF14879a175A2F1cEFC7c616f35b6d9c2b0Fd8326"},
+ },
+ exp: 0.0,
+ },
+ "one fifth": {
+ start: EthereumSigners{
+ {Power: 1073741823, EthereumAddress: "0x479FFc856Cdfa0f5D1AE6Fa61915b01351A7773D"},
+ {Power: 1073741823, EthereumAddress: "0x8E91960d704Df3fF24ECAb78AB9df1B5D9144140"},
+ {Power: 2147483646, EthereumAddress: "0xF14879a175A2F1cEFC7c616f35b6d9c2b0Fd8326"},
+ },
+ diff: EthereumSigners{
+ {Power: 858993459, EthereumAddress: "0x479FFc856Cdfa0f5D1AE6Fa61915b01351A7773D"},
+ {Power: 858993459, EthereumAddress: "0x8E91960d704Df3fF24ECAb78AB9df1B5D9144140"},
+ {Power: 2576980377, EthereumAddress: "0xF14879a175A2F1cEFC7c616f35b6d9c2b0Fd8326"},
+ },
+ exp: 0.2,
+ },
+ "real world": {
+ start: EthereumSigners{
+ {Power: 678509841, EthereumAddress: "0x6db48cBBCeD754bDc760720e38E456144e83269b"},
+ {Power: 671724742, EthereumAddress: "0x8E91960d704Df3fF24ECAb78AB9df1B5D9144140"},
+ {Power: 685294939, EthereumAddress: "0x479FFc856Cdfa0f5D1AE6Fa61915b01351A7773D"},
+ {Power: 671724742, EthereumAddress: "0x0A7254b318dd742A3086882321C27779B4B642a6"},
+ {Power: 671724742, EthereumAddress: "0x454330deAaB759468065d08F2b3B0562caBe1dD1"},
+ {Power: 617443955, EthereumAddress: "0x3511A211A6759d48d107898302042d1301187BA9"},
+ {Power: 6785098, EthereumAddress: "0x37A0603dA2ff6377E5C7f75698dabA8EE4Ba97B8"},
+ {Power: 291759231, EthereumAddress: "0xF14879a175A2F1cEFC7c616f35b6d9c2b0Fd8326"},
+ },
+ diff: EthereumSigners{
+ {Power: 642345266, EthereumAddress: "0x479FFc856Cdfa0f5D1AE6Fa61915b01351A7773D"},
+ {Power: 678509841, EthereumAddress: "0x6db48cBBCeD754bDc760720e38E456144e83269b"},
+ {Power: 671724742, EthereumAddress: "0x0A7254b318dd742A3086882321C27779B4B642a6"},
+ {Power: 671724742, EthereumAddress: "0x454330deAaB759468065d08F2b3B0562caBe1dD1"},
+ {Power: 671724742, EthereumAddress: "0x8E91960d704Df3fF24ECAb78AB9df1B5D9144140"},
+ {Power: 617443955, EthereumAddress: "0x3511A211A6759d48d107898302042d1301187BA9"},
+ {Power: 291759231, EthereumAddress: "0xF14879a175A2F1cEFC7c616f35b6d9c2b0Fd8326"},
+ {Power: 6785098, EthereumAddress: "0x37A0603dA2ff6377E5C7f75698dabA8EE4Ba97B8"},
+ },
+ exp: 0.010000000011641532,
+ },
+ }
+ for msg, spec := range specs {
+ t.Run(msg, func(t *testing.T) {
+ assert.Equal(t, spec.exp, spec.start.PowerDiff(spec.diff))
+ })
+ }
+}
+
+func TestValsetSort(t *testing.T) {
+ specs := map[string]struct {
+ src EthereumSigners
+ exp EthereumSigners
+ }{
+ "by power desc": {
+ src: EthereumSigners{
+ {Power: 1, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(3)}, 20)).String()},
+ {Power: 2, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(1)}, 20)).String()},
+ {Power: 3, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(2)}, 20)).String()},
+ },
+ exp: EthereumSigners{
+ {Power: 3, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(2)}, 20)).String()},
+ {Power: 2, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(1)}, 20)).String()},
+ {Power: 1, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(3)}, 20)).String()},
+ },
+ },
+ "by eth addr on same power": {
+ src: EthereumSigners{
+ {Power: 1, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(2)}, 20)).String()},
+ {Power: 1, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(1)}, 20)).String()},
+ {Power: 1, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(3)}, 20)).String()},
+ },
+ exp: EthereumSigners{
+ {Power: 1, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(1)}, 20)).String()},
+ {Power: 1, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(2)}, 20)).String()},
+ {Power: 1, EthereumAddress: gethcommon.BytesToAddress(bytes.Repeat([]byte{byte(3)}, 20)).String()},
+ },
+ },
+ // if you're thinking about changing this due to a change in the sorting algorithm
+ // you MUST go change this in gravity_utils/types.rs as well. You will also break all
+ // bridges in production when they try to migrate so use extreme caution!
+ "real world": {
+ src: EthereumSigners{
+ {Power: 678509841, EthereumAddress: "0x6db48cBBCeD754bDc760720e38E456144e83269b"},
+ {Power: 671724742, EthereumAddress: "0x8E91960d704Df3fF24ECAb78AB9df1B5D9144140"},
+ {Power: 685294939, EthereumAddress: "0x479FFc856Cdfa0f5D1AE6Fa61915b01351A7773D"},
+ {Power: 671724742, EthereumAddress: "0x0A7254b318dd742A3086882321C27779B4B642a6"},
+ {Power: 671724742, EthereumAddress: "0x454330deAaB759468065d08F2b3B0562caBe1dD1"},
+ {Power: 617443955, EthereumAddress: "0x3511A211A6759d48d107898302042d1301187BA9"},
+ {Power: 6785098, EthereumAddress: "0x37A0603dA2ff6377E5C7f75698dabA8EE4Ba97B8"},
+ {Power: 291759231, EthereumAddress: "0xF14879a175A2F1cEFC7c616f35b6d9c2b0Fd8326"},
+ },
+ exp: EthereumSigners{
+ {Power: 685294939, EthereumAddress: "0x479FFc856Cdfa0f5D1AE6Fa61915b01351A7773D"},
+ {Power: 678509841, EthereumAddress: "0x6db48cBBCeD754bDc760720e38E456144e83269b"},
+ {Power: 671724742, EthereumAddress: "0x0A7254b318dd742A3086882321C27779B4B642a6"},
+ {Power: 671724742, EthereumAddress: "0x454330deAaB759468065d08F2b3B0562caBe1dD1"},
+ {Power: 671724742, EthereumAddress: "0x8E91960d704Df3fF24ECAb78AB9df1B5D9144140"},
+ {Power: 617443955, EthereumAddress: "0x3511A211A6759d48d107898302042d1301187BA9"},
+ {Power: 291759231, EthereumAddress: "0xF14879a175A2F1cEFC7c616f35b6d9c2b0Fd8326"},
+ {Power: 6785098, EthereumAddress: "0x37A0603dA2ff6377E5C7f75698dabA8EE4Ba97B8"},
+ },
+ },
+ }
+ for msg, spec := range specs {
+ t.Run(msg, func(t *testing.T) {
+ spec.src.Sort()
+ assert.Equal(t, spec.src, spec.exp)
+ shuffled := shuffled(spec.src)
+ shuffled.Sort()
+ assert.Equal(t, shuffled, spec.exp)
+ })
+ }
+}
+
+func shuffled(v EthereumSigners) EthereumSigners {
+ mrand.Shuffle(len(v), func(i, j int) {
+ v[i], v[j] = v[j], v[i]
+ })
+ return v
+}
diff --git a/notes.md b/notes.md
new file mode 100644
index 0000000..7ce02b3
--- /dev/null
+++ b/notes.md
@@ -0,0 +1,123 @@
+# Installing Gravity on a Cosmos chain
+
+## Installing Gravity on an unstarted chain
+
+0. The deployed contract address is stored in the gentx's that validators generate
+ - Validators generate an Ethereum keypair and submit it as part of their gentx
+ - Validators also sign over the gentx validator state with their ethereum keypair
+1. Once Gentx signing is complete the Ethereum signatures are collected and used to submit a valset update to the already deployed Ethereum contract
+2. The chain starts, the validators all observe the Ethereum contract state and find that it matches their current validator state, proceed with updates as normal
+
+## Installing Gravity on a live Cosmos chain
+
+0. There is a governance resolution accepting the gravity code into the full node codebase
+ - Once gravity starts running on a validator, it generates an Ethereum keypair.
+ - We may get this from config temporarily
+ - Gravity publishes a validator's Ethereum address every single block.
+ - This is most likely just going to mean putting it in the gravity keeper, but maybe there needs to be some kind of greater tie in with the rest of the validator set information
+ - see staking/keeper/keeper.go for an example of getting individual and all validators
+ - A gravityId is chosen at this step.
+ - This may be hardcoded for now
+ - The source code hash of the gravity Ethereum contract is saved here.
+ - This may be hardcoded as well
+ - At some later step, we will need to check that all validators have their eth address in there
+1. There is a governance resolution that says "we are going to start gravity at block x"
+ - This is a parameter-changing resolution that the gravity module looks for
+1. Right after block x, the gravity module looks at the validator set at block x, and signs over it using its Ethereum keypair.
+1. Gravity puts the Ethereum signature from the last step into the consensus state. As part of consensus, the validators check that each of these signatures is valid.
+ - The Eth signatures over the Eth addresses of the validator set from the last block are now required in every block going forward.
+1. The deployer script hits a full node api, gets the Eth signatures of the valset from the latest block, and deploys the Ethereum contract.
+1. The deployer submits the address of the gravity contract that it deployed to Ethereum.
+ - We will consider the scenario that many deployers deploy many valid gravity eth contracts.
+ - The gravity module checks the Ethereum chain for each submitted address, and makes sure that the gravity contract at that address is using the correct source code, and has the correct validator set.
+1. There is a rule in the gravity module that the correct gravity eth contract address with the lowest address in the earliest block that is at least n blocks back is the "official" contract. After n blocks passes, this allows anyone wanting to use gravity to know which ethereum contract to send their money to.
+
+# Creating messages for the Ethereum contract
+
+## Valset Process
+
+- Gravity Daemon on each val submits a "MsgSetEthAddress" with an eth address and its signature over their Cosmos address
+- This validates the signature and adds the Eth addresss to the store under the EthAddressKey prefix.
+- Somebody submits a "MsgValsetRequest".
+- The valset from the current block goes into the store under the ValsetRequestKey prefix
+ - The valset's nonce is set as the current blockheight
+ - The valset is stored using the nonce/blockheight as the key
+- When the gravity daemons see a valset in the store, they sign over it with their eth key, and submit a MsgValsetConfirm. This goes into the store, after validation.
+ - Gravity daemons sign every valset that shows up in the store automatically, since they implicitly endorse it by having participated in the consensus which put it in the store.
+ - The valset confirm is stored using the nonce as the key, like the valset request
+- Once 66% of the gravity daemons have submitted signatures for a particular valset, a relayer can submit the valset, by accessing the valset and the signatures from the store. Maybe we will make a method to do this easily.
+
+## TX Batch process
+
+- User submits Cosmos TX with requested Eth TX "EthTx"
+- This goes into everyone's stores by consensus
+
+- --> Gravity module sorts TXs into batches, and puts the batches into the "BatchStore", and all Eth TXs in a batch are removed from the mempool.
+
+- Gravity Daemon on each validator sees all batches in the BatchStore, signs over the batches, sends a "BatchConfirmTx" containing all eth signatures for all the batches.
+- The BatchConfirmTx goes into a BatchConfirmStore, now the relayer can relay the batch once there's 66%
+
+- Now the batch is processed by the Eth contract.
+- The Gravity Daemons on the validators observe this, and they submit a "BatchSubmittedTx". This TX goes into a Batch SubmittedStore. The cosmos state machine discards the batch permanently once it sees that over 66% of the validators have submitted a BatchSubmittedTx.
+ - If there are any older batches in the BatchConfirmStore, they are removed because they can now never be submitted. The Eth Tx's in the old batches are released back into the mempool.
+
+## Deposit oracle process
+
+- Gravity Daemons constantly observe the Ethereum blockchain. Specifically the Gravity Ethereum contract
+- When a deposit is observed each validator sends a DepositTX after 50 blocks have elapsed (to resolve forks)
+- When more than 66% of the validator shave signed off on a DepositTX the message handler itself calls out to the bank and generates tokens
+
+# CosmosSDK / Tendermint considerations
+
+## Signing
+
+In order to update the validator state on the Gravity Ethereum contract we need to perform probably the simplest 'off chain work' possible. Signing the current validator state with an Ethereum key and submitting that as a message
+so that a relayer may observe and ferry the signed 'ValSetUpdate' message over to Ethereum.
+
+The concept of 'validators signing some known value' is very core to Tendermint and of course any proof of stake system. So when it's presented as a step in any Gravity process no one bats an eye. But we're not coding Gravity as a Tendermint extension, it's a CosmosSDK module.
+
+CosmosSDK modules don't have access to validator private keys or a signing context to work with. In order to get around this we perform the signing in a separate codebase that interacts with the main module. Typically this would be called a 'relayer' but since we're writing a module where the validators specifically must perform actions with their own private keys it may be better to term this as a 'validator external signer' or something along those lines.
+
+The need for an external signer doubles the number of states required to produce a working Gravity CosmosSDK module state machine. For example the ValSetUpdate message generation process requires a trigger message, this goes into a store where the external signers observe it and submit their own signatures. This 'waiting for sigs' state could be eliminated if signing the state update could be processed as part of the trigger message handler itself.
+
+This obviously isn't a show stopper, but if it's easy _and_ maintainable we should consider using ABCI to do this at the Tendermint level.
+
+## Gravity Consensus
+
+Performing our signing at the CosmosSDK level rather than the Tendermint level has other implications. Mainly it changes the nature of the slashing and halting conditions. At the Tendermint level if signing the ValSetUpdate was part of processing the message failing to do so would result in downtime for that validator on that block. On the other hand submitting a ValSetUpdate signature in a CosmosSDK module is just another message, having no consensus impact other than slashing conditions we may add. Since slashing conditions are slow this produces the following potential vulnerability.
+
+If a validator failing to produce ValSetUpdates and the process is implemented in Tendermint they are simply racking up downtime and have no capabilities as a validator. But if the process is implemented at the CosmosSDK level they will continue to operate normally as a validator.
+
+My intuition about vulnerabilities here is that they could only be used to halt the bridge using 1/3rd of the stake. Since that's roughly the same as halting the chain using 1/3rd of the active stake I don't think it's an issue.
+Ethereum event feed
+
+- There is a governance parameter called EthBlockDelay, for example 50 blocks
+- Gravity Daemons get the current block number from their Geth, then get the events from the block EthBlockDelay lower than the current one
+- They send an EthBlockData message
+- These messages go in an EthBlockDataStore, indexed by the block number and the validator that sent them.
+- Once there is a version of the block data that matches from at least 66% of the validators, it is considered legit
+- Once a block goes over 66% (and all previous blocks are also over 66%), tokens are minted as a result of EthToCosmos transfers in that block.
+- (optional downtime slashing???) Something watches for validators that have not submitted matching block data, and triggers a downtime slashing
+
+Alternate experimental ethereum input
+
+- Let's say that accounts have to send a ClaimTokens message to get their tokens that have been transferred over from Eth (just for sake of argument)
+
+- When a ClaimTokens message comes in, each validator in the state machine, checks it's own eth block DB (this is seperate from the Cosmos KV stores, and is access only by the gravity module. The gravity daemon fills it up with block data from a different process) to see if the tokens have been transferred to that account.
+- Validators with a different opinion on the state of Eth will arrive at different conclusions, and produce different blocks. Validators that disagree will have downtime, according to Tendermint. This allows Tendermint to handle all consensus, and we don't think about it.
+
+Ethereum to Cosmos transfers
+
+- Function in contract takes a destination Cosmos address and transfer amount
+- Does the transfer and logs a EthToCosmosTransfer event with the amount and destination
+
+Alternate batch assembly by validators
+
+- Allowing anyone to request batches as we have envisioned previously opens up an attack vector where someone assembles unprofitable batches to stop the bridge.
+- Instead, why not just have the validators assemble batches?
+- In the cosmos state machine, they look at all transactions, sort them from lowest to highest fee, and chop that list into batches.
+- Now relayers can try to submit the batches.
+- Batches are submitted to Eth, and transactions build up in the pool, in parallel.
+- At some point the validators make new batches sorted in the same way.
+- Relayers may choose to submit new batches which invalidate older low fee batches.
diff --git a/orchestrator/.dockerignore b/orchestrator/.dockerignore
new file mode 100644
index 0000000..644db56
--- /dev/null
+++ b/orchestrator/.dockerignore
@@ -0,0 +1,6 @@
+.dockerignore
+.git
+.gitignore
+Dockerfile
+testnet.Dockerfile
+target/
\ No newline at end of file
diff --git a/orchestrator/.gitignore b/orchestrator/.gitignore
new file mode 100644
index 0000000..2f7896d
--- /dev/null
+++ b/orchestrator/.gitignore
@@ -0,0 +1 @@
+target/
diff --git a/orchestrator/Cargo.lock b/orchestrator/Cargo.lock
new file mode 100644
index 0000000..ca5356a
--- /dev/null
+++ b/orchestrator/Cargo.lock
@@ -0,0 +1,4165 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "abscissa_core"
+version = "0.6.0-pre.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "576dbfaac815924aefd67b1a6566fefdb617f3df250a9eb384440078831143e4"
+dependencies = [
+ "abscissa_derive",
+ "arc-swap",
+ "backtrace",
+ "canonical-path",
+ "chrono",
+ "color-eyre",
+ "fs-err",
+ "gumdrop",
+ "once_cell",
+ "regex",
+ "secrecy",
+ "semver 0.10.0",
+ "serde",
+ "termcolor",
+ "toml",
+ "tracing",
+ "tracing-log",
+ "tracing-subscriber",
+ "wait-timeout",
+]
+
+[[package]]
+name = "abscissa_derive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74f5722bc48763cb9d81d8427ca05b6aa2842f6632cf8e4c0a29eef9baececcc"
+dependencies = [
+ "darling",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "abscissa_tokio"
+version = "0.6.0-pre.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80063fd5884d9a4220c4de14287b19c6aaf4a8f30a7dafb84cb757ff202edbff"
+dependencies = [
+ "abscissa_core",
+ "actix-rt 2.2.0",
+ "tokio 1.5.0",
+]
+
+[[package]]
+name = "actix"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "543c47e7827f8fcc9d1445bd98ba402137bfce80ee2187429de49c52b5131bd3"
+dependencies = [
+ "actix-rt 2.2.0",
+ "actix_derive",
+ "bitflags",
+ "bytes 1.0.1",
+ "crossbeam-channel",
+ "futures-core",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+ "log",
+ "once_cell",
+ "parking_lot",
+ "pin-project-lite 0.2.6",
+ "smallvec",
+ "tokio 1.5.0",
+ "tokio-util 0.6.6",
+]
+
+[[package]]
+name = "actix-codec"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570"
+dependencies = [
+ "bitflags",
+ "bytes 0.5.6",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "pin-project 0.4.28",
+ "tokio 0.2.25",
+ "tokio-util 0.3.1",
+]
+
+[[package]]
+name = "actix-codec"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d5dbeb2d9e51344cb83ca7cc170f1217f9fe25bfc50160e6e200b5c31c1019a"
+dependencies = [
+ "bitflags",
+ "bytes 1.0.1",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "pin-project-lite 0.2.6",
+ "tokio 1.5.0",
+ "tokio-util 0.6.6",
+]
+
+[[package]]
+name = "actix-connect"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc"
+dependencies = [
+ "actix-codec 0.3.0",
+ "actix-rt 1.1.1",
+ "actix-service 1.0.6",
+ "actix-utils 2.0.0",
+ "derive_more",
+ "either",
+ "futures-util",
+ "http",
+ "log",
+ "openssl",
+ "tokio-openssl 0.4.0",
+ "trust-dns-proto",
+ "trust-dns-resolver",
+]
+
+[[package]]
+name = "actix-http"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "452299e87817ae5673910e53c243484ca38be3828db819b6011736fc6982e874"
+dependencies = [
+ "actix-codec 0.3.0",
+ "actix-connect",
+ "actix-rt 1.1.1",
+ "actix-service 1.0.6",
+ "actix-threadpool",
+ "actix-tls 2.0.0",
+ "actix-utils 2.0.0",
+ "base64",
+ "bitflags",
+ "brotli2",
+ "bytes 0.5.6",
+ "cookie",
+ "copyless",
+ "derive_more",
+ "either",
+ "encoding_rs",
+ "flate2",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "fxhash",
+ "h2 0.2.7",
+ "http",
+ "httparse",
+ "indexmap",
+ "itoa",
+ "language-tags 0.2.2",
+ "lazy_static",
+ "log",
+ "mime",
+ "percent-encoding",
+ "pin-project 1.0.6",
+ "rand 0.7.3",
+ "regex",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sha-1",
+ "slab",
+ "time 0.2.26",
+]
+
+[[package]]
+name = "actix-http"
+version = "3.0.0-beta.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a6b8dd8ffcb0277cebef2c4b496821c888e0320817c1862a83359d4e384797a"
+dependencies = [
+ "actix-codec 0.4.0",
+ "actix-rt 2.2.0",
+ "actix-service 2.0.0",
+ "actix-tls 3.0.0-beta.5",
+ "actix-utils 3.0.0",
+ "ahash",
+ "base64",
+ "bitflags",
+ "brotli2",
+ "bytes 1.0.1",
+ "bytestring",
+ "derive_more",
+ "encoding_rs",
+ "flate2",
+ "futures-core",
+ "futures-util",
+ "h2 0.3.3",
+ "http",
+ "httparse",
+ "itoa",
+ "language-tags 0.3.2",
+ "local-channel",
+ "log",
+ "mime",
+ "once_cell",
+ "percent-encoding",
+ "pin-project 1.0.6",
+ "pin-project-lite 0.2.6",
+ "rand 0.8.3",
+ "regex",
+ "serde",
+ "sha-1",
+ "smallvec",
+ "time 0.2.26",
+ "tokio 1.5.0",
+ "zstd",
+]
+
+[[package]]
+name = "actix-macros"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "actix-macros"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbcb2b608f0accc2f5bcf3dd872194ce13d94ee45b571487035864cf966b04ef"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "actix-router"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ad299af73649e1fc893e333ccf86f377751eb95ff875d095131574c6f43452c"
+dependencies = [
+ "bytestring",
+ "http",
+ "log",
+ "regex",
+ "serde",
+]
+
+[[package]]
+name = "actix-rt"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227"
+dependencies = [
+ "actix-macros 0.1.3",
+ "actix-threadpool",
+ "copyless",
+ "futures-channel",
+ "futures-util",
+ "smallvec",
+ "tokio 0.2.25",
+]
+
+[[package]]
+name = "actix-rt"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc7d7cd957c9ed92288a7c3c96af81fa5291f65247a76a34dac7b6af74e52ba0"
+dependencies = [
+ "actix-macros 0.2.0",
+ "futures-core",
+ "tokio 1.5.0",
+]
+
+[[package]]
+name = "actix-server"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e"
+dependencies = [
+ "actix-codec 0.3.0",
+ "actix-rt 1.1.1",
+ "actix-service 1.0.6",
+ "actix-utils 2.0.0",
+ "futures-channel",
+ "futures-util",
+ "log",
+ "mio 0.6.23",
+ "mio-uds",
+ "num_cpus",
+ "slab",
+ "socket2 0.3.19",
+]
+
+[[package]]
+name = "actix-service"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb"
+dependencies = [
+ "futures-util",
+ "pin-project 0.4.28",
+]
+
+[[package]]
+name = "actix-service"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77f5f9d66a8730d0fae62c26f3424f5751e5518086628a40b7ab6fca4a705034"
+dependencies = [
+ "futures-core",
+ "paste",
+ "pin-project-lite 0.2.6",
+]
+
+[[package]]
+name = "actix-testing"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c"
+dependencies = [
+ "actix-macros 0.1.3",
+ "actix-rt 1.1.1",
+ "actix-server",
+ "actix-service 1.0.6",
+ "log",
+ "socket2 0.3.19",
+]
+
+[[package]]
+name = "actix-threadpool"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30"
+dependencies = [
+ "derive_more",
+ "futures-channel",
+ "lazy_static",
+ "log",
+ "num_cpus",
+ "parking_lot",
+ "threadpool",
+]
+
+[[package]]
+name = "actix-tls"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb"
+dependencies = [
+ "actix-codec 0.3.0",
+ "actix-service 1.0.6",
+ "actix-utils 2.0.0",
+ "futures-util",
+ "openssl",
+ "tokio-openssl 0.4.0",
+]
+
+[[package]]
+name = "actix-tls"
+version = "3.0.0-beta.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65b7bb60840962ef0332f7ea01a57d73a24d2cb663708511ff800250bbfef569"
+dependencies = [
+ "actix-codec 0.4.0",
+ "actix-rt 2.2.0",
+ "actix-service 2.0.0",
+ "actix-utils 3.0.0",
+ "derive_more",
+ "futures-core",
+ "http",
+ "log",
+ "openssl",
+ "tokio-openssl 0.6.1",
+ "tokio-util 0.6.6",
+]
+
+[[package]]
+name = "actix-utils"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a"
+dependencies = [
+ "actix-codec 0.3.0",
+ "actix-rt 1.1.1",
+ "actix-service 1.0.6",
+ "bitflags",
+ "bytes 0.5.6",
+ "either",
+ "futures-channel",
+ "futures-sink",
+ "futures-util",
+ "log",
+ "pin-project 0.4.28",
+ "slab",
+]
+
+[[package]]
+name = "actix-utils"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94"
+dependencies = [
+ "local-waker",
+ "pin-project-lite 0.2.6",
+]
+
+[[package]]
+name = "actix-web"
+version = "3.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86"
+dependencies = [
+ "actix-codec 0.3.0",
+ "actix-http 2.2.0",
+ "actix-macros 0.1.3",
+ "actix-router",
+ "actix-rt 1.1.1",
+ "actix-server",
+ "actix-service 1.0.6",
+ "actix-testing",
+ "actix-threadpool",
+ "actix-tls 2.0.0",
+ "actix-utils 2.0.0",
+ "actix-web-codegen",
+ "awc 2.0.3",
+ "bytes 0.5.6",
+ "derive_more",
+ "encoding_rs",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "fxhash",
+ "log",
+ "mime",
+ "openssl",
+ "pin-project 1.0.6",
+ "regex",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "socket2 0.3.19",
+ "time 0.2.26",
+ "tinyvec",
+ "url",
+]
+
+[[package]]
+name = "actix-web-codegen"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "actix_derive"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "addr2line"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "ahash"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f200cbb1e856866d9eade941cf3aa0c5d7dd36f74311c4273b494f4ef036957"
+dependencies = [
+ "getrandom 0.2.2",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "anomaly"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "550632e31568ae1a5f47998c3aa48563030fc49b9ec91913ca337cf64fbc5ccb"
+dependencies = [
+ "backtrace",
+]
+
+[[package]]
+name = "ansi_term"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
+dependencies = [
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
+
+[[package]]
+name = "arc-swap"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4d7d63395147b81a9e570bcc6243aaf71c017bd666d4909cfef0085bdda8d73"
+
+[[package]]
+name = "arrayvec"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
+
+[[package]]
+name = "async-stream"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3670df70cbc01729f901f94c887814b3c68db038aad1329a418bae178bc5295c"
+dependencies = [
+ "async-stream-impl",
+ "futures-core",
+]
+
+[[package]]
+name = "async-stream-impl"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3548b8efc9f8e8a5a0a2808c5bd8451a9031b9e5b879a79590304ae928b0a70"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.49"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589652ce7ccb335d1e7ecb3be145425702b290dbcb7029bbeaae263fc1d87b48"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+
+[[package]]
+name = "awc"
+version = "2.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691"
+dependencies = [
+ "actix-codec 0.3.0",
+ "actix-http 2.2.0",
+ "actix-rt 1.1.1",
+ "actix-service 1.0.6",
+ "base64",
+ "bytes 0.5.6",
+ "cfg-if 1.0.0",
+ "derive_more",
+ "futures-core",
+ "log",
+ "mime",
+ "openssl",
+ "percent-encoding",
+ "rand 0.7.3",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+]
+
+[[package]]
+name = "awc"
+version = "3.0.0-beta.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15ffe93051a6e05151f310862b6097b58c40e873352083caa820c406392732b2"
+dependencies = [
+ "actix-codec 0.4.0",
+ "actix-http 3.0.0-beta.7",
+ "actix-rt 2.2.0",
+ "actix-service 2.0.0",
+ "base64",
+ "bytes 1.0.1",
+ "derive_more",
+ "futures-core",
+ "itoa",
+ "log",
+ "mime",
+ "openssl",
+ "percent-encoding",
+ "pin-project-lite 0.2.6",
+ "rand 0.8.3",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+]
+
+[[package]]
+name = "axum"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24f143b3839608f1254ac928abeffea9d654d9732162dcb6f0dd92bc022672f1"
+dependencies = [
+ "async-trait",
+ "bytes 1.0.1",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "pin-project 1.0.6",
+ "regex",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "tokio 1.5.0",
+ "tokio-util 0.6.6",
+ "tower",
+ "tower-http",
+]
+
+[[package]]
+name = "backtrace"
+version = "0.3.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc"
+dependencies = [
+ "addr2line",
+ "cfg-if 1.0.0",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "base-x"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
+
+[[package]]
+name = "base64"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+
+[[package]]
+name = "base64ct"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5"
+
+[[package]]
+name = "bech32"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1"
+
+[[package]]
+name = "bech32"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c7f7096bc256f5e5cb960f60dfc4f4ef979ca65abe7fb9d5a4f77150d3783d4"
+
+[[package]]
+name = "bip32"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b48054b307f98bf2ddb17ffd4e9d029bfaf3e7cd5fe807e412768e4370015e3d"
+dependencies = [
+ "bs58",
+ "hkd32",
+ "hmac 0.11.0",
+ "k256",
+ "ripemd160",
+ "sha2",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+
+[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "block-padding",
+ "generic-array",
+]
+
+[[package]]
+name = "block-padding"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
+
+[[package]]
+name = "brotli-sys"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "brotli2"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e"
+dependencies = [
+ "brotli-sys",
+ "libc",
+]
+
+[[package]]
+name = "bs58"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
+dependencies = [
+ "sha2",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "bytes"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
+
+[[package]]
+name = "bytes"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
+
+[[package]]
+name = "bytestring"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d"
+dependencies = [
+ "bytes 1.0.1",
+]
+
+[[package]]
+name = "canonical-path"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f"
+
+[[package]]
+name = "cc"
+version = "1.0.67"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
+dependencies = [
+ "jobserver",
+]
+
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chrono"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
+dependencies = [
+ "libc",
+ "num-integer",
+ "num-traits",
+ "serde",
+ "time 0.1.43",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "clarity"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef8749bcae70d65c0705636ee675020490f35e05cf4ec2d4b78455aeca2194f7"
+dependencies = [
+ "lazy_static",
+ "num-bigint 0.4.0",
+ "num-traits",
+ "num256",
+ "secp256k1 0.20.1",
+ "serde",
+ "serde-rlp",
+ "serde_bytes",
+ "serde_derive",
+ "sha3",
+]
+
+[[package]]
+name = "client"
+version = "0.4.1"
+dependencies = [
+ "actix-rt 2.2.0",
+ "clarity",
+ "cosmos_gravity",
+ "deep_space 2.4.3",
+ "docopt",
+ "env_logger",
+ "ethereum_gravity",
+ "gravity_proto",
+ "gravity_utils",
+ "lazy_static",
+ "openssl-probe",
+ "serde",
+ "serde_derive",
+ "tokio 1.5.0",
+ "url",
+ "web30",
+]
+
+[[package]]
+name = "color-eyre"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f1885697ee8a177096d42f158922251a41973117f6d8a234cee94b9509157b7"
+dependencies = [
+ "backtrace",
+ "eyre",
+ "indenter",
+ "once_cell",
+ "owo-colors",
+]
+
+[[package]]
+name = "const-oid"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22"
+
+[[package]]
+name = "const_fn"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "076a6803b0dacd6a88cfe64deba628b01533ff5ef265687e6938280c1afd0a28"
+
+[[package]]
+name = "contact"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46eb2b658f7d46ac4a9737d8d69f4784796aea04b7388935d3eddd4470b883f4"
+dependencies = [
+ "actix-web",
+ "deep_space 0.2.5",
+ "log",
+ "num256",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tokio 0.2.25",
+]
+
+[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
+[[package]]
+name = "cookie"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951"
+dependencies = [
+ "percent-encoding",
+ "time 0.2.26",
+ "version_check",
+]
+
+[[package]]
+name = "copyless"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536"
+
+[[package]]
+name = "cosmos-sdk-proto"
+version = "0.5.0"
+source = "git+http://github.com/cosmos/cosmos-rust?branch=main#c0c0e4e04fe0a79d4d619846f9337c94f1e13ecd"
+dependencies = [
+ "prost",
+ "prost-types",
+ "tendermint-proto",
+ "tonic",
+]
+
+[[package]]
+name = "cosmos_gravity"
+version = "0.1.0"
+dependencies = [
+ "actix",
+ "bytes 1.0.1",
+ "clarity",
+ "cosmos-sdk-proto",
+ "deep_space 2.4.3",
+ "env_logger",
+ "ethereum_gravity",
+ "gravity_proto",
+ "gravity_utils",
+ "log",
+ "num256",
+ "prost",
+ "prost-types",
+ "rand 0.8.3",
+ "serde",
+ "sha3",
+ "tokio 1.5.0",
+ "tonic",
+ "web30",
+]
+
+[[package]]
+name = "cpuid-bool"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
+
+[[package]]
+name = "crc32fast"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
+dependencies = [
+ "autocfg",
+ "cfg-if 1.0.0",
+ "lazy_static",
+]
+
+[[package]]
+name = "crypto-bigint"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b32a398eb1ccfbe7e4f452bc749c44d38dd732e9a253f19da224c416f00ee7f4"
+dependencies = [
+ "generic-array",
+ "rand_core 0.6.2",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "crypto-mac"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
+[[package]]
+name = "crypto-mac"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
+[[package]]
+name = "darling"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim 0.9.3",
+ "syn",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "deep_space"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afd044e670beb23ce6a2007d139ed3787b99c85b5ff3982b8fdfda66c3682e53"
+dependencies = [
+ "base64",
+ "bech32 0.7.3",
+ "hmac 0.10.1",
+ "num-bigint 0.3.2",
+ "num-traits",
+ "num256",
+ "pbkdf2 0.6.0",
+ "rand 0.7.3",
+ "ripemd160",
+ "secp256k1 0.19.0",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "sha2",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "deep_space"
+version = "2.4.3"
+source = "git+https://github.com/iqlusioninc/deep_space/?branch=zaki/tendermint_0_21#3aaf866c5c2bed69beda86d46d0f4a9465806e70"
+dependencies = [
+ "base64",
+ "bech32 0.8.0",
+ "bytes 1.0.1",
+ "cosmos-sdk-proto",
+ "hmac 0.11.0",
+ "log",
+ "num-bigint 0.4.0",
+ "num-traits",
+ "num256",
+ "pbkdf2 0.8.0",
+ "prost",
+ "prost-types",
+ "rand 0.8.3",
+ "ripemd160",
+ "rust_decimal",
+ "secp256k1 0.20.1",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "sha2",
+ "tendermint-proto",
+ "tokio 1.5.0",
+ "tonic",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "der"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49f215f706081a44cb702c71c39a52c05da637822e9c1645a50b7202689e982d"
+dependencies = [
+ "const-oid",
+]
+
+[[package]]
+name = "derive_more"
+version = "0.99.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f82b1b72f1263f214c0f823371768776c4f5841b942c9883aa8e5ec584fd0ba6"
+dependencies = [
+ "convert_case",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "discard"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
+
+[[package]]
+name = "docopt"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f3f119846c823f9eafcf953a8f6ffb6ed69bf6240883261a7f13b634579a51f"
+dependencies = [
+ "lazy_static",
+ "regex",
+ "serde",
+ "strsim 0.10.0",
+]
+
+[[package]]
+name = "ecdsa"
+version = "0.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05cb0ed2d2ce37766ac86c05f66973ace8c51f7f1533bedce8fb79e2b54b3f14"
+dependencies = [
+ "der",
+ "elliptic-curve",
+ "hmac 0.11.0",
+ "signature",
+]
+
+[[package]]
+name = "either"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+
+[[package]]
+name = "elliptic-curve"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83e5c176479da93a0983f0a6fdc3c1b8e7d5be0d7fe3fe05a99f15b96582b9a8"
+dependencies = [
+ "crypto-bigint",
+ "ff",
+ "generic-array",
+ "group",
+ "pkcs8",
+ "rand_core 0.6.2",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "enum-as-inner"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "error"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6e606f14042bb87cc02ef6a14db6c90ab92ed6f62d87e69377bc759fd7987cc"
+dependencies = [
+ "traitobject",
+ "typeable",
+]
+
+[[package]]
+name = "ethereum_gravity"
+version = "0.1.0"
+dependencies = [
+ "clarity",
+ "deep_space 2.4.3",
+ "gravity_utils",
+ "log",
+ "num256",
+ "sha3",
+ "web30",
+]
+
+[[package]]
+name = "eyre"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "221239d1d5ea86bf5d6f91c9d6bc3646ffe471b08ff9b0f91c44f115ac969d2b"
+dependencies = [
+ "indenter",
+ "once_cell",
+]
+
+[[package]]
+name = "ff"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63eec06c61e487eecf0f7e6e6372e596a81922c28d33e645d6983ca6493a1af0"
+dependencies = [
+ "rand_core 0.6.2",
+ "subtle",
+]
+
+[[package]]
+name = "fixedbitset"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
+
+[[package]]
+name = "flate2"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crc32fast",
+ "libc",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
+dependencies = [
+ "matches",
+ "percent-encoding",
+]
+
+[[package]]
+name = "fs-err"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ebd3504ad6116843b8375ad70df74e7bfe83cac77a1f3fe73200c844d43bfe0"
+
+[[package]]
+name = "fuchsia-cprng"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+
+[[package]]
+name = "fuchsia-zircon"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+dependencies = [
+ "bitflags",
+ "fuchsia-zircon-sys",
+]
+
+[[package]]
+name = "fuchsia-zircon-sys"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+
+[[package]]
+name = "futures"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
+dependencies = [
+ "proc-macro-hack",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
+
+[[package]]
+name = "futures-task"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
+
+[[package]]
+name = "futures-util"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite 0.2.6",
+ "pin-utils",
+ "proc-macro-hack",
+ "proc-macro-nested",
+ "slab",
+]
+
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "wasi 0.9.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "wasi 0.10.2+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "gimli"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
+
+[[package]]
+name = "gorc"
+version = "0.1.0"
+dependencies = [
+ "abscissa_core",
+ "abscissa_tokio",
+ "actix-rt 2.2.0",
+ "bip32",
+ "bytes 1.0.1",
+ "clarity",
+ "cosmos_gravity",
+ "deep_space 2.4.3",
+ "ethereum_gravity",
+ "gravity_proto",
+ "gravity_utils",
+ "gumdrop",
+ "k256",
+ "once_cell",
+ "orchestrator",
+ "pkcs8",
+ "prost",
+ "rand_core 0.6.2",
+ "regex",
+ "relayer",
+ "rpassword",
+ "serde",
+ "signatory",
+ "thiserror",
+ "tokio 1.5.0",
+ "toml",
+ "tonic",
+ "web30",
+]
+
+[[package]]
+name = "gravity_proto"
+version = "0.1.0"
+dependencies = [
+ "bytes 1.0.1",
+ "cosmos-sdk-proto",
+ "prost",
+ "prost-types",
+ "tonic",
+]
+
+[[package]]
+name = "gravity_utils"
+version = "0.1.0"
+dependencies = [
+ "actix",
+ "clarity",
+ "cosmos-sdk-proto",
+ "deep_space 2.4.3",
+ "gravity_proto",
+ "log",
+ "num-bigint 0.4.0",
+ "num256",
+ "rand 0.8.3",
+ "serde",
+ "serde_derive",
+ "sha3",
+ "tokio 1.5.0",
+ "tonic",
+ "url",
+ "web30",
+]
+
+[[package]]
+name = "group"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912"
+dependencies = [
+ "ff",
+ "rand_core 0.6.2",
+ "subtle",
+]
+
+[[package]]
+name = "gumdrop"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee50908bc1beeac1f2902e0b4e0cd0d844e716f5ebdc6f0cfc1163fe5e10bcde"
+dependencies = [
+ "gumdrop_derive",
+]
+
+[[package]]
+name = "gumdrop_derive"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90454ce4de40b7ca6a8968b5ef367bdab48413962588d0d2b1638d60090c35d7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "h2"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535"
+dependencies = [
+ "bytes 0.5.6",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio 0.2.25",
+ "tokio-util 0.3.1",
+ "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "h2"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726"
+dependencies = [
+ "bytes 1.0.1",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio 1.5.0",
+ "tokio-util 0.6.6",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
+
+[[package]]
+name = "heck"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hkd32"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8"
+dependencies = [
+ "hmac 0.11.0",
+ "once_cell",
+ "pbkdf2 0.8.0",
+ "rand_core 0.6.2",
+ "sha2",
+ "zeroize",
+]
+
+[[package]]
+name = "hmac"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15"
+dependencies = [
+ "crypto-mac 0.10.0",
+ "digest",
+]
+
+[[package]]
+name = "hmac"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
+dependencies = [
+ "crypto-mac 0.11.0",
+ "digest",
+]
+
+[[package]]
+name = "hostname"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
+dependencies = [
+ "libc",
+ "match_cfg",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "http"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
+dependencies = [
+ "bytes 1.0.1",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dfb77c123b4e2f72a2069aeae0b4b4949cc7e966df277813fc16347e7549737"
+dependencies = [
+ "bytes 1.0.1",
+ "http",
+ "pin-project-lite 0.2.6",
+]
+
+[[package]]
+name = "httparse"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68"
+
+[[package]]
+name = "httpdate"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
+
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
+name = "hyper"
+version = "0.14.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11"
+dependencies = [
+ "bytes 1.0.1",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2 0.3.3",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite 0.2.6",
+ "socket2 0.4.0",
+ "tokio 1.5.0",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "idna"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21"
+dependencies = [
+ "matches",
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "indenter"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
+
+[[package]]
+name = "indexmap"
+version = "1.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "iovec"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "ipconfig"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
+dependencies = [
+ "socket2 0.3.19",
+ "widestring",
+ "winapi 0.3.9",
+ "winreg",
+]
+
+[[package]]
+name = "itertools"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+
+[[package]]
+name = "jobserver"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "972f5ae5d1cb9c6ae417789196c803205313edde988685da5e3aae0827b9e7fd"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "k256"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3a26a4a8e8b0ab315c687767b543c923c9667a1f2bf42a42818d1453891c7c1"
+dependencies = [
+ "cfg-if 1.0.0",
+ "ecdsa",
+ "elliptic-curve",
+ "sha2",
+ "sha3",
+]
+
+[[package]]
+name = "keccak"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
+
+[[package]]
+name = "kernel32-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
+dependencies = [
+ "winapi 0.2.8",
+ "winapi-build",
+]
+
+[[package]]
+name = "language-tags"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
+
+[[package]]
+name = "language-tags"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.93"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
+
+[[package]]
+name = "linked-hash-map"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
+
+[[package]]
+name = "local-channel"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6246c68cf195087205a0512559c97e15eaf95198bf0e206d662092cdcb03fe9f"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "local-waker",
+]
+
+[[package]]
+name = "local-waker"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84f9a2d3e27ce99ce2c3aad0b09b1a7b916293ea9b2bf624c13fe646fadd8da4"
+
+[[package]]
+name = "lock_api"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "lru-cache"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
+dependencies = [
+ "linked-hash-map",
+]
+
+[[package]]
+name = "match_cfg"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
+
+[[package]]
+name = "matchers"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
+dependencies = [
+ "regex-automata",
+]
+
+[[package]]
+name = "matches"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+
+[[package]]
+name = "memchr"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
+
+[[package]]
+name = "mime"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
+dependencies = [
+ "adler",
+ "autocfg",
+]
+
+[[package]]
+name = "mio"
+version = "0.6.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
+dependencies = [
+ "cfg-if 0.1.10",
+ "fuchsia-zircon",
+ "fuchsia-zircon-sys",
+ "iovec",
+ "kernel32-sys",
+ "libc",
+ "log",
+ "miow 0.2.2",
+ "net2",
+ "slab",
+ "winapi 0.2.8",
+]
+
+[[package]]
+name = "mio"
+version = "0.7.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
+dependencies = [
+ "libc",
+ "log",
+ "miow 0.3.7",
+ "ntapi",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "mio-uds"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
+dependencies = [
+ "iovec",
+ "libc",
+ "mio 0.6.23",
+]
+
+[[package]]
+name = "miow"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
+dependencies = [
+ "kernel32-sys",
+ "net2",
+ "winapi 0.2.8",
+ "ws2_32-sys",
+]
+
+[[package]]
+name = "miow"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
+dependencies = [
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "multimap"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
+
+[[package]]
+name = "net2"
+version = "0.2.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
+dependencies = [
+ "cfg-if 0.1.10",
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "ntapi"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
+dependencies = [
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "num"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36"
+dependencies = [
+ "num-bigint 0.2.6",
+ "num-complex 0.2.4",
+ "num-integer",
+ "num-iter",
+ "num-rational 0.2.4",
+ "num-traits",
+]
+
+[[package]]
+name = "num"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
+dependencies = [
+ "num-bigint 0.4.0",
+ "num-complex 0.4.0",
+ "num-integer",
+ "num-iter",
+ "num-rational 0.4.0",
+ "num-traits",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d0a3d5e207573f948a9e5376662aa743a2ea13f7c50a554d7af443a73fbfeba"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+ "serde",
+]
+
+[[package]]
+name = "num-complex"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-complex"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "num-derive"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-iter"
+version = "0.1.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-rational"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
+dependencies = [
+ "autocfg",
+ "num-bigint 0.2.6",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-rational"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
+dependencies = [
+ "autocfg",
+ "num-bigint 0.4.0",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num256"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fa34cf745163764b9af28a43f8c9734005651cb6460cb90c0042ad7fb053705"
+dependencies = [
+ "lazy_static",
+ "num 0.4.0",
+ "num-derive",
+ "num-traits",
+ "serde",
+ "serde_derive",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "object"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
+
+[[package]]
+name = "once_cell"
+version = "1.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
+name = "openssl"
+version = "0.10.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577"
+dependencies = [
+ "bitflags",
+ "cfg-if 1.0.0",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
+
+[[package]]
+name = "openssl-src"
+version = "111.15.0+1.1.1k"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1a5f6ae2ac04393b217ea9f700cd04fa9bf3d93fae2872069f3d15d908af70a"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f"
+dependencies = [
+ "autocfg",
+ "cc",
+ "libc",
+ "openssl-src",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "orchestrator"
+version = "0.4.1"
+dependencies = [
+ "actix-rt 2.2.0",
+ "axum",
+ "clarity",
+ "cosmos_gravity",
+ "deep_space 2.4.3",
+ "docopt",
+ "env_logger",
+ "ethereum_gravity",
+ "futures",
+ "gravity_proto",
+ "gravity_utils",
+ "hyper",
+ "lazy_static",
+ "log",
+ "num256",
+ "openssl",
+ "openssl-probe",
+ "prometheus",
+ "rand 0.8.3",
+ "relayer",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tokio 1.5.0",
+ "tonic",
+ "web30",
+]
+
+[[package]]
+name = "owo-colors"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2386b4ebe91c2f7f51082d4cefa145d030e33a1842a96b12e4885cc3c01f7a55"
+
+[[package]]
+name = "parking_lot"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
+dependencies = [
+ "instant",
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
+dependencies = [
+ "cfg-if 1.0.0",
+ "instant",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "password-hash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1a5d4e9c205d2c1ae73b84aab6240e98218c0e72e63b50422cfb2d1ca952282"
+dependencies = [
+ "base64ct",
+ "rand_core 0.6.2",
+ "subtle",
+]
+
+[[package]]
+name = "paste"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
+
+[[package]]
+name = "pbkdf2"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3b8c0d71734018084da0c0354193a5edfb81b20d2d57a92c5b154aefc554a4a"
+dependencies = [
+ "base64",
+ "crypto-mac 0.10.0",
+ "hmac 0.10.1",
+ "rand 0.7.3",
+ "rand_core 0.5.1",
+ "sha2",
+ "subtle",
+]
+
+[[package]]
+name = "pbkdf2"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa"
+dependencies = [
+ "base64ct",
+ "crypto-mac 0.11.0",
+ "hmac 0.11.0",
+ "password-hash",
+ "sha2",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+
+[[package]]
+name = "petgraph"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
+dependencies = [
+ "fixedbitset",
+ "indexmap",
+]
+
+[[package]]
+name = "pin-project"
+version = "0.4.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f"
+dependencies = [
+ "pin-project-internal 0.4.28",
+]
+
+[[package]]
+name = "pin-project"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc174859768806e91ae575187ada95c91a29e96a98dc5d2cd9a1fed039501ba6"
+dependencies = [
+ "pin-project-internal 1.0.6",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "0.4.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a490329918e856ed1b083f244e3bfe2d8c4f336407e4ea9e1a9f479ff09049e5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkcs8"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09d156817ae0125e8aa5067710b0db24f0984830614f99875a70aa5e3b74db69"
+dependencies = [
+ "base64ct",
+ "der",
+ "spki",
+ "zeroize",
+]
+
+[[package]]
+name = "pkg-config"
+version = "0.3.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
+
+[[package]]
+name = "proc-macro-nested"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "prometheus"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5986aa8d62380092d2f50f8b1cdba9cb9b6731ffd4b25b51fd126b6c3e05b99c"
+dependencies = [
+ "cfg-if 1.0.0",
+ "fnv",
+ "lazy_static",
+ "memchr",
+ "parking_lot",
+ "protobuf",
+ "thiserror",
+]
+
+[[package]]
+name = "prost"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e6984d2f1a23009bd270b8bb56d0926810a3d483f59c987d77969e9d8e840b2"
+dependencies = [
+ "bytes 1.0.1",
+ "prost-derive",
+]
+
+[[package]]
+name = "prost-build"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32d3ebd75ac2679c2af3a92246639f9fcc8a442ee420719cc4fe195b98dd5fa3"
+dependencies = [
+ "bytes 1.0.1",
+ "heck",
+ "itertools",
+ "log",
+ "multimap",
+ "petgraph",
+ "prost",
+ "prost-types",
+ "tempfile",
+ "which",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "169a15f3008ecb5160cba7d37bcd690a7601b6d30cfb87a117d45e59d52af5d4"
+dependencies = [
+ "anyhow",
+ "itertools",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b518d7cdd93dab1d1122cf07fa9a60771836c668dde9d9e2a139f957f0d9f1bb"
+dependencies = [
+ "bytes 1.0.1",
+ "prost",
+]
+
+[[package]]
+name = "proto_build"
+version = "0.1.0"
+dependencies = [
+ "prost",
+ "prost-build",
+ "regex",
+ "tempdir",
+ "tonic",
+ "tonic-build",
+ "walkdir",
+]
+
+[[package]]
+name = "protobuf"
+version = "2.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db50e77ae196458ccd3dc58a31ea1a90b0698ab1b7928d89f644c25d72070267"
+
+[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
+[[package]]
+name = "quote"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
+dependencies = [
+ "fuchsia-cprng",
+ "libc",
+ "rand_core 0.3.1",
+ "rdrand",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom 0.1.16",
+ "libc",
+ "rand_chacha 0.2.2",
+ "rand_core 0.5.1",
+ "rand_hc 0.2.0",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
+dependencies = [
+ "libc",
+ "rand_chacha 0.3.0",
+ "rand_core 0.6.2",
+ "rand_hc 0.3.0",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.2",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
+dependencies = [
+ "rand_core 0.4.2",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom 0.1.16",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
+dependencies = [
+ "getrandom 0.2.2",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
+dependencies = [
+ "rand_core 0.6.2",
+]
+
+[[package]]
+name = "rdrand"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
+dependencies = [
+ "byteorder",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+
+[[package]]
+name = "register_delegate_keys"
+version = "0.4.1"
+dependencies = [
+ "actix-rt 2.2.0",
+ "clarity",
+ "contact",
+ "cosmos_gravity",
+ "deep_space 2.4.3",
+ "docopt",
+ "env_logger",
+ "ethereum_gravity",
+ "gravity_proto",
+ "gravity_utils",
+ "lazy_static",
+ "log",
+ "openssl-probe",
+ "rand 0.8.3",
+ "relayer",
+ "serde",
+ "serde_derive",
+ "web30",
+]
+
+[[package]]
+name = "relayer"
+version = "0.4.1"
+dependencies = [
+ "actix",
+ "actix-rt 2.2.0",
+ "clarity",
+ "cosmos_gravity",
+ "deep_space 2.4.3",
+ "docopt",
+ "env_logger",
+ "ethereum_gravity",
+ "gravity_proto",
+ "gravity_utils",
+ "lazy_static",
+ "log",
+ "num256",
+ "openssl-probe",
+ "serde",
+ "serde_derive",
+ "tokio 1.5.0",
+ "tonic",
+ "web30",
+]
+
+[[package]]
+name = "remove_dir_all"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+dependencies = [
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "resolv-conf"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
+dependencies = [
+ "hostname",
+ "quick-error",
+]
+
+[[package]]
+name = "ripemd160"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251"
+dependencies = [
+ "block-buffer",
+ "digest",
+ "opaque-debug",
+]
+
+[[package]]
+name = "rpassword"
+version = "5.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb"
+dependencies = [
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "rust_decimal"
+version = "1.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc7f5b8840fb1f83869a3e1dfd06d93db79ea05311ac5b42b8337d3371caa4f1"
+dependencies = [
+ "arrayvec",
+ "num-traits",
+ "serde",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
+
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+dependencies = [
+ "semver 0.9.0",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "secp256k1"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6179428c22c73ac0fbb7b5579a56353ce78ba29759b3b8575183336ea74cdfb"
+dependencies = [
+ "secp256k1-sys 0.3.0",
+]
+
+[[package]]
+name = "secp256k1"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450"
+dependencies = [
+ "secp256k1-sys 0.4.0",
+]
+
+[[package]]
+name = "secp256k1-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11553d210db090930f4432bea123b31f70bbf693ace14504ea2a35e796c28dd2"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "secp256k1-sys"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "secrecy"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0673d6a6449f5e7d12a1caf424fd9363e2af3a4953023ed455e3c4beef4597c0"
+dependencies = [
+ "serde",
+ "zeroize",
+]
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+dependencies = [
+ "semver-parser",
+]
+
+[[package]]
+name = "semver"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "394cec28fa623e00903caf7ba4fa6fb9a0e260280bb8cdbbba029611108a0190"
+dependencies = [
+ "semver-parser",
+ "serde",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+
+[[package]]
+name = "serde"
+version = "1.0.125"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde-rlp"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69472f967577700225f282233c0625f7b73c371c3953b72d6dcfb91bd0133ca9"
+dependencies = [
+ "byteorder",
+ "error",
+ "num 0.2.1",
+ "serde",
+]
+
+[[package]]
+name = "serde_bytes"
+version = "0.11.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.125"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sha-1"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfebf75d25bd900fd1e7d11501efab59bc846dbc76196839663e6637bba9f25f"
+dependencies = [
+ "block-buffer",
+ "cfg-if 1.0.0",
+ "cpuid-bool",
+ "digest",
+ "opaque-debug",
+]
+
+[[package]]
+name = "sha1"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
+
+[[package]]
+name = "sha2"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de"
+dependencies = [
+ "block-buffer",
+ "cfg-if 1.0.0",
+ "cpuid-bool",
+ "digest",
+ "opaque-debug",
+]
+
+[[package]]
+name = "sha3"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809"
+dependencies = [
+ "block-buffer",
+ "digest",
+ "keccak",
+ "opaque-debug",
+]
+
+[[package]]
+name = "sharded-slab"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "signatory"
+version = "0.23.0-pre.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fbbe064f3bfa8f81121e2320ee3e857caa4d91389a734ca22a3ed47baf1b0f5"
+dependencies = [
+ "pkcs8",
+ "rand_core 0.6.2",
+ "signature",
+ "zeroize",
+]
+
+[[package]]
+name = "signature"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335"
+dependencies = [
+ "digest",
+ "rand_core 0.6.2",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+
+[[package]]
+name = "smallvec"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
+
+[[package]]
+name = "socket2"
+version = "0.3.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "socket2"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
+dependencies = [
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "spki"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "987637c5ae6b3121aba9d513f869bd2bff11c4cc086c22473befd6649c0bd521"
+dependencies = [
+ "der",
+]
+
+[[package]]
+name = "standback"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
+name = "stdweb"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
+dependencies = [
+ "discard",
+ "rustc_version",
+ "stdweb-derive",
+ "stdweb-internal-macros",
+ "stdweb-internal-runtime",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "stdweb-derive"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_derive",
+ "syn",
+]
+
+[[package]]
+name = "stdweb-internal-macros"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
+dependencies = [
+ "base-x",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "sha1",
+ "syn",
+]
+
+[[package]]
+name = "stdweb-internal-runtime"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
+
+[[package]]
+name = "strsim"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "subtle"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
+
+[[package]]
+name = "subtle-encoding"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945"
+dependencies = [
+ "zeroize",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
+]
+
+[[package]]
+name = "tempdir"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
+dependencies = [
+ "rand 0.4.6",
+ "remove_dir_all",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "rand 0.8.3",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "tendermint-proto"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfd0371c6b0c7fc4f6b053b8a1bc868a2a47c49a1408c4cd6f595d9f3bd3c238"
+dependencies = [
+ "anomaly",
+ "bytes 1.0.1",
+ "chrono",
+ "num-derive",
+ "num-traits",
+ "prost",
+ "prost-types",
+ "serde",
+ "serde_bytes",
+ "subtle-encoding",
+ "thiserror",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "test_runner"
+version = "0.1.0"
+dependencies = [
+ "actix",
+ "actix-rt 2.2.0",
+ "actix-web",
+ "clarity",
+ "cosmos_gravity",
+ "deep_space 2.4.3",
+ "docopt",
+ "env_logger",
+ "ethereum_gravity",
+ "futures",
+ "gravity_proto",
+ "gravity_utils",
+ "lazy_static",
+ "log",
+ "num256",
+ "orchestrator",
+ "rand 0.8.3",
+ "serde",
+ "serde_derive",
+ "tokio 1.5.0",
+ "tonic",
+ "url",
+ "web30",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "threadpool"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
+dependencies = [
+ "num_cpus",
+]
+
+[[package]]
+name = "time"
+version = "0.1.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+dependencies = [
+ "libc",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "time"
+version = "0.2.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08a8cbfbf47955132d0202d1662f49b2423ae35862aee471f3ba4b133358f372"
+dependencies = [
+ "const_fn",
+ "libc",
+ "standback",
+ "stdweb",
+ "time-macros",
+ "version_check",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "time-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1"
+dependencies = [
+ "proc-macro-hack",
+ "time-macros-impl",
+]
+
+[[package]]
+name = "time-macros-impl"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa"
+dependencies = [
+ "proc-macro-hack",
+ "proc-macro2",
+ "quote",
+ "standback",
+ "syn",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+
+[[package]]
+name = "tokio"
+version = "0.2.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092"
+dependencies = [
+ "bytes 0.5.6",
+ "futures-core",
+ "iovec",
+ "lazy_static",
+ "libc",
+ "memchr",
+ "mio 0.6.23",
+ "mio-uds",
+ "pin-project-lite 0.1.12",
+ "signal-hook-registry",
+ "slab",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "tokio"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5"
+dependencies = [
+ "autocfg",
+ "bytes 1.0.1",
+ "libc",
+ "memchr",
+ "mio 0.7.11",
+ "num_cpus",
+ "once_cell",
+ "parking_lot",
+ "pin-project-lite 0.2.6",
+ "signal-hook-registry",
+ "tokio-macros",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tokio-openssl"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594"
+dependencies = [
+ "openssl",
+ "tokio 0.2.25",
+]
+
+[[package]]
+name = "tokio-openssl"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac1bec5c0a4aa71e3459802c7a12e8912c2091ce2151004f9ce95cc5d1c6124e"
+dependencies = [
+ "futures",
+ "openssl",
+ "pin-project 1.0.6",
+ "tokio 1.5.0",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e177a5d8c3bf36de9ebe6d58537d8879e964332f93fb3339e43f618c81361af0"
+dependencies = [
+ "futures-core",
+ "pin-project-lite 0.2.6",
+ "tokio 1.5.0",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
+dependencies = [
+ "bytes 0.5.6",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "pin-project-lite 0.1.12",
+ "tokio 0.2.25",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "940a12c99365c31ea8dd9ba04ec1be183ffe4920102bb7122c2f515437601e8e"
+dependencies = [
+ "bytes 1.0.1",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "pin-project-lite 0.2.6",
+ "tokio 1.5.0",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "tonic"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "556dc31b450f45d18279cfc3d2519280273f460d5387e6b7b24503e65d206f8b"
+dependencies = [
+ "async-stream",
+ "async-trait",
+ "base64",
+ "bytes 1.0.1",
+ "futures-core",
+ "futures-util",
+ "h2 0.3.3",
+ "http",
+ "http-body",
+ "hyper",
+ "percent-encoding",
+ "pin-project 1.0.6",
+ "prost",
+ "prost-derive",
+ "tokio 1.5.0",
+ "tokio-stream",
+ "tokio-util 0.6.6",
+ "tower",
+ "tower-service",
+ "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "tonic-build"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c695de27302f4697191dda1c7178131a8cb805463dda02864acb80fe1322fdcf"
+dependencies = [
+ "proc-macro2",
+ "prost-build",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tower"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f715efe02c0862926eb463e49368d38ddb119383475686178e32e26d15d06a66"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "indexmap",
+ "pin-project 1.0.6",
+ "rand 0.8.3",
+ "slab",
+ "tokio 1.5.0",
+ "tokio-stream",
+ "tokio-util 0.6.6",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b56efe69aa0ad2b5da6b942e57ea9f6fe683b7a314d4ff48662e2c8838de1"
+dependencies = [
+ "bytes 1.0.1",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "pin-project 1.0.6",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
+
+[[package]]
+name = "tower-service"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
+
+[[package]]
+name = "tracing"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
+dependencies = [
+ "cfg-if 1.0.0",
+ "log",
+ "pin-project-lite 0.2.6",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "tracing-futures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
+dependencies = [
+ "pin-project 1.0.6",
+ "tracing",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
+dependencies = [
+ "lazy_static",
+ "log",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa5553bf0883ba7c9cbe493b085c29926bd41b66afc31ff72cf17ff4fb60dcd5"
+dependencies = [
+ "ansi_term",
+ "lazy_static",
+ "matchers",
+ "regex",
+ "sharded-slab",
+ "smallvec",
+ "thread_local",
+ "tracing",
+ "tracing-core",
+ "tracing-log",
+]
+
+[[package]]
+name = "traitobject"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
+
+[[package]]
+name = "trust-dns-proto"
+version = "0.19.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cad71a0c0d68ab9941d2fb6e82f8fb2e86d9945b94e1661dd0aaea2b88215a9"
+dependencies = [
+ "async-trait",
+ "cfg-if 1.0.0",
+ "enum-as-inner",
+ "futures",
+ "idna",
+ "lazy_static",
+ "log",
+ "rand 0.7.3",
+ "smallvec",
+ "thiserror",
+ "tokio 0.2.25",
+ "url",
+]
+
+[[package]]
+name = "trust-dns-resolver"
+version = "0.19.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "710f593b371175db53a26d0b38ed2978fafb9e9e8d3868b1acd753ea18df0ceb"
+dependencies = [
+ "cfg-if 0.1.10",
+ "futures",
+ "ipconfig",
+ "lazy_static",
+ "log",
+ "lru-cache",
+ "resolv-conf",
+ "smallvec",
+ "thiserror",
+ "tokio 0.2.25",
+ "trust-dns-proto",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+
+[[package]]
+name = "typeable"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
+
+[[package]]
+name = "typenum"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0"
+dependencies = [
+ "matches",
+]
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+
+[[package]]
+name = "url"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "matches",
+ "percent-encoding",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
+
+[[package]]
+name = "version_check"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
+
+[[package]]
+name = "wait-timeout"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi 0.3.9",
+ "winapi-util",
+]
+
+[[package]]
+name = "want"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+dependencies = [
+ "log",
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "wasi"
+version = "0.10.2+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
+dependencies = [
+ "cfg-if 1.0.0",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
+dependencies = [
+ "bumpalo",
+ "lazy_static",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
+
+[[package]]
+name = "web30"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4268b83b39379f4f8ff24dca0a9001afa637d68f08120a92bc09da042e5a7fda"
+dependencies = [
+ "actix",
+ "awc 3.0.0-beta.6",
+ "clarity",
+ "futures",
+ "lazy_static",
+ "log",
+ "num 0.4.0",
+ "num256",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tokio 1.5.0",
+]
+
+[[package]]
+name = "which"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe"
+dependencies = [
+ "either",
+ "libc",
+]
+
+[[package]]
+name = "widestring"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c"
+
+[[package]]
+name = "winapi"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-build"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "winreg"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
+dependencies = [
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "ws2_32-sys"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
+dependencies = [
+ "winapi 0.2.8",
+ "winapi-build",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81a974bcdd357f0dca4d41677db03436324d45a4c9ed2d0b873a5a360ce41c36"
+dependencies = [
+ "zeroize_derive",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zstd"
+version = "0.7.0+zstd.1.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9428752481d8372e15b1bf779ea518a179ad6c771cca2d2c60e4fbff3cc2cd52"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "3.1.0+zstd.1.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aa1926623ad7fe406e090555387daf73db555b948134b4d73eac5eb08fb666d"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "1.5.0+zstd.1.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e6c094340240369025fc6b731b054ee2a834328fa584310ac96aa4baebdc465"
+dependencies = [
+ "cc",
+ "libc",
+]
diff --git a/orchestrator/Cargo.toml b/orchestrator/Cargo.toml
new file mode 100644
index 0000000..05c72c5
--- /dev/null
+++ b/orchestrator/Cargo.toml
@@ -0,0 +1,15 @@
+[workspace]
+default-members = ["gorc", "orchestrator", "test_runner"]
+members = [
+ "orchestrator",
+ "cosmos_gravity",
+ "ethereum_gravity",
+ "gravity_utils",
+ "proto_build",
+ "test_runner",
+ "gravity_proto",
+ "relayer",
+ "client",
+ "register_delegate_keys",
+ "gorc",
+]
diff --git a/orchestrator/Dockerfile b/orchestrator/Dockerfile
new file mode 100644
index 0000000..1c17c1f
--- /dev/null
+++ b/orchestrator/Dockerfile
@@ -0,0 +1,33 @@
+# Reference: https://www.lpalmieri.com/posts/fast-rust-docker-builds/
+
+FROM rust:1.52 as cargo-chef-rust
+RUN apt-get install bash
+RUN cargo install cargo-chef
+
+FROM cargo-chef-rust as planner
+WORKDIR app
+# We only pay the installation cost once,
+# it will be cached from the second build onwards
+# To ensure a reproducible build consider pinning
+# the cargo-chef version with `--version X.X.X`
+COPY . .
+RUN cargo chef prepare --recipe-path recipe.json
+
+FROM cargo-chef-rust as cacher
+WORKDIR app
+COPY --from=planner /app/recipe.json recipe.json
+RUN cargo chef cook --release --recipe-path recipe.json
+
+FROM cargo-chef-rust as builder
+WORKDIR app
+COPY . .
+# Copy over the cached dependencies
+COPY --from=cacher /app/target target
+COPY --from=cacher /usr/local/cargo /usr/local/cargo
+RUN cargo build --release --bin orchestrator
+
+FROM cargo-chef-rust as runtime
+WORKDIR app
+COPY startup.sh startup.sh
+COPY --from=builder /app/target/release/orchestrator /usr/local/bin
+CMD sh startup.sh
\ No newline at end of file
diff --git a/orchestrator/README.md b/orchestrator/README.md
new file mode 100644
index 0000000..9098347
--- /dev/null
+++ b/orchestrator/README.md
@@ -0,0 +1,121 @@
+# Orchestrator folder
+
+### client/
+
+This folder builds a binary that is a client application for the gravity system. It contains the following commands:
+- `cosmos-to-eth`
+- `eth-to-cosmos`
+- `deploy-erc20-representation`
+
+### cosmos_gravity/
+
+This is a library for interacting with the cosmos chain both queries and transactions. It substantally wraps `gravity_proto`.
+
+### ethereum_gravity/
+
+This is a library that contains code for the interactions with the counterparty ethereum chain.
+
+### gravity_proto/
+
+`prost` generated bindings for working with the gravity protobuf objects.
+
+### gravity_utils/
+
+Various utilities for working with the `gravity` code.
+
+### orchestrator/
+
+The package to build the orchestartor binary.
+
+### proto_build/
+
+Run `cargo run` in this folder to build `gravity_proto` also note, this will generate too many files. Only `gravity.v1.rs` is required.
+
+### register_delegate_keys/
+
+This is a sepreate binary for running a command to register delegate keys for a validator. NOTE: this needs to be done in `gentx` now so this is likely no longer needed.
+
+### relayer/
+
+This is to build the relayer logic (i.e. cosmos to ethereum) as a seperate binary. It also contains the library for the relayer.
+
+### scripts/
+
+Supporting bash scripts for this library
+
+### test_runner/
+
+A binary which runs tests against a cosmos chain
+
+
+## CLI
+
+### CURRENT
+
+```
+client cosmos-to-eth --cosmos-phrase= --cosmos-grpc= --cosmos-prefix= --cosmos-denom= --amount= --eth-destination= [--no-batch] [--times=]
+client eth-to-cosmos --ethereum-key= --ethereum-rpc= --cosmos-prefix= --contract-address= --erc20-address= --amount= --cosmos-destination= [--times=]
+client deploy-erc20-representation --cosmos-grpc= --cosmos-prefix= --cosmos-denom= --ethereum-key= --ethereum-rpc= --contract-address= --erc20-name= --erc20-symbol= --erc20-decimals=
+orchestrator --cosmos-phrase= --ethereum-key= --cosmos-grpc= --address-prefix= --ethereum-rpc= --fees= --contract-address=
+register-delegate-key --validator-phrase= --address-prefix= [--cosmos-phrase=] [--ethereum-key=] --cosmos-grpc= --fees=
+relayer --ethereum-key= --cosmos-grpc= --address-prefix= --ethereum-rpc= --contract-address= --cosmos-grpc=
+test_runner
+```
+
+## PROPOSED
+
+Proposing the name `gorc` for the binary. This is short for `gravity-orchestrator`.
+
+```
+gorc
+ tx
+ eth
+ send-to-cosmos [from-eth-key] [to-cosmos-addr] [erc20 conract] [erc20 amount] [[--times=int]]
+ send [from-key] [to-addr] [amount] [token-contract]
+ cosmos
+ send-to-eth [from-cosmos-key] [to-eth-addr] [erc20-coin] [[--times=int]]
+ send [from-key] [to-addr] [coin-amount]
+ query
+ eth
+ balance [key-name]
+ contract
+ cosmos
+ balance [key-name]
+ gravity-keys [key-name]
+ deploy
+ cosmos-erc20 [denom] [erc20_name] [erc20_symbol] [erc20_decimals]
+ start
+ orchestrator [contract-address] [fee-denom]
+ relayer
+ tests
+ runner
+ keys
+ eth
+ add [name]
+ import [name] [privkey]
+ delete [name]
+ update [name] [new-name]
+ list
+ show [name]
+ cosmos
+ add [name]
+ import [name] [mnemnoic]
+ delete [name]
+ update [name] [new-name]
+ list
+ show [name]
+```
+
+```json
+[gravity]
+ contract = "0x6b175474e89094c44da98b954eedeac495271d0f"
+
+[ethereum]
+key = "testkey"
+rpc = "http://localhost:8545"
+
+[cosmos]
+key = "testkey"
+grpc = "http://localhost:9090"
+prefix = "cosmos"
+```
diff --git a/orchestrator/ci.Dockerfile b/orchestrator/ci.Dockerfile
new file mode 100644
index 0000000..4496bf9
--- /dev/null
+++ b/orchestrator/ci.Dockerfile
@@ -0,0 +1,6 @@
+FROM alpine:edge
+
+COPY target/release/orchestrator /usr/bin/orchestrator
+COPY startup.sh startup.sh
+
+CMD sh startup.sh
\ No newline at end of file
diff --git a/orchestrator/client/Cargo.toml b/orchestrator/client/Cargo.toml
new file mode 100644
index 0000000..b1bd115
--- /dev/null
+++ b/orchestrator/client/Cargo.toml
@@ -0,0 +1,24 @@
+[package]
+name = "client"
+version = "0.4.1"
+authors = ["Justin Kilpatrick "]
+edition = "2018"
+
+[dependencies]
+ethereum_gravity = {path = "../ethereum_gravity"}
+cosmos_gravity = {path = "../cosmos_gravity"}
+gravity_utils = {path = "../gravity_utils"}
+gravity_proto = {path = "../gravity_proto/"}
+
+deep_space ={git="https://github.com/iqlusioninc/deep_space/", branch="zaki/tendermint_0_21"}
+serde_derive = "1.0"
+clarity = "0.4.11"
+docopt = "1"
+serde = "1.0"
+actix-rt = "2.2"
+lazy_static = "1"
+url = "2"
+web30 = "0.14.4"
+env_logger = "0.8"
+openssl-probe = "0.1"
+tokio = "1.4"
\ No newline at end of file
diff --git a/orchestrator/client/src/main.rs b/orchestrator/client/src/main.rs
new file mode 100644
index 0000000..2618483
--- /dev/null
+++ b/orchestrator/client/src/main.rs
@@ -0,0 +1,302 @@
+//! This file is the binary entry point for the Gravity client software, an easy to use cli utility that
+//! allows anyone to send funds across the Gravity bridge. Currently this application only does anything
+//! on the Ethereum side of the bridge since withdraw batches are incomplete.
+
+// there are several binaries for this crate if we allow dead code on all of them
+// we will see functions not used in one binary as dead code. In order to fix that
+// we forbid dead code in all but the 'main' binary
+#![allow(dead_code)]
+
+#[macro_use]
+extern crate serde_derive;
+#[macro_use]
+extern crate lazy_static;
+
+use clarity::Address as EthAddress;
+use clarity::PrivateKey as EthPrivateKey;
+use clarity::Uint256;
+use cosmos_gravity::send::{send_request_batch_tx, send_to_eth};
+use deep_space::address::Address as CosmosAddress;
+use deep_space::{coin::Coin, private_key::PrivateKey as CosmosPrivateKey};
+use docopt::Docopt;
+use env_logger::Env;
+use ethereum_gravity::send_to_cosmos::send_to_cosmos;
+use gravity_proto::gravity::DenomToErc20Request;
+use gravity_utils::connection_prep::{check_for_eth, check_for_fee_denom, create_rpc_connections};
+use std::{process::exit, time::Duration};
+
+const TIMEOUT: Duration = Duration::from_secs(60);
+
+pub fn one_eth() -> f64 {
+ 1000000000000000000f64
+}
+
+pub fn one_atom() -> f64 {
+ 1000000f64
+}
+
+pub fn print_eth(input: Uint256) -> String {
+ let float: f64 = input.to_string().parse().unwrap();
+ let res = float / one_eth();
+ format!("{}", res)
+}
+
+pub fn print_atom(input: Uint256) -> String {
+ let float: f64 = input.to_string().parse().unwrap();
+ let res = float / one_atom();
+ format!("{}", res)
+}
+
+#[derive(Debug, Deserialize)]
+struct Args {
+ flag_cosmos_phrase: String,
+ flag_ethereum_key: String,
+ flag_cosmos_grpc: String,
+ flag_ethereum_rpc: String,
+ flag_contract_address: String,
+ flag_cosmos_denom: String,
+ flag_amount: Option,
+ flag_cosmos_destination: String,
+ flag_erc20_address: String,
+ flag_eth_destination: String,
+ flag_no_batch: bool,
+ flag_times: usize,
+ flag_cosmos_prefix: String,
+ cmd_eth_to_cosmos: bool,
+ cmd_cosmos_to_eth: bool,
+}
+
+lazy_static! {
+ pub static ref USAGE: String = format!(
+ "Usage:
+ {} cosmos-to-eth --cosmos-phrase= --cosmos-grpc= --cosmos-prefix= --cosmos-denom= --amount= --eth-destination= [--no-batch] [--times=]
+ {} eth-to-cosmos --ethereum-key= --ethereum-rpc= --cosmos-prefix= --contract-address= --erc20-address= --amount= --cosmos-destination= [--times=]
+ Options:
+ -h --help Show this screen.
+ --cosmos-phrase= The mnenmonic of the Cosmos account key of the validator
+ --ethereum-key= The Ethereum private key of the sender
+ --cosmos-legacy-rpc= The Cosmos Legacy RPC url, this will need to be manually enabled
+ --cosmos-grpc= The Cosmos gRPC url
+ --cosmos-prefix= The Bech32 Prefix used for the Cosmos chain's addresses
+ --ethereum-rpc= The Ethereum RPC url, should be a self hosted node
+ --contract-address= The Ethereum contract address for Gravity, this is temporary
+ --erc20-address= An erc20 address on Ethereum to send funds from
+ --cosmos-denom= The Cosmos denom that you intend to send to Ethereum
+ --amount= The amount of tokens to send, for example 1.5
+ --cosmos-destination= A cosmos address to send tokens to
+ --eth-destination= A cosmos address to send tokens to
+ --no-batch Don't request a batch when sending to Ethereum
+ --times= The number of times this send should be preformed, useful for stress testing
+ Description:
+ cosmos-to-eth Locks up a Cosmos asset in the batch pool. Optionally this command will also request a batch.
+ eth-to-cosmos Sends an Ethereum ERC20 asset to a Cosmos destination address
+ deploy-erc20-representation Deploys an ERC20 representation for a Cosmos asset, required to bridge a Cosmos native asset with 'cosmos-to-eth'
+ About:
+ Althea Gravity client software, moves tokens from Ethereum to Cosmos and back
+ Written By: {}
+ Version {}",
+ env!("CARGO_PKG_NAME"),
+ env!("CARGO_PKG_NAME"),
+ env!("CARGO_PKG_AUTHORS"),
+ env!("CARGO_PKG_VERSION"),
+ );
+}
+
+#[actix_rt::main]
+async fn main() {
+ env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
+ // On Linux static builds we need to probe ssl certs path to be able to
+ // do TLS stuff.
+ openssl_probe::init_ssl_cert_env_vars();
+ let args: Args = Docopt::new(USAGE.as_str())
+ .and_then(|d| d.deserialize())
+ .unwrap_or_else(|e| e.exit());
+
+ let times = if args.flag_times == 0 {
+ 1usize
+ } else {
+ args.flag_times
+ };
+
+ if args.cmd_cosmos_to_eth {
+ let gravity_denom = args.flag_cosmos_denom;
+ // todo actually query metadata for this
+ let is_cosmos_originated = !gravity_denom.starts_with("gravity");
+ let amount = args.flag_amount.unwrap().parse().unwrap();
+ let cosmos_key = CosmosPrivateKey::from_phrase(&args.flag_cosmos_phrase, "")
+ .expect("Failed to parse cosmos key phrase, does it have a password?");
+ let cosmos_address = cosmos_key.to_address(&args.flag_cosmos_prefix).unwrap();
+
+ println!("Sending from Cosmos address {}", cosmos_address);
+ let connections = create_rpc_connections(
+ args.flag_cosmos_prefix,
+ Some(args.flag_cosmos_grpc),
+ None,
+ TIMEOUT,
+ )
+ .await;
+ let contact = connections.contact.unwrap();
+ let mut grpc = connections.grpc.unwrap();
+
+ let res = grpc
+ .denom_to_erc20(DenomToErc20Request {
+ denom: gravity_denom.clone(),
+ })
+ .await;
+ match res {
+ Ok(val) => println!(
+ "Asset {} has ERC20 representation {}",
+ gravity_denom,
+ val.into_inner().erc20
+ ),
+ Err(_e) => {
+ println!(
+ "Asset {} has no ERC20 representation, you may need to deploy an ERC20 for it!",
+ gravity_denom
+ );
+ exit(1);
+ }
+ }
+
+ let amount = Coin {
+ amount,
+ denom: gravity_denom.clone(),
+ };
+ let bridge_fee = Coin {
+ denom: gravity_denom.clone(),
+ amount: 1u64.into(),
+ };
+ let eth_dest: EthAddress = args.flag_eth_destination.parse().unwrap();
+ check_for_fee_denom(&gravity_denom, cosmos_address, &contact).await;
+
+ let balances = contact
+ .get_balances(cosmos_address)
+ .await
+ .expect("Failed to get balances!");
+ let mut found = None;
+ for coin in balances.iter() {
+ if coin.denom == gravity_denom {
+ found = Some(coin);
+ }
+ }
+
+ println!("Cosmos balances {:?}", balances);
+
+ if found.is_none() {
+ panic!("You don't have any {} tokens!", gravity_denom);
+ } else if amount.amount.clone() * times.into() >= found.clone().unwrap().amount
+ && times == 1
+ {
+ if is_cosmos_originated {
+ panic!("Your transfer of {} {} tokens is greater than your balance of {} tokens. Remember you need some to pay for fees!", print_atom(amount.amount), gravity_denom, print_atom(found.unwrap().amount.clone()));
+ } else {
+ panic!("Your transfer of {} {} tokens is greater than your balance of {} tokens. Remember you need some to pay for fees!", print_eth(amount.amount), gravity_denom, print_eth(found.unwrap().amount.clone()));
+ }
+ } else if amount.amount.clone() * times.into() >= found.clone().unwrap().amount {
+ if is_cosmos_originated {
+ panic!("Your transfer of {} * {} {} tokens is greater than your balance of {} tokens. Try to reduce the amount or the --times parameter", print_atom(amount.amount), times, gravity_denom, print_atom(found.unwrap().amount.clone()));
+ } else {
+ panic!("Your transfer of {} * {} {} tokens is greater than your balance of {} tokens. Try to reduce the amount or the --times parameter", print_eth(amount.amount), times, gravity_denom, print_eth(found.unwrap().amount.clone()));
+ }
+ }
+
+ for _ in 0..times {
+ println!(
+ "Locking {} / {} into the batch pool",
+ amount.clone(),
+ gravity_denom
+ );
+ let res = send_to_eth(
+ cosmos_key,
+ eth_dest,
+ amount.clone(),
+ bridge_fee.clone(),
+ &contact,
+ )
+ .await;
+ match res {
+ Ok(tx_id) => println!("Send to Eth txid {}", tx_id.txhash),
+ Err(e) => println!("Failed to send tokens! {:?}", e),
+ }
+ }
+
+ if !args.flag_no_batch {
+ println!("Requesting a batch to push transaction along immediately");
+ send_request_batch_tx(cosmos_key, gravity_denom, bridge_fee, &contact)
+ .await
+ .expect("Failed to request batch");
+ } else {
+ println!("--no-batch specified, your transfer will wait until someone requests a batch for this token type")
+ }
+ } else if args.cmd_eth_to_cosmos {
+ let erc20_address: EthAddress = args
+ .flag_erc20_address
+ .parse()
+ .expect("Invalid ERC20 contract address!");
+ let ethereum_key: EthPrivateKey = args
+ .flag_ethereum_key
+ .parse()
+ .expect("Invalid Ethereum private key!");
+ let contract_address: EthAddress = args
+ .flag_contract_address
+ .parse()
+ .expect("Invalid contract address!");
+ let connections = create_rpc_connections(
+ args.flag_cosmos_prefix,
+ None,
+ Some(args.flag_ethereum_rpc),
+ TIMEOUT,
+ )
+ .await;
+ let web3 = connections.web3.unwrap();
+ let cosmos_dest: CosmosAddress = args.flag_cosmos_destination.parse().unwrap();
+ let ethereum_public_key = ethereum_key.to_public_key().unwrap();
+ check_for_eth(ethereum_public_key, &web3).await;
+
+ let amount: Uint256 = args.flag_amount.unwrap().parse().unwrap();
+
+ let erc20_balance = web3
+ .get_erc20_balance(erc20_address, ethereum_public_key)
+ .await
+ .expect("Failed to get balance, check ERC20 contract address");
+
+ if erc20_balance == 0u8.into() {
+ panic!(
+ "You have zero {} tokens, please double check your sender and erc20 addresses!",
+ contract_address
+ );
+ } else if amount.clone() * times.into() > erc20_balance {
+ panic!(
+ "Insufficient balance {} > {}",
+ amount * times.into(),
+ erc20_balance
+ );
+ }
+
+ for _ in 0..times {
+ println!(
+ "Sending {} / {} to Cosmos from {} to {}",
+ amount.clone(),
+ erc20_address,
+ ethereum_public_key,
+ cosmos_dest
+ );
+ // we send some erc20 tokens to the gravity contract to register a deposit
+ let res = send_to_cosmos(
+ erc20_address,
+ contract_address,
+ amount.clone(),
+ cosmos_dest,
+ ethereum_key,
+ Some(TIMEOUT),
+ &web3,
+ vec![],
+ )
+ .await;
+ match res {
+ Ok(tx_id) => println!("Send to Cosmos txid: {:#066x}", tx_id),
+ Err(e) => println!("Failed to send tokens! {:?}", e),
+ }
+ }
+ }
+}
diff --git a/orchestrator/cosmos_gravity/Cargo.toml b/orchestrator/cosmos_gravity/Cargo.toml
new file mode 100644
index 0000000..33cbeef
--- /dev/null
+++ b/orchestrator/cosmos_gravity/Cargo.toml
@@ -0,0 +1,31 @@
+[package]
+name = "cosmos_gravity"
+version = "0.1.0"
+authors = ["Justin Kilpatrick "]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+gravity_utils = {path = "../gravity_utils"}
+ethereum_gravity = {path = "../ethereum_gravity"}
+gravity_proto = {path = "../gravity_proto/"}
+
+deep_space ={git="https://github.com/iqlusioninc/deep_space/", branch="zaki/tendermint_0_21"}
+clarity = "0.4.11"
+serde = "1.0"
+num256 = "0.3"
+log = "0.4"
+sha3 = "0.9"
+tokio = "1.4"
+web30 = "0.14.4"
+tonic = "0.4"
+cosmos-sdk-proto = {git="http://github.com/cosmos/cosmos-rust", branch="main"}
+prost = "0.7"
+prost-types = "0.7"
+bytes = "1"
+
+[dev-dependencies]
+env_logger = "0.8"
+rand = "0.8"
+actix = "0.11"
\ No newline at end of file
diff --git a/orchestrator/cosmos_gravity/src/build.rs b/orchestrator/cosmos_gravity/src/build.rs
new file mode 100644
index 0000000..ec1bb1e
--- /dev/null
+++ b/orchestrator/cosmos_gravity/src/build.rs
@@ -0,0 +1,213 @@
+use clarity::PrivateKey as EthPrivateKey;
+use deep_space::private_key::PrivateKey as CosmosPrivateKey;
+use deep_space::utils::bytes_to_hex_str;
+use deep_space::Contact;
+use deep_space::Msg;
+use ethereum_gravity::utils::downcast_uint256;
+use gravity_proto::gravity as proto;
+use gravity_proto::ToAny;
+use gravity_utils::message_signatures::{
+ encode_logic_call_confirm, encode_tx_batch_confirm, encode_valset_confirm,
+};
+use gravity_utils::types::*;
+
+pub fn signer_set_tx_confirmation_messages(
+ contact: &Contact,
+ ethereum_key: EthPrivateKey,
+ valsets: Vec,
+ cosmos_key: CosmosPrivateKey,
+ gravity_id: String,
+) -> Vec {
+ let cosmos_address = cosmos_key.to_address(&contact.get_prefix()).unwrap();
+ let ethereum_address = ethereum_key.to_public_key().unwrap();
+
+ let mut msgs = Vec::new();
+ for valset in valsets {
+ let data = encode_valset_confirm(gravity_id.clone(), valset.clone());
+ let signature = ethereum_key.sign_ethereum_msg(&data);
+ let confirmation = proto::SignerSetTxConfirmation {
+ ethereum_signer: ethereum_address.to_string(),
+ signer_set_nonce: valset.nonce,
+ signature: signature.to_bytes().to_vec(),
+ };
+ let msg = proto::MsgSubmitEthereumTxConfirmation {
+ signer: cosmos_address.to_string(),
+ confirmation: confirmation.to_any(),
+ };
+ let msg = Msg::new("/gravity.v1.MsgSubmitEthereumTxConfirmation", msg);
+ msgs.push(msg);
+ }
+ msgs
+}
+
+pub fn batch_tx_confirmation_messages(
+ contact: &Contact,
+ ethereum_key: EthPrivateKey,
+ batches: Vec,
+ cosmos_key: CosmosPrivateKey,
+ gravity_id: String,
+) -> Vec {
+ let cosmos_address = cosmos_key.to_address(&contact.get_prefix()).unwrap();
+ let ethereum_address = ethereum_key.to_public_key().unwrap();
+
+ let mut msgs = Vec::new();
+ for batch in batches {
+ let data = encode_tx_batch_confirm(gravity_id.clone(), batch.clone());
+ let signature = ethereum_key.sign_ethereum_msg(&data);
+ let confirmation = proto::BatchTxConfirmation {
+ token_contract: batch.token_contract.to_string(),
+ batch_nonce: batch.nonce,
+ ethereum_signer: ethereum_address.to_string(),
+ signature: signature.to_bytes().to_vec(),
+ };
+ let msg = proto::MsgSubmitEthereumEvent {
+ signer: cosmos_address.to_string(),
+ event: confirmation.to_any(),
+ };
+ let msg = Msg::new("/gravity.v1.MsgSubmitEthereumTxConfirmation", msg);
+ msgs.push(msg);
+ }
+ msgs
+}
+
+pub fn contract_call_tx_confirmation_messages(
+ contact: &Contact,
+ ethereum_key: EthPrivateKey,
+ logic_calls: Vec,
+ cosmos_key: CosmosPrivateKey,
+ gravity_id: String,
+) -> Vec {
+ let cosmos_address = cosmos_key.to_address(&contact.get_prefix()).unwrap();
+ let ethereum_address = ethereum_key.to_public_key().unwrap();
+
+ let mut msgs = Vec::new();
+ for logic_call in logic_calls {
+ let data = encode_logic_call_confirm(gravity_id.clone(), logic_call.clone());
+ let signature = ethereum_key.sign_ethereum_msg(&data);
+ let confirmation = proto::ContractCallTxConfirmation {
+ ethereum_signer: ethereum_address.to_string(),
+ signature: signature.to_bytes().to_vec(),
+ invalidation_scope: bytes_to_hex_str(&logic_call.invalidation_id)
+ .as_bytes()
+ .to_vec(),
+ invalidation_nonce: logic_call.invalidation_nonce,
+ };
+ let msg = proto::MsgSubmitEthereumTxConfirmation {
+ signer: cosmos_address.to_string(),
+ confirmation: confirmation.to_any(),
+ };
+ let msg = Msg::new("/gravity.v1.MsgSubmitEthereumTxConfirmation", msg);
+ msgs.push(msg);
+ }
+ msgs
+}
+
+pub fn ethereum_event_messages(
+ contact: &Contact,
+ cosmos_key: CosmosPrivateKey,
+ deposits: Vec,
+ batches: Vec,
+ erc20_deploys: Vec,
+ logic_calls: Vec,
+ valsets: Vec,
+) -> Vec {
+ let cosmos_address = cosmos_key.to_address(&contact.get_prefix()).unwrap();
+
+ // This sorts oracle messages by event nonce before submitting them. It's not a pretty implementation because
+ // we're missing an intermediary layer of abstraction. We could implement 'EventTrait' and then implement sort
+ // for it, but then when we go to transform 'EventTrait' objects into GravityMsg enum values we'll have all sorts
+ // of issues extracting the inner object from the TraitObject. Likewise we could implement sort of GravityMsg but that
+ // would require a truly horrendous (nearly 100 line) match statement to deal with all combinations. That match statement
+ // could be reduced by adding two traits to sort against but really this is the easiest option.
+ //
+ // We index the events by event nonce in an unordered hashmap and then play them back in order into a vec
+ let mut unordered_msgs = std::collections::HashMap::new();
+ for deposit in deposits {
+ let event = proto::SendToCosmosEvent {
+ event_nonce: downcast_uint256(deposit.event_nonce.clone()).unwrap(),
+ ethereum_height: downcast_uint256(deposit.block_height).unwrap(),
+ token_contract: deposit.erc20.to_string(),
+ amount: deposit.amount.to_string(),
+ cosmos_receiver: deposit.destination.to_string(),
+ ethereum_sender: deposit.sender.to_string(),
+ };
+ let msg = proto::MsgSubmitEthereumEvent {
+ signer: cosmos_address.to_string(),
+ event: event.to_any(),
+ };
+ let msg = Msg::new("/gravity.v1.MsgSubmitEthereumEvent", msg);
+ unordered_msgs.insert(deposit.event_nonce, msg);
+ }
+ for batch in batches {
+ let event = proto::BatchExecutedEvent {
+ event_nonce: downcast_uint256(batch.event_nonce.clone()).unwrap(),
+ batch_nonce: downcast_uint256(batch.batch_nonce.clone()).unwrap(),
+ ethereum_height: downcast_uint256(batch.block_height).unwrap(),
+ token_contract: batch.erc20.to_string(),
+ };
+ let msg = proto::MsgSubmitEthereumEvent {
+ signer: cosmos_address.to_string(),
+ event: event.to_any(),
+ };
+ let msg = Msg::new("/gravity.v1.MsgSubmitEthereumEvent", msg);
+ unordered_msgs.insert(batch.event_nonce, msg);
+ }
+ for deploy in erc20_deploys {
+ let event = proto::Erc20DeployedEvent {
+ event_nonce: downcast_uint256(deploy.event_nonce.clone()).unwrap(),
+ ethereum_height: downcast_uint256(deploy.block_height).unwrap(),
+ cosmos_denom: deploy.cosmos_denom,
+ token_contract: deploy.erc20_address.to_string(),
+ erc20_name: deploy.name,
+ erc20_symbol: deploy.symbol,
+ erc20_decimals: deploy.decimals as u64,
+ };
+ let msg = proto::MsgSubmitEthereumEvent {
+ signer: cosmos_address.to_string(),
+ event: event.to_any(),
+ };
+ let msg = Msg::new("/gravity.v1.MsgSubmitEthereumEvent", msg);
+ unordered_msgs.insert(deploy.event_nonce, msg);
+ }
+ for logic_call in logic_calls {
+ let event = proto::ContractCallExecutedEvent {
+ event_nonce: downcast_uint256(logic_call.event_nonce.clone()).unwrap(),
+ ethereum_height: downcast_uint256(logic_call.block_height).unwrap(),
+ invalidation_id: logic_call.invalidation_id,
+ invalidation_nonce: downcast_uint256(logic_call.invalidation_nonce).unwrap(),
+ };
+ let msg = proto::MsgSubmitEthereumEvent {
+ signer: cosmos_address.to_string(),
+ event: event.to_any(),
+ };
+ let msg = Msg::new("/gravity.v1.MsgSubmitEthereumEvent", msg);
+ unordered_msgs.insert(logic_call.event_nonce, msg);
+ }
+ for valset in valsets {
+ let event = proto::SignerSetTxExecutedEvent {
+ event_nonce: downcast_uint256(valset.event_nonce.clone()).unwrap(),
+ signer_set_tx_nonce: downcast_uint256(valset.valset_nonce.clone()).unwrap(),
+ ethereum_height: downcast_uint256(valset.block_height).unwrap(),
+ members: valset.members.iter().map(|v| v.into()).collect(),
+ };
+ let msg = proto::MsgSubmitEthereumEvent {
+ signer: cosmos_address.to_string(),
+ event: event.to_any(),
+ };
+ let msg = Msg::new("/gravity.v1.MsgSubmitEthereumEvent", msg);
+ unordered_msgs.insert(valset.event_nonce, msg);
+ }
+
+ let mut keys = Vec::new();
+ for (key, _) in unordered_msgs.iter() {
+ keys.push(key.clone());
+ }
+ keys.sort();
+
+ let mut msgs = Vec::new();
+ for i in keys.iter() {
+ msgs.push(unordered_msgs.remove_entry(&i).unwrap().1);
+ }
+
+ msgs
+}
diff --git a/orchestrator/cosmos_gravity/src/lib.rs b/orchestrator/cosmos_gravity/src/lib.rs
new file mode 100644
index 0000000..6da7941
--- /dev/null
+++ b/orchestrator/cosmos_gravity/src/lib.rs
@@ -0,0 +1,12 @@
+//! This crate contains various components and utilities for interacting with the Gravity Cosmos module. Primarily
+//! Extensions to Althea's 'deep_space' Cosmos transaction library to allow it to send Gravity module specific messages
+//! parse Gravity module specific endpoints and generally interact with the multitude of Gravity specific functionality
+//! that's part of the Cosmos module.
+
+#[macro_use]
+extern crate log;
+
+pub mod build;
+pub mod query;
+pub mod send;
+pub mod utils;
\ No newline at end of file
diff --git a/orchestrator/cosmos_gravity/src/query.rs b/orchestrator/cosmos_gravity/src/query.rs
new file mode 100644
index 0000000..e40eb71
--- /dev/null
+++ b/orchestrator/cosmos_gravity/src/query.rs
@@ -0,0 +1,194 @@
+use clarity::Address as EthAddress;
+use deep_space::address::Address;
+use gravity_proto::gravity::query_client::QueryClient as GravityQueryClient;
+use gravity_proto::gravity::*;
+use gravity_utils::error::GravityError;
+use gravity_utils::types::*;
+use tonic::transport::Channel;
+
+/// get the valset for a given nonce (block) height
+pub async fn get_valset(
+ client: &mut GravityQueryClient,
+ nonce: u64,
+) -> Result