forked from cerc-io/laconicd-deprecated
Compare commits
347
Commits
v0.1.0-dev
...
docs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f4ebc4648 | ||
|
|
e9f8aa04f9 | ||
|
|
1c023f7b5d | ||
|
|
f04ee6eaa8 | ||
|
|
93a8da40e8 | ||
|
|
b18840607f | ||
|
|
7f4ee8313f | ||
|
|
559159c30d | ||
|
|
f89c866f50 | ||
|
|
fc06fbfb48 | ||
|
|
20ce3dfb3d | ||
|
|
ac5fd42bbf | ||
|
|
eb0948b2c6 | ||
|
|
dde1038571 | ||
|
|
e5cad8c48b | ||
|
|
808a7fe2b3 | ||
|
|
007e27dcbc | ||
|
|
399bf4f69f | ||
|
|
137a781bee | ||
|
|
a75f275f3e | ||
|
|
92295c3061 | ||
|
|
11e82761b4 | ||
|
|
1bbb2d7f42 | ||
|
|
f9c4f75f76 | ||
|
|
26238a6f2f | ||
|
|
b34e83a29a | ||
|
|
d0fba5b727 | ||
|
|
f705908614 | ||
|
|
fd887f80bc | ||
|
|
49cd996e80 | ||
|
|
2c9d18fd93 | ||
|
|
b1f755db7b | ||
|
|
bfb702009a | ||
|
|
54e49b83e7 | ||
|
|
68187bc75b | ||
|
|
4040c3425f | ||
|
|
9de27fb24f | ||
|
|
a7aff81d32 | ||
|
|
264aa45492 | ||
|
|
00814e2714 | ||
|
|
3f946920ad | ||
|
|
d9c6ab8740 | ||
|
|
075978b906 | ||
|
|
3f77c8886a | ||
|
|
21026234fb | ||
|
|
8beea8811d | ||
|
|
75763bf1c4 | ||
|
|
d1c4da99b9 | ||
|
|
dda48584a5 | ||
|
|
760cddf698 | ||
|
|
752fb3944f | ||
|
|
eb1af33649 | ||
|
|
63b66c1ffc | ||
|
|
fde19d25ad | ||
|
|
8ae41eb7cc | ||
|
|
19b1635e00 | ||
|
|
de5fc87573 | ||
|
|
e6d416db7f | ||
|
|
694d4c667d | ||
|
|
e20e7c24c8 | ||
|
|
e8b0e2cf30 | ||
|
|
fd59a37798 | ||
|
|
cf0be98f9b | ||
|
|
9d7333d4fb | ||
|
|
feae504ff8 | ||
|
|
cfeeece6bd | ||
|
|
e3f97b1df9 | ||
|
|
a7f8611858 | ||
|
|
de7c0558c9 | ||
|
|
9d4c381e1a | ||
|
|
2ea883bc50 | ||
|
|
92791d5f9d | ||
|
|
92f07873f4 | ||
|
|
7f70108a4a | ||
|
|
8477b3d9cb | ||
|
|
f7623b26f9 | ||
|
|
d762ce98b3 | ||
|
|
8f5449f397 | ||
|
|
d377665800 | ||
|
|
8cd1189e8c | ||
|
|
a0e2858d4f | ||
|
|
2b8b18d659 | ||
|
|
555934b799 | ||
|
|
39b742874c | ||
|
|
2a6383ed99 | ||
|
|
8513dc1ffe | ||
|
|
a1ab3e9c23 | ||
|
|
75ae6efb5f | ||
|
|
4b0940deeb | ||
|
|
df6dce0e3a | ||
|
|
a4fc953e1a | ||
|
|
dd114a939f | ||
|
|
24e0a75673 | ||
|
|
56bd697701 | ||
|
|
4aef5ff22a | ||
|
|
548f2a7b92 | ||
|
|
401e351080 | ||
|
|
96393bfc36 | ||
|
|
e90b21bc8e | ||
|
|
4ddc8afd18 | ||
|
|
d19e38833c | ||
|
|
4687710908 | ||
|
|
70d52948da | ||
|
|
a6e0210375 | ||
|
|
42b5e443da | ||
|
|
bde62e2d31 | ||
|
|
9807d7c6de | ||
|
|
01bc2ec170 | ||
|
|
b4ce7cac60 | ||
|
|
8bcdb2c0e5 | ||
|
|
93a57bc330 | ||
|
|
edf456985b | ||
|
|
889ff2b8ec | ||
|
|
575c8e7183 | ||
|
|
5360730d42 | ||
|
|
49afc0f90d | ||
|
|
6b88b26a40 | ||
|
|
d04787e97f | ||
|
|
50e093a6d2 | ||
|
|
ef202505d1 | ||
|
|
dbe9f705cd | ||
|
|
67fba0a813 | ||
|
+1 |
cfbd98011a | ||
|
|
77d9e29923 | ||
|
|
805b2eada5 | ||
|
|
caa1c5a6c6 | ||
|
|
40d5eff9fa | ||
|
|
eb4631fb81 | ||
|
|
4e2236a6fb | ||
|
+1 |
4aa5d0b26a | ||
|
|
3bea3fa1ef | ||
|
|
0d69a69625 | ||
|
|
19a1be61c7 | ||
|
|
e41c713ffb | ||
|
|
a2c26208ed | ||
|
|
6095794cf0 | ||
|
|
bf54193669 | ||
|
|
f21592ebfe | ||
|
|
dcd2891b73 | ||
|
|
0f5b1aa929 | ||
|
|
bd0f073704 | ||
|
|
d02cc63c2f | ||
|
|
f7009b0e94 | ||
|
|
aeedef9b4b | ||
|
|
1baccfaee5 | ||
|
|
b51907a949 | ||
|
|
e16b7f8ab0 | ||
|
|
7b22a53556 | ||
|
|
f32288b16d | ||
|
|
03a03b211a | ||
|
|
4ccc17324b | ||
|
|
628a7fa18e | ||
|
|
724a06632b | ||
|
|
e39a74998e | ||
|
|
fd3c803b44 | ||
|
|
04f595d3d5 | ||
|
|
43c4d7c3fb | ||
|
|
0a01cead67 | ||
|
|
317f5b43b5 | ||
|
|
351e6d6eb3 | ||
|
|
0b92af406a | ||
|
|
7d8664043e | ||
|
|
aeb6aeb715 | ||
|
|
cad7545f8a | ||
|
|
5e15c64d02 | ||
|
|
e6c9b7723b | ||
|
|
f5b61e914e | ||
|
|
4320f46fc8 | ||
|
|
eea80d50c3 | ||
|
|
8eaffe88a5 | ||
|
|
2a58069002 | ||
|
|
4ec794204c | ||
|
|
ade84319e6 | ||
|
|
e9f1ab646c | ||
|
|
03768c20cb | ||
|
|
8e4ff5aae2 | ||
|
|
7c53e32c78 | ||
|
|
7ec5e5fdef | ||
|
|
d34aa09610 | ||
|
|
b9804505a3 | ||
|
|
9f4828e5bb | ||
|
|
4cb2737647 | ||
|
|
42cd3f5a4d | ||
|
|
ced5280571 | ||
|
|
fdfe3d9761 | ||
|
|
eb17366dcc | ||
|
|
d822fee5c1 | ||
|
|
8bc3cc471b | ||
|
|
0777d0b670 | ||
|
|
bd2c7f2072 | ||
|
|
fd338cbf6b | ||
|
|
e437c4331d | ||
|
|
514785bd89 | ||
|
|
e752d80e9f | ||
|
|
845bef6dab | ||
|
|
09013d7ea0 | ||
|
|
9cf098b047 | ||
|
|
86def86fee | ||
|
|
9828964f1f | ||
|
|
66292080e4 | ||
|
|
ccc6f5b53d | ||
|
|
50e463725e | ||
|
|
5d237a5ee4 | ||
|
|
68f1d1c8e6 | ||
|
|
924232f02e | ||
|
|
423944bf79 | ||
|
|
a2f246c2a6 | ||
|
|
4ee1d86377 | ||
|
|
8333765b27 | ||
|
|
876d9cfee3 | ||
|
|
1737e654f1 | ||
|
|
54fa882ab8 | ||
|
|
9219fb710b | ||
|
|
b6b4ae8e26 | ||
|
|
4e87775f68 | ||
|
|
11a1225ebd | ||
|
|
705893c0ac | ||
|
|
3b0fa63832 | ||
|
|
e6d0eff957 | ||
|
|
91b042b653 | ||
|
|
5a491537ca | ||
|
|
5d2798aa7e | ||
|
|
ee72632582 | ||
|
|
841c93cd65 | ||
|
|
bfe059e43e | ||
|
|
c8d4d3f9a3 | ||
|
|
2d8be4e85b | ||
|
|
32eaec8d99 | ||
|
|
16db5cabb5 | ||
|
|
afe15fefe4 | ||
|
|
2bf2b6758b | ||
|
|
5ece791395 | ||
|
|
be8fd869ff | ||
|
|
93020f8786 | ||
|
|
d6a6bb5c9d | ||
|
|
77fee0e882 | ||
|
|
392d1dd8cf | ||
|
|
b7e8dd8216 | ||
|
|
e96a4b9f9d | ||
|
|
fdabf69cb3 | ||
|
|
d922441bec | ||
|
|
d4621f3e82 | ||
|
|
f42f339d05 | ||
|
|
32c905ab87 | ||
|
|
481e3b82ce | ||
|
|
72c1098972 | ||
|
|
a874c1e1ca | ||
|
|
a3f1d8d89d | ||
|
|
d647988ad5 | ||
|
|
da12c4cbdb | ||
|
|
0968e9e5fd | ||
|
|
2a205e561a | ||
|
|
7c7f3f02bb | ||
|
|
e04422b6ff | ||
|
|
fb33f9b186 | ||
|
|
fd36873261 | ||
|
|
882dd4e2e3 | ||
|
|
d82b5c20c0 | ||
|
|
9aa15e081e | ||
|
|
10c49f7748 | ||
|
|
d1446fc1f4 | ||
|
|
19bc44a226 | ||
|
|
bc1d81c5e8 | ||
|
|
23a3362475 | ||
|
|
0cab27d529 | ||
|
|
1447bf6655 | ||
|
|
08a8191002 | ||
|
|
5ff2a2c45f | ||
|
|
1fe07edbf9 | ||
|
|
b1aedf9a2a | ||
|
|
799dffef7d | ||
|
|
1474c70719 | ||
|
|
ac75a9a4a4 | ||
|
|
8bf8d34376 | ||
|
|
f70e4c1253 | ||
|
|
40b3b9ae1b | ||
|
|
1000461a55 | ||
|
|
c644dd6707 | ||
|
|
1076307e6b | ||
|
|
2f531af3f2 | ||
|
|
2a9ee7f196 | ||
|
|
2476cc5e3c | ||
|
|
f4ebe6e8b9 | ||
|
|
cd3b0be5ed | ||
|
|
b1b12945c0 | ||
|
|
25501469c3 | ||
|
|
75d553674c | ||
|
|
c7a2fb97c7 | ||
|
|
8e12d94359 | ||
|
|
4ead9814cc | ||
|
|
83c8916c46 | ||
|
|
2e067590a2 | ||
|
|
89e2b29aed | ||
|
|
e91ec58aa1 | ||
|
|
e9ab6241db | ||
|
|
4116bfac5e | ||
|
|
bc8c87cb28 | ||
|
|
fe5fefbd8e | ||
|
|
516972119c | ||
|
|
f69c887276 | ||
|
|
fe4ec68ccc | ||
|
|
be7a711f66 | ||
|
|
360e08265c | ||
|
|
f9323f6473 | ||
|
|
06516f7eb3 | ||
|
|
19b6c03f37 | ||
|
|
e79a6ed6b2 | ||
|
|
78c8ceb244 | ||
|
|
bcdb982886 | ||
|
|
202bc5f1cd | ||
|
|
a8722655bb | ||
|
|
cda968bddd | ||
|
|
d6423f0c3f | ||
|
|
fb9adf979c | ||
|
|
561d5db985 | ||
|
|
34c2593e43 | ||
|
|
a1867a584a | ||
|
|
548bf48d7a | ||
|
|
27d4ea393d | ||
|
|
9d7641aeea | ||
|
|
4fe758e51b | ||
|
|
aeb7e1589e | ||
|
|
1894d22609 | ||
|
|
f7d6d063be | ||
|
|
05d9b290a7 | ||
|
|
9164eb329d | ||
|
|
52a3f9c66f | ||
|
|
83627b9967 | ||
|
|
bc82f3f8eb | ||
|
|
fdb92ee788 | ||
|
|
bbb54a6d17 | ||
|
|
b42e187060 | ||
|
|
8d3381a5f9 | ||
|
|
04c2f05002 | ||
|
|
d6a64a275a | ||
|
|
2088297e3d | ||
|
|
692fd9548a | ||
|
|
e65582df71 | ||
|
|
01b789c3e9 | ||
|
|
d84837a438 | ||
|
|
20785afeb7 | ||
|
|
1a01c6a992 | ||
|
|
b8ae5984c5 | ||
|
|
b59d9a23ea | ||
|
|
742b6d1300 | ||
|
|
d4db62a98c | ||
|
|
0463c8bfcd |
@@ -0,0 +1,5 @@
|
|||||||
|
# Configuration docs: https://bencher.orijtech.com/configuration/
|
||||||
|
suppress_failure_on_regression: false
|
||||||
|
global:
|
||||||
|
reg_min: 10
|
||||||
|
imp_min: -10
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
client/docs/swagger-ui/* linguist-vendored
|
||||||
|
client/docs/statik/* linguist-vendored
|
||||||
|
third-party/* linguist-vendored
|
||||||
|
client/docs/* linguist-documentation
|
||||||
|
docs/* linguist-documentation
|
||||||
|
x/**/spec/* linguist-documentation
|
||||||
|
**/*.pb.go linguist-generated
|
||||||
|
**/*.pb.gw.go linguist-generated
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
# CODEOWNERS: https://help.github.com/articles/about-codeowners/
|
# CODEOWNERS: https://help.github.com/articles/about-codeowners/
|
||||||
|
|
||||||
# Primary repo maintainers
|
# Primary repo maintainers
|
||||||
* @fedekunze @khoslaventures @nzoghb
|
* @fedekunze @khoslaventures @jolube
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
name: Docs build
|
|
||||||
# This workflow runs when a PR is labeled with `docs`
|
|
||||||
# This will check if the docs build successfully by running `npm run build`
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- release/*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-docs-build:
|
|
||||||
name: Check docs build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2.3.4
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: technote-space/get-diff-action@v5
|
|
||||||
id: git_diff
|
|
||||||
with:
|
|
||||||
PATTERNS: |
|
|
||||||
docs/*
|
|
||||||
SUFFIX_FILTER: |
|
|
||||||
.md
|
|
||||||
- name: Install dependencies and build docs 🧱
|
|
||||||
run: |
|
|
||||||
make build-docs
|
|
||||||
@@ -16,8 +16,11 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v3
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.17
|
||||||
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
id: git_diff
|
id: git_diff
|
||||||
with:
|
with:
|
||||||
SUFFIX_FILTER: |
|
SUFFIX_FILTER: |
|
||||||
@@ -26,4 +29,4 @@ jobs:
|
|||||||
.sum
|
.sum
|
||||||
- run: |
|
- run: |
|
||||||
make build
|
make build
|
||||||
if: "env.GIT_DIFF != ''"
|
if: env.GIT_DIFF
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
name: Remove old artifacts
|
|
||||||
# Remove old artifacts runs a crob job that removes old artifacts
|
|
||||||
# generated from the split tests workflow.
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
# Every day at 1am
|
|
||||||
- cron: "0 1 * * *"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
remove-old-artifacts:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 10
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Remove old artifacts
|
|
||||||
uses: c-hive/gha-remove-artifacts@v1.2.0
|
|
||||||
with:
|
|
||||||
age: "7 days"
|
|
||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ jobs:
|
|||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v3
|
||||||
- name: Use Node.js
|
- name: Use Node.js
|
||||||
uses: actions/setup-node@v2.4.0
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: '12.x'
|
node-version: '12.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm install
|
run: npm install
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
id: git_diff
|
id: git_diff
|
||||||
with:
|
with:
|
||||||
SUFFIX_FILTER: |
|
SUFFIX_FILTER: |
|
||||||
@@ -35,4 +35,4 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
sudo make contract-tools
|
sudo make contract-tools
|
||||||
sudo make test-contract
|
sudo make test-contract
|
||||||
if: "env.GIT_DIFF != ''"
|
if: env.GIT_DIFF
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: release
|
environment: release
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
name: Notion Sync
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
[
|
||||||
|
opened,
|
||||||
|
edited,
|
||||||
|
labeled,
|
||||||
|
unlabeled,
|
||||||
|
assigned,
|
||||||
|
unassigned,
|
||||||
|
milestoned,
|
||||||
|
demilestoned,
|
||||||
|
reopened,
|
||||||
|
closed,
|
||||||
|
]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
notion_job:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Add GitHub Issues to Notion
|
||||||
|
steps:
|
||||||
|
- name: Add GitHub Issues to Notion
|
||||||
|
uses: vulcanize/notion-github-action@v1.2.4-issueid
|
||||||
|
with:
|
||||||
|
notion-token: ${{ secrets.NOTION_TOKEN }}
|
||||||
|
notion-db: ${{ secrets.NOTION_DATABASE }}
|
||||||
@@ -9,6 +9,6 @@ jobs:
|
|||||||
triage:
|
triage:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/labeler@v3
|
- uses: actions/labeler@v4
|
||||||
with:
|
with:
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ jobs:
|
|||||||
markdown-link-check:
|
markdown-link-check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v3
|
||||||
- uses: gaurav-nelson/github-action-markdown-link-check@1.0.13
|
- uses: gaurav-nelson/github-action-markdown-link-check@1.0.14
|
||||||
with:
|
with:
|
||||||
folder-path: "docs"
|
folder-path: "docs"
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v3
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
with:
|
with:
|
||||||
SUFFIX_FILTER: |
|
SUFFIX_FILTER: |
|
||||||
.go
|
.go
|
||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
- uses: golangci/golangci-lint-action@v2.5.2
|
- uses: golangci/golangci-lint-action@v2.5.2
|
||||||
with:
|
with:
|
||||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||||
version: v1.29
|
version: v1.42.1
|
||||||
args: --timeout 10m
|
args: --timeout 10m
|
||||||
github-token: ${{ secrets.github_token }}
|
github-token: ${{ secrets.github_token }}
|
||||||
# Check only if there are differences in the source code
|
# Check only if there are differences in the source code
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 5
|
timeout-minutes: 5
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v3
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
with:
|
with:
|
||||||
PATTERNS: |
|
PATTERNS: |
|
||||||
**/**.proto
|
**/**.proto
|
||||||
@@ -20,8 +20,8 @@ jobs:
|
|||||||
breakage:
|
breakage:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v3
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
with:
|
with:
|
||||||
PATTERNS: |
|
PATTERNS: |
|
||||||
**/**.proto
|
**/**.proto
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
name: Run Gosec
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Gosec:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO111MODULE: on
|
||||||
|
steps:
|
||||||
|
- name: Checkout Source
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Get Diff
|
||||||
|
uses: technote-space/get-diff-action@v6.0.1
|
||||||
|
with:
|
||||||
|
PATTERNS: |
|
||||||
|
**/*.go
|
||||||
|
go.mod
|
||||||
|
go.sum
|
||||||
|
- name: Run Gosec Security Scanner
|
||||||
|
uses: informalsystems/gosec@master
|
||||||
|
with:
|
||||||
|
# we let the report trigger content trigger a failure using the GitHub Security features.
|
||||||
|
args: '-no-fail -fmt sarif -out results.sarif ./...'
|
||||||
|
if: "env.GIT_DIFF_FILTERED != ''"
|
||||||
|
- name: Upload SARIF file
|
||||||
|
uses: github/codeql-action/upload-sarif@v1
|
||||||
|
with:
|
||||||
|
# Path to SARIF file relative to the root of the repository
|
||||||
|
sarif_file: results.sarif
|
||||||
|
if: "env.GIT_DIFF_FILTERED != ''"
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
name: Semgrep
|
||||||
|
on:
|
||||||
|
# Scan changed files in PRs, block on new issues only (existing issues ignored)
|
||||||
|
pull_request: {}
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- .github/workflows/semgrep.yml
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * 0'
|
||||||
|
jobs:
|
||||||
|
semgrep:
|
||||||
|
name: Scan
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: (github.actor != 'dependabot[bot]')
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Get Diff
|
||||||
|
uses: technote-space/get-diff-action@v6.0.1
|
||||||
|
with:
|
||||||
|
PATTERNS: |
|
||||||
|
**/*.go
|
||||||
|
**/*.js
|
||||||
|
**/*.ts
|
||||||
|
**/*.sol
|
||||||
|
go.mod
|
||||||
|
go.sum
|
||||||
|
- uses: returntocorp/semgrep-action@v1
|
||||||
|
with:
|
||||||
|
publishToken: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||||
|
# Upload findings to GitHub Advanced Security Dashboard [step 1/2]
|
||||||
|
# See also the next step.
|
||||||
|
generateSarif: "1"
|
||||||
|
if: "env.GIT_DIFF_FILTERED != ''"
|
||||||
|
# Upload findings to GitHub Advanced Security Dashboard [step 2/2]
|
||||||
|
- name: Upload SARIF file for GitHub Advanced Security Dashboard
|
||||||
|
uses: github/codeql-action/upload-sarif@v1
|
||||||
|
with:
|
||||||
|
sarif_file: semgrep.sarif
|
||||||
|
if: "env.GIT_DIFF_FILTERED != ''"
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
name: "Close stale issues & pull requests"
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 0 * * *"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
stale:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/stale@v4
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
stale-pr-message: "This pull request has been automatically marked as stale because it has not had
|
|
||||||
recent activity. It will be closed in 7 days-before-close if no further activity occurs."
|
|
||||||
stale-issue-message: "This issue is stale because it has been open 45 days with no activity. Remove `Status: Stale` label or comment or this will be closed in 7 days."
|
|
||||||
days-before-stale: 45
|
|
||||||
days-before-close: 7
|
|
||||||
exempt-issue-labels: "Status: Blocked, Type: Bug, pinned, automerge"
|
|
||||||
exempt-pr-labels: "Status: Blocked, Type: Bug, pinned, automerge"
|
|
||||||
stale-pr-label: "Status: Stale"
|
|
||||||
stale-issue-label: "Status: Stale"
|
|
||||||
+77
-30
@@ -26,7 +26,7 @@ jobs:
|
|||||||
- name: Install tparse
|
- name: Install tparse
|
||||||
run: |
|
run: |
|
||||||
export GO111MODULE="on" && go get github.com/mfridman/tparse@latest
|
export GO111MODULE="on" && go get github.com/mfridman/tparse@latest
|
||||||
- uses: actions/cache@v2.1.6
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/go/bin
|
path: ~/go/bin
|
||||||
key: ${{ runner.os }}-go-tparse-binary
|
key: ${{ runner.os }}-go-tparse-binary
|
||||||
@@ -37,8 +37,8 @@ jobs:
|
|||||||
- uses: actions/setup-go@v2.1.4
|
- uses: actions/setup-go@v2.1.4
|
||||||
with:
|
with:
|
||||||
go-version: 1.17
|
go-version: 1.17
|
||||||
- uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v3
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
with:
|
with:
|
||||||
PATTERNS: |
|
PATTERNS: |
|
||||||
**/**.sol
|
**/**.sol
|
||||||
@@ -55,54 +55,62 @@ jobs:
|
|||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
if: env.GIT_DIFF
|
if: env.GIT_DIFF
|
||||||
|
|
||||||
# TODO: refactor before enabling
|
test-importer:
|
||||||
# test-importer:
|
runs-on: ubuntu-latest
|
||||||
# runs-on: ubuntu-latest
|
timeout-minutes: 10
|
||||||
# timeout-minutes: 10
|
steps:
|
||||||
# steps:
|
- uses: actions/setup-go@v2.1.4
|
||||||
# - uses: actions/checkout@v2.3.4
|
with:
|
||||||
# - uses: actions/setup-go@v2.1.4
|
go-version: 1.17
|
||||||
# with:
|
- uses: actions/checkout@v3
|
||||||
# go-version: 1.17
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
# - uses: technote-space/get-diff-action@v5
|
id: git_diff
|
||||||
# id: git_diff
|
with:
|
||||||
# with:
|
SUFFIX_FILTER: |
|
||||||
# SUFFIX_FILTER: |
|
.go
|
||||||
# .go
|
.mod
|
||||||
# .mod
|
.sum
|
||||||
# .sum
|
- name: test-importer
|
||||||
# - name: test-importer
|
run: |
|
||||||
# run: |
|
make test-import
|
||||||
# make test-import
|
if: env.GIT_DIFF
|
||||||
# if: "env.GIT_DIFF != ''"
|
|
||||||
|
|
||||||
test-solidity:
|
test-solidity:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 240
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
batch: ['1-3', '2-3', '3-3']
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v3
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.17
|
||||||
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
id: git_diff
|
id: git_diff
|
||||||
with:
|
with:
|
||||||
PATTERNS: |
|
PATTERNS: |
|
||||||
**/**.sol
|
**/**.sol
|
||||||
**/**.go
|
**/**.go
|
||||||
|
tests/solidity/**/*.js
|
||||||
|
tests/solidity/**/*.sh
|
||||||
go.mod
|
go.mod
|
||||||
go.sum
|
go.sum
|
||||||
- name: test-solidity
|
- name: test-solidity
|
||||||
run: |
|
run: |
|
||||||
make test-solidity
|
./scripts/run-solidity-tests.sh --batch=${{ matrix.batch }}
|
||||||
if: "env.GIT_DIFF != ''"
|
if: env.GIT_DIFF
|
||||||
|
|
||||||
liveness-test:
|
liveness-test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-go@v2.1.4
|
- uses: actions/setup-go@v2.1.4
|
||||||
with:
|
with:
|
||||||
go-version: 1.17
|
go-version: 1.17
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
id: git_diff
|
id: git_diff
|
||||||
with:
|
with:
|
||||||
PATTERNS: |
|
PATTERNS: |
|
||||||
@@ -123,3 +131,42 @@ jobs:
|
|||||||
./contrib/scripts/test_localnet_liveness.sh 100 5 50 localhost
|
./contrib/scripts/test_localnet_liveness.sh 100 5 50 localhost
|
||||||
if: env.GIT_DIFF
|
if: env.GIT_DIFF
|
||||||
|
|
||||||
|
test-rpc:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 15
|
||||||
|
steps:
|
||||||
|
- uses: actions/setup-go@v2.1.4
|
||||||
|
with:
|
||||||
|
go-version: 1.17
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
|
with:
|
||||||
|
PATTERNS: |
|
||||||
|
**/**.sol
|
||||||
|
**/**.go
|
||||||
|
go.mod
|
||||||
|
go.sum
|
||||||
|
- name: Test rpc endpoint
|
||||||
|
run: |
|
||||||
|
make test-rpc
|
||||||
|
if: env.GIT_DIFF
|
||||||
|
|
||||||
|
test-e2e:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 15
|
||||||
|
steps:
|
||||||
|
- uses: actions/setup-go@v2.1.4
|
||||||
|
with:
|
||||||
|
go-version: 1.17
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: technote-space/get-diff-action@v6.0.1
|
||||||
|
with:
|
||||||
|
PATTERNS: |
|
||||||
|
**/**.sol
|
||||||
|
**/**.go
|
||||||
|
go.mod
|
||||||
|
go.sum
|
||||||
|
- name: Test e2e
|
||||||
|
run: |
|
||||||
|
make test-integration
|
||||||
|
if: env.GIT_DIFF
|
||||||
@@ -71,3 +71,4 @@ dependency-graph.png
|
|||||||
# Node.js
|
# Node.js
|
||||||
tests/**/node_modules/*
|
tests/**/node_modules/*
|
||||||
tests-solidity/**/node_modules/*
|
tests-solidity/**/node_modules/*
|
||||||
|
**/**.json
|
||||||
+3
-4
@@ -15,21 +15,20 @@ linters:
|
|||||||
- gocritic
|
- gocritic
|
||||||
- gofmt
|
- gofmt
|
||||||
- goimports
|
- goimports
|
||||||
- golint
|
- revive
|
||||||
- gosec
|
- gosec
|
||||||
- gosimple
|
- gosimple
|
||||||
- govet
|
- govet
|
||||||
- ineffassign
|
- ineffassign
|
||||||
# - lll TODO: enable
|
# - lll TODO: enable
|
||||||
- misspell
|
- misspell
|
||||||
- maligned
|
|
||||||
- nakedret
|
- nakedret
|
||||||
- prealloc
|
- prealloc
|
||||||
- scopelint
|
- exportloopref
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- structcheck
|
- structcheck
|
||||||
- stylecheck
|
- stylecheck
|
||||||
- typecheck
|
# - typecheck #TODO: enable
|
||||||
- unconvert
|
- unconvert
|
||||||
- unparam
|
- unparam
|
||||||
- unused
|
- unused
|
||||||
|
|||||||
+25
-2
@@ -1,10 +1,33 @@
|
|||||||
|
queue_rules:
|
||||||
|
- name: default
|
||||||
|
conditions:
|
||||||
|
- "#approved-reviews-by>1"
|
||||||
|
|
||||||
pull_request_rules:
|
pull_request_rules:
|
||||||
- name: automerge to base branch with label automerge and branch protection passing
|
- name: automerge to the base branch with label automerge and branch protection passing
|
||||||
conditions:
|
conditions:
|
||||||
- "#approved-reviews-by>1"
|
- "#approved-reviews-by>1"
|
||||||
- base=main
|
- base=main
|
||||||
- label=automerge
|
- label=automerge
|
||||||
actions:
|
actions:
|
||||||
|
queue:
|
||||||
|
name: default
|
||||||
merge:
|
merge:
|
||||||
method: squash
|
method: squash
|
||||||
strict: true
|
commit_message: title+body
|
||||||
|
- name: backport patches to v0.9.x branch
|
||||||
|
conditions:
|
||||||
|
- base=main
|
||||||
|
- label=backport/0.9.x
|
||||||
|
actions:
|
||||||
|
backport:
|
||||||
|
branches:
|
||||||
|
- release/v0.9.x
|
||||||
|
- name: backport patches to v0.7.x branch
|
||||||
|
conditions:
|
||||||
|
- base=main
|
||||||
|
- label=backport/0.7.x
|
||||||
|
actions:
|
||||||
|
backport:
|
||||||
|
branches:
|
||||||
|
- release/v0.7.x
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Ignore git items
|
||||||
|
.gitignore
|
||||||
|
.git/
|
||||||
|
:include .gitignore
|
||||||
|
|
||||||
|
# Common large paths
|
||||||
|
node_modules/
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
vendor/
|
||||||
|
.env/
|
||||||
|
.venv/
|
||||||
|
.tox/
|
||||||
|
*.min.js
|
||||||
|
*.pb.gw.go
|
||||||
|
|
||||||
|
# Common test paths
|
||||||
|
test/
|
||||||
|
tests/
|
||||||
|
*_test.go
|
||||||
|
|
||||||
|
# Semgrep rules folder
|
||||||
|
.semgrep
|
||||||
|
|
||||||
|
# Semgrep-action log folder
|
||||||
|
.semgrep_logs/
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
client/docs/
|
||||||
+319
-96
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
Guiding Principles:
|
Guiding Principles:
|
||||||
|
|
||||||
@@ -35,12 +36,227 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## Unreleased
|
## [v0.12.2] - 2022-03-30
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (feemarket) [tharsis#1021](https://github.com/tharsis/ethermint/pull/1021) Fix fee market migration.
|
||||||
|
|
||||||
|
## [v0.12.1] - 2022-03-29
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (evm) [tharsis#1016](https://github.com/tharsis/ethermint/pull/1016) Update validate basic check for storage state.
|
||||||
|
|
||||||
|
## [v0.12.0] - 2022-03-24
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (rpc) [tharsis#1012](https://github.com/tharsis/ethermint/pull/1012) fix the tx hash in filter entries created by `eth_newPendingTransactionFilter`.
|
||||||
|
* (rpc) [tharsis#1006](https://github.com/tharsis/ethermint/pull/1006) Use `string` as the parameters type to correct ambiguous results.
|
||||||
|
* (ante) [tharsis#1004](https://github.com/tharsis/ethermint/pull/1004) Make `MaxTxGasWanted` configurable.
|
||||||
|
* (ante) [tharsis#991](https://github.com/tharsis/ethermint/pull/991) Set an upper bound to gasWanted to prevent DoS attack.
|
||||||
|
* (rpc) [tharsis#990](https://github.com/tharsis/ethermint/pull/990) Calculate reward values from all `MsgEthereumTx` from a block in `eth_feeHistory`.
|
||||||
|
|
||||||
|
## [v0.11.0] - 2022-03-06
|
||||||
|
|
||||||
|
### State Machine Breaking
|
||||||
|
|
||||||
|
* (ante) [tharsis#964](https://github.com/tharsis/ethermint/pull/964) add NewInfiniteGasMeterWithLimit for storing the user provided gas limit. Fixes block's consumed gas calculation in the block creation phase.
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (rpc) [tharsis#975](https://github.com/tharsis/ethermint/pull/975) Fix unexpected `nil` values for `reward`, returned by `EffectiveGasTipValue(blockBaseFee)` in the `eth_feeHistory` RPC method.
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
- (rpc) [tharsis#979](https://github.com/tharsis/ethermint/pull/979) Add configurable timeouts to http server
|
||||||
|
- (rpc) [tharsis#988](https://github.com/tharsis/ethermint/pull/988) json-rpc server always use local rpc client
|
||||||
|
|
||||||
|
## [v0.10.1] - 2022-03-04
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (rpc) [tharsis#970](https://github.com/tharsis/ethermint/pull/970) Fix unexpected nil reward values on `eth_feeHistory` response
|
||||||
|
* (evm) [tharsis#529](https://github.com/tharsis/ethermint/issues/529) Add support return value on trace tx response.
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* (rpc) [tharsis#968](https://github.com/tharsis/ethermint/pull/968) Add some buffer to returned gas price to provide better default UX for client.
|
||||||
|
|
||||||
|
## [v0.10.0] - 2022-02-26
|
||||||
|
|
||||||
|
### API Breaking
|
||||||
|
|
||||||
|
* (ante) [tharsis#866](https://github.com/tharsis/ethermint/pull/866) `NewAnteHandler` constructor now receives a `HandlerOptions` field.
|
||||||
|
* (evm) [tharsis#849](https://github.com/tharsis/ethermint/pull/849) `PostTxProcessing` hook now takes an Ethereum tx `Receipt` and a `from` `Address` as arguments.
|
||||||
|
* (ante) [tharsis#916](https://github.com/tharsis/ethermint/pull/916) Don't check min-gas-price for eth tx if london hardfork enabled and feemarket enabled.
|
||||||
|
|
||||||
|
### State Machine Breaking
|
||||||
|
|
||||||
|
* (deps) [tharsis#912](https://github.com/tharsis/ethermint/pull/912) Bump Cosmos SDK version to [`v0.45.1`](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.45.1)
|
||||||
|
* (evm) [tharsis#840](https://github.com/tharsis/ethermint/pull/840) Store empty topics as empty array rather than nil.
|
||||||
|
* (feemarket) [tharsis#822](https://github.com/tharsis/ethermint/pull/822) Update EIP1559 base fee in `BeginBlock`.
|
||||||
|
* (evm) [tharsis#817](https://github.com/tharsis/ethermint/pull/817) Use `effectiveGasPrice` in ante handler, add `effectiveGasPrice` to tx receipt.
|
||||||
|
* (evm) [tharsis#808](https://github.com/tharsis/ethermint/issues/808) increase nonce in ante handler for contract creation transaction.
|
||||||
|
* (evm) [tharsis#851](https://github.com/tharsis/ethermint/pull/851) fix contract address used in EVM, this issue is caused by [tharsis#808](https://github.com/tharsis/ethermint/issues/808).
|
||||||
|
* (evm) Reject invalid `MsgEthereumTx` wrapping tx
|
||||||
|
* (evm) Fix `SelfDestruct` opcode by deleting account code and state.
|
||||||
|
* (feemarket) [tharsis#855](https://github.com/tharsis/ethermint/pull/855) Consistent `BaseFee` check logic.
|
||||||
|
* (evm) [tharsis#729](https://github.com/tharsis/ethermint/pull/729) Refactor EVM `StateDB` implementation.
|
||||||
|
* (evm) [tharsis#945](https://github.com/tharsis/ethermint/pull/945) Bumb Go-ethereum version to [`v1.10.16`](https://github.com/ethereum/go-ethereum/releases/tag/v1.10.16)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* (ante) [tharsis#950](https://github.com/tharsis/ethermint/pull/950) Add support for EIP712 signed Cosmos transactions
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* (types) [tharsis#884](https://github.com/tharsis/ethermint/pull/884) Introduce a new `EthAccountI` interface for EVM-compatible account types.
|
||||||
|
* (types) [tharsis#849](https://github.com/tharsis/ethermint/pull/849) Add `Type` function to distinguish EOAs from Contract accounts.
|
||||||
|
* (evm) [tharsis#826](https://github.com/tharsis/ethermint/issues/826) Improve allocation of bytes of `tx.To` address.
|
||||||
|
* (evm) [tharsis#827](https://github.com/tharsis/ethermint/issues/827) Speed up creation of event logs by using the slice insertion idiom with indices.
|
||||||
|
* (ante) [tharsis#819](https://github.com/tharsis/ethermint/pull/819) Remove redundant ante handlers
|
||||||
|
* (app) [tharsis#873](https://github.com/tharsis/ethermint/pull/873) Validate code hash in GenesisAccount
|
||||||
|
* (evm) [tharsis#901](https://github.com/tharsis/ethermint/pull/901) Support multiple `MsgEthereumTx` in single tx.
|
||||||
|
* (config) [tharsis#908](https://github.com/tharsis/ethermint/pull/908) Add `api.enable` flag for Cosmos SDK Rest server
|
||||||
|
* (feemarket) [tharsis#919](https://github.com/tharsis/ethermint/pull/919) Initialize baseFee in default genesis state.
|
||||||
|
* (feemarket) [tharsis#943](https://github.com/tharsis/ethermint/pull/943) Store the base fee as a module param instead of using state storage.
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (rpc) [tharsis#955](https://github.com/tharsis/ethermint/pull/955) Fix websocket server push duplicated messages to subscriber.
|
||||||
|
* (rpc) [tharsis#953](https://github.com/tharsis/ethermint/pull/953) Add `eth_signTypedData` api support.
|
||||||
|
* (log) [tharsis#948](https://github.com/tharsis/ethermint/pull/948) Redirect go-ethereum's logs to cosmos-sdk logger.
|
||||||
|
* (evm) [tharsis#884](https://github.com/tharsis/ethermint/pull/884) Support multiple account types on the EVM `StateDB`.
|
||||||
|
* (rpc) [tharsis#831](https://github.com/tharsis/ethermint/pull/831) Fix BaseFee value when height is specified.
|
||||||
|
* (evm) [tharsis#838](https://github.com/tharsis/ethermint/pull/838) Fix splitting of trace.Memory into 32 chunks.
|
||||||
|
* (rpc) [tharsis#860](https://github.com/tharsis/ethermint/pull/860) Fix `eth_getLogs` when specify blockHash without address/topics, and limit the response size.
|
||||||
|
* (rpc) [tharsis#865](https://github.com/tharsis/ethermint/pull/865) Fix RPC Filter parameters being ignored
|
||||||
|
* (evm) [tharsis#871](https://github.com/tharsis/ethermint/pull/871) Set correct nonce in `EthCall` and `EstimateGas` grpc query.
|
||||||
|
* (rpc) [tharsis#878](https://github.com/tharsis/ethermint/pull/878) Workaround to make GetBlock RPC api report correct block gas used.
|
||||||
|
* (rpc) [tharsis#900](https://github.com/tharsis/ethermint/pull/900) `newPendingTransactions` filter return ethereum tx hash.
|
||||||
|
* (rpc) [tharsis#933](https://github.com/tharsis/ethermint/pull/933) Fix `newPendingTransactions` subscription deadlock when a Websocket client exits without unsubscribing and the node errors.
|
||||||
|
* (evm) [tharsis#932](https://github.com/tharsis/ethermint/pull/932) Fix base fee check logic in state transition.
|
||||||
|
|
||||||
|
## [v0.9.0] - 2021-12-01
|
||||||
|
|
||||||
|
### State Machine Breaking
|
||||||
|
|
||||||
|
* (evm) [tharsis#802](https://github.com/tharsis/ethermint/pull/802) Clear access list for each transaction
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* (app) [tharsis#794](https://github.com/tharsis/ethermint/pull/794) Setup in-place store migrators.
|
||||||
|
* (ci) [tharsis#784](https://github.com/tharsis/ethermint/pull/784) Enable automatic backport of PRs.
|
||||||
|
* (rpc) [tharsis#786](https://github.com/tharsis/ethermint/pull/786) Improve error message of `SendTransaction`/`SendRawTransaction` JSON-RPC APIs.
|
||||||
|
* (rpc) [tharsis#810](https://github.com/tharsis/ethermint/pull/810) Optimize tx index lookup in web3 rpc
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (license) [tharsis#800](https://github.com/tharsis/ethermint/pull/800) Re-license project to [LGPLv3](https://choosealicense.com/licenses/lgpl-3.0/#) to comply with go-ethereum.
|
||||||
|
* (evm) [tharsis#794](https://github.com/tharsis/ethermint/pull/794) Register EVM gRPC `Msg` server.
|
||||||
|
* (rpc) [tharsis#781](https://github.com/tharsis/ethermint/pull/781) Fix get block invalid transactions filter.
|
||||||
|
* (rpc) [tharsis#782](https://github.com/tharsis/ethermint/pull/782) Fix wrong block gas limit returned by JSON-RPC.
|
||||||
|
* (evm) [tharsis#798](https://github.com/tharsis/ethermint/pull/798) Fix the semantic of `ForEachStorage` callback's return value
|
||||||
|
|
||||||
|
## [v0.8.1] - 2021-11-23
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (feemarket) [tharsis#770](https://github.com/tharsis/ethermint/pull/770) Enable fee market (EIP1559) by default.
|
||||||
|
* (rpc) [tharsis#769](https://github.com/tharsis/ethermint/pull/769) Fix default Ethereum signer for JSON-RPC.
|
||||||
|
|
||||||
|
## [v0.8.0] - 2021-11-17
|
||||||
|
|
||||||
|
### State Machine Breaking
|
||||||
|
|
||||||
|
* (evm, ante) [tharsis#620](https://github.com/tharsis/ethermint/pull/620) Add fee market field to EVM `Keeper` and `AnteHandler`.
|
||||||
|
* (all) [tharsis#231](https://github.com/tharsis/ethermint/pull/231) Bump go-ethereum version to [`v1.10.9`](https://github.com/ethereum/go-ethereum/releases/tag/v1.10.9)
|
||||||
|
* (ante) [tharsis#703](https://github.com/tharsis/ethermint/pull/703) Fix some fields in transaction are not authenticated by signature.
|
||||||
|
* (evm) [tharsis#751](https://github.com/tharsis/ethermint/pull/751) don't revert gas refund logic when transaction reverted
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* (rpc, evm) [tharsis#673](https://github.com/tharsis/ethermint/pull/673) Use tendermint events to store fee market basefee.
|
||||||
|
* (rpc) [tharsis#624](https://github.com/tharsis/ethermint/pull/624) Implement new JSON-RPC endpoints from latest geth version
|
||||||
|
* (evm) [tharsis#662](https://github.com/tharsis/ethermint/pull/662) Disable basefee for non london blocks
|
||||||
|
* (cmd) [tharsis#712](https://github.com/tharsis/ethermint/pull/712) add tx cli to build evm transaction
|
||||||
|
* (rpc) [tharsis#733](https://github.com/tharsis/ethermint/pull/733) add JSON_RPC endpoint `personal_unpair`
|
||||||
|
* (rpc) [tharsis#734](https://github.com/tharsis/ethermint/pull/734) add JSON_RPC endpoint `eth_feeHistory`
|
||||||
|
* (rpc) [tharsis#740](https://github.com/tharsis/ethermint/pull/740) add JSON_RPC endpoint `personal_initializeWallet`
|
||||||
|
* (rpc) [tharsis#743](https://github.com/tharsis/ethermint/pull/743) add JSON_RPC endpoint `debug_traceBlockByHash`
|
||||||
|
* (rpc) [tharsis#748](https://github.com/tharsis/ethermint/pull/748) add JSON_RPC endpoint `personal_listWallets`
|
||||||
|
* (rpc) [tharsis#754](https://github.com/tharsis/ethermint/pull/754) add JSON_RPC endpoint `debug_intermediateRoots`
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (evm) [tharsis#746](https://github.com/tharsis/ethermint/pull/746) Set EVM debugging based on tracer configuration.
|
||||||
|
* (app,cli) [tharsis#725](https://github.com/tharsis/ethermint/pull/725) Fix cli-config for `keys` command.
|
||||||
|
* (rpc) [tharsis#727](https://github.com/tharsis/ethermint/pull/727) Decode raw transaction using RLP.
|
||||||
|
* (rpc) [tharsis#661](https://github.com/tharsis/ethermint/pull/661) Fix OOM bug when creating too many filters using JSON-RPC.
|
||||||
|
* (evm) [tharsis#660](https://github.com/tharsis/ethermint/pull/660) Fix `nil` pointer panic in `ApplyNativeMessage`.
|
||||||
|
* (evm, test) [tharsis#649](https://github.com/tharsis/ethermint/pull/649) Test DynamicFeeTx.
|
||||||
|
* (evm) [tharsis#702](https://github.com/tharsis/ethermint/pull/702) Fix panic in web3 RPC handlers
|
||||||
|
* (rpc) [tharsis#720](https://github.com/tharsis/ethermint/pull/720) Fix `debug_traceTransaction` failure
|
||||||
|
* (rpc) [tharsis#741](https://github.com/tharsis/ethermint/pull/741) Fix `eth_getBlockByNumberAndHash` return with non eth txs
|
||||||
|
* (rpc) [tharsis#743](https://github.com/tharsis/ethermint/pull/743) Fix debug JSON RPC handler crash on non-existing block
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* (tests) [tharsis#704](https://github.com/tharsis/ethermint/pull/704) Introduce E2E testing framework for clients
|
||||||
|
* (deps) [tharsis#737](https://github.com/tharsis/ethermint/pull/737) Bump ibc-go to [`v2.0.0`](https://github.com/cosmos/ibc-go/releases/tag/v2.0.0)
|
||||||
|
* (rpc) [tharsis#671](https://github.com/tharsis/ethermint/pull/671) Don't pass base fee externally for `EthCall`/`EthEstimateGas` apis.
|
||||||
|
* (evm) [tharsis#674](https://github.com/tharsis/ethermint/pull/674) Refactor `ApplyMessage`, remove
|
||||||
|
`ApplyNativeMessage`.
|
||||||
|
* (rpc) [tharsis#714](https://github.com/tharsis/ethermint/pull/714) remove `MsgEthereumTx` support in `TxConfig`
|
||||||
|
|
||||||
|
## [v0.7.2] - 2021-10-24
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* (deps) [tharsis#692](https://github.com/tharsis/ethermint/pull/692) Bump Cosmos SDK version to [`v0.44.3`](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.3).
|
||||||
|
* (rpc) [tharsis#679](https://github.com/tharsis/ethermint/pull/679) Fix file close handle.
|
||||||
|
* (deps) [tharsis#668](https://github.com/tharsis/ethermint/pull/668) Bump Tendermint version to [`v0.34.14`](https://github.com/tendermint/tendermint/releases/tag/v0.34.14).
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (rpc) [tharsis#667](https://github.com/tharsis/ethermint/issues/667) Fix `ExpandHome` restrictions bypass
|
||||||
|
|
||||||
|
## [v0.7.1] - 2021-10-08
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (evm) [tharsis#650](https://github.com/tharsis/ethermint/pull/650) Fix panic when flattening the cache context in case transaction is reverted.
|
||||||
|
* (rpc, test) [tharsis#608](https://github.com/tharsis/ethermint/pull/608) Fix rpc test.
|
||||||
|
|
||||||
|
## [v0.7.0] - 2021-10-07
|
||||||
|
|
||||||
|
### API Breaking
|
||||||
|
|
||||||
|
* (rpc) [tharsis#400](https://github.com/tharsis/ethermint/issues/400) Restructure JSON-RPC directory and rename server config
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* (deps) [tharsis#621](https://github.com/tharsis/ethermint/pull/621) Bump IBC-go to [`v1.2.1`](https://github.com/cosmos/ibc-go/releases/tag/v1.2.1)
|
||||||
|
* (evm) [tharsis#613](https://github.com/tharsis/ethermint/pull/613) Refactor `traceTx`
|
||||||
|
* (deps) [tharsis#610](https://github.com/tharsis/ethermint/pull/610) Bump Cosmos SDK to [v0.44.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.1).
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (rpc) [tharsis#642](https://github.com/tharsis/ethermint/issues/642) Fix `eth_getLogs` when string is specified in filter's from or to fields
|
||||||
|
* (evm) [tharsis#616](https://github.com/tharsis/ethermint/issues/616) Fix halt on deeply nested stack of cache context. Stack is now flattened before iterating over the tx logs.
|
||||||
|
* (rpc, evm) [tharsis#614](https://github.com/tharsis/ethermint/issues/614) Use JSON for (un)marshaling tx `Log`s from events.
|
||||||
|
* (rpc) [tharsis#611](https://github.com/tharsis/ethermint/pull/611) Fix panic on JSON-RPC when querying for an invalid block height.
|
||||||
|
* (cmd) [tharsis#483](https://github.com/tharsis/ethermint/pull/483) Use config values on genesis accounts.
|
||||||
|
|
||||||
|
## [v0.6.0] - 2021-09-29
|
||||||
|
|
||||||
### State Machine Breaking
|
### State Machine Breaking
|
||||||
|
|
||||||
* (app) [tharsis#476](https://github.com/tharsis/ethermint/pull/476) Update Bech32 HRP to `ethm`.
|
* (app) [tharsis#476](https://github.com/tharsis/ethermint/pull/476) Update Bech32 HRP to `ethm`.
|
||||||
* (evm) [tharsis#556](https://github.com/tharsis/ethermint/pull/556) Remove tx logs and block bloom from chain state
|
* (evm) [tharsis#556](https://github.com/tharsis/ethermint/pull/556) Remove tx logs and block bloom from chain state
|
||||||
|
* (evm) [tharsis#590](https://github.com/tharsis/ethermint/pull/590) Contract storage key is not hashed anymore
|
||||||
|
|
||||||
### API Breaking
|
### API Breaking
|
||||||
|
|
||||||
@@ -49,12 +265,16 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
* (evm) [tharsis#469](https://github.com/tharsis/ethermint/pull/469) Support [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
|
* (evm) [tharsis#469](https://github.com/tharsis/ethermint/pull/469) Support [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
|
||||||
* (evm) [tharsis#417](https://github.com/tharsis/ethermint/pull/417) Add `EvmHooks` for tx post-processing
|
* (evm) [tharsis#417](https://github.com/tharsis/ethermint/pull/417) Add `EvmHooks` for tx post-processing
|
||||||
* (rpc) [tharsis#506](https://github.com/tharsis/ethermint/pull/506) Support for `debug_traceTransaction` RPC endpoint
|
* (rpc) [tharsis#506](https://github.com/tharsis/ethermint/pull/506) Support for `debug_traceTransaction` RPC endpoint
|
||||||
* (rpc) [tharsis#555](https://github.com/tharsis/ethermint/pull/555) Support for `debug_traceBlockByNumber` RPC endpoint
|
* (rpc) [tharsis#555](https://github.com/tharsis/ethermint/pull/555) Support for `debug_traceBlockByNumber` RPC endpoint
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (rpc, server) [tharsis#600](https://github.com/tharsis/ethermint/pull/600) Add TLS configuration for websocket API
|
||||||
|
* (rpc) [tharsis#598](https://github.com/tharsis/ethermint/pull/598) Check truncation when creating a `BlockNumber` from `big.Int`
|
||||||
|
* (evm) [tharsis#597](https://github.com/tharsis/ethermint/pull/597) Check for `uint64` -> `int64` block height overflow on `GetHashFn`
|
||||||
|
* (evm) [tharsis#579](https://github.com/tharsis/ethermint/pull/579) Update `DeriveChainID` function to handle `v` signature values `< 35`.
|
||||||
* (encoding) [tharsis#478](https://github.com/tharsis/ethermint/pull/478) Register `Evidence` to amino codec.
|
* (encoding) [tharsis#478](https://github.com/tharsis/ethermint/pull/478) Register `Evidence` to amino codec.
|
||||||
* (rpc) [tharsis#478](https://github.com/tharsis/ethermint/pull/481) Getting the node configuration when calling the `miner` rpc methods.
|
* (rpc) [tharsis#478](https://github.com/tharsis/ethermint/pull/481) Getting the node configuration when calling the `miner` rpc methods.
|
||||||
* (cli) [tharsis#561](https://github.com/tharsis/ethermint/pull/561) `Export` and `Start` commands now use the same home directory.
|
* (cli) [tharsis#561](https://github.com/tharsis/ethermint/pull/561) `Export` and `Start` commands now use the same home directory.
|
||||||
@@ -62,6 +282,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
* (evm) [tharsis#461](https://github.com/tharsis/ethermint/pull/461) Increase performance of `StateDB` transaction log storage (r/w).
|
* (evm) [tharsis#461](https://github.com/tharsis/ethermint/pull/461) Increase performance of `StateDB` transaction log storage (r/w).
|
||||||
|
* (evm) [tharsis#566](https://github.com/tharsis/ethermint/pull/566) Introduce `stateErr` store in `StateDB` to avoid meaningless operations if any error happened before
|
||||||
|
* (rpc, evm) [tharsis#587](https://github.com/tharsis/ethermint/pull/587) Apply bloom filter when query ethlogs with range of blocks
|
||||||
|
* (evm) [tharsis#586](https://github.com/tharsis/ethermint/pull/586) Benchmark evm keeper
|
||||||
|
|
||||||
## [v0.5.0] - 2021-08-20
|
## [v0.5.0] - 2021-08-20
|
||||||
|
|
||||||
@@ -78,7 +301,7 @@ the Tracer type used to collect execution traces from the EVM transaction execut
|
|||||||
* (evm) [tharsis#68](https://github.com/tharsis/ethermint/issues/68) Replace block hash storage map to use staking `HistoricalInfo`.
|
* (evm) [tharsis#68](https://github.com/tharsis/ethermint/issues/68) Replace block hash storage map to use staking `HistoricalInfo`.
|
||||||
* (evm) [tharsis#276](https://github.com/tharsis/ethermint/pull/276) Vm errors don't result in cosmos tx failure, just
|
* (evm) [tharsis#276](https://github.com/tharsis/ethermint/pull/276) Vm errors don't result in cosmos tx failure, just
|
||||||
different tx state and events.
|
different tx state and events.
|
||||||
* (evm) [tharsis#342](https://github.com/tharsis/ethermint/issues/342) Don't clear balance when resetting the account.
|
* (evm) [tharsis#342](https://github.com/tharsis/ethermint/issues/342) Don't clear balance when resetting the account.
|
||||||
* (evm) [tharsis#334](https://github.com/tharsis/ethermint/pull/334) Log index changed to the index in block rather than
|
* (evm) [tharsis#334](https://github.com/tharsis/ethermint/pull/334) Log index changed to the index in block rather than
|
||||||
tx.
|
tx.
|
||||||
* (evm) [tharsis#399](https://github.com/tharsis/ethermint/pull/399) Exception in sub-message call reverts the call if it's not propagated.
|
* (evm) [tharsis#399](https://github.com/tharsis/ethermint/pull/399) Exception in sub-message call reverts the call if it's not propagated.
|
||||||
@@ -92,8 +315,8 @@ the Tracer type used to collect execution traces from the EVM transaction execut
|
|||||||
* The `TxReceipt`, `TxReceiptsByBlockHeight` endpoints have been removed from the Query service.
|
* The `TxReceipt`, `TxReceiptsByBlockHeight` endpoints have been removed from the Query service.
|
||||||
* The `ContractAddress`, `Bloom` have been removed from the `MsgEthereumTxResponse` and the
|
* The `ContractAddress`, `Bloom` have been removed from the `MsgEthereumTxResponse` and the
|
||||||
response now contains the ethereum-formatted `Hash` in hex format.
|
response now contains the ethereum-formatted `Hash` in hex format.
|
||||||
* (eth) [\#845](https://github.com/cosmos/ethermint/pull/845) The `eth` namespace must be included in the list of API's as default to run the rpc server without error.
|
* (eth) [tharsis#845](https://github.com/cosmos/ethermint/pull/845) The `eth` namespace must be included in the list of API's as default to run the rpc server without error.
|
||||||
* (evm) [#202](https://github.com/tharsis/ethermint/pull/202) Web3 api `SendTransaction`/`SendRawTransaction` returns ethereum compatible transaction hash, and query api `GetTransaction*` also accept that.
|
* (evm) [tharsis#202](https://github.com/tharsis/ethermint/pull/202) Web3 api `SendTransaction`/`SendRawTransaction` returns ethereum compatible transaction hash, and query api `GetTransaction*` also accept that.
|
||||||
* (rpc) [tharsis#258](https://github.com/tharsis/ethermint/pull/258) Return empty `BloomFilter` instead of throwing an error when it cannot be found (`nil` or empty).
|
* (rpc) [tharsis#258](https://github.com/tharsis/ethermint/pull/258) Return empty `BloomFilter` instead of throwing an error when it cannot be found (`nil` or empty).
|
||||||
* (rpc) [tharsis#277](https://github.com/tharsis/ethermint/pull/321) Fix `BloomFilter` response.
|
* (rpc) [tharsis#277](https://github.com/tharsis/ethermint/pull/321) Fix `BloomFilter` response.
|
||||||
|
|
||||||
@@ -109,13 +332,13 @@ the Tracer type used to collect execution traces from the EVM transaction execut
|
|||||||
* (deps) [tharsis#423](https://github.com/tharsis/ethermint/pull/423) Bump Cosmos SDK and Tendermint versions to [v0.43.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0) and [v0.34.11](https://github.com/tendermint/tendermint/releases/tag/v0.34.11), respectively.
|
* (deps) [tharsis#423](https://github.com/tharsis/ethermint/pull/423) Bump Cosmos SDK and Tendermint versions to [v0.43.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0) and [v0.34.11](https://github.com/tendermint/tendermint/releases/tag/v0.34.11), respectively.
|
||||||
* (evm) [tharsis#66](https://github.com/tharsis/ethermint/issues/66) Support legacy transaction types for signing.
|
* (evm) [tharsis#66](https://github.com/tharsis/ethermint/issues/66) Support legacy transaction types for signing.
|
||||||
* (evm) [tharsis#24](https://github.com/tharsis/ethermint/pull/24) Implement metrics for `MsgEthereumTx`, state transitions, `BeginBlock` and `EndBlock`.
|
* (evm) [tharsis#24](https://github.com/tharsis/ethermint/pull/24) Implement metrics for `MsgEthereumTx`, state transitions, `BeginBlock` and `EndBlock`.
|
||||||
* (rpc) [#124](https://github.com/tharsis/ethermint/issues/124) Implement `txpool_content`, `txpool_inspect` and `txpool_status` RPC methods
|
* (rpc) [tharsis#124](https://github.com/tharsis/ethermint/issues/124) Implement `txpool_content`, `txpool_inspect` and `txpool_status` RPC methods
|
||||||
* (rpc) [tharsis#112](https://github.com/tharsis/ethermint/pull/153) Fix `eth_coinbase` to return the ethereum address of the validator
|
* (rpc) [tharsis#112](https://github.com/tharsis/ethermint/pull/153) Fix `eth_coinbase` to return the ethereum address of the validator
|
||||||
* (rpc) [tharsis#176](https://github.com/tharsis/ethermint/issues/176) Support fetching pending nonce
|
* (rpc) [tharsis#176](https://github.com/tharsis/ethermint/issues/176) Support fetching pending nonce
|
||||||
* (rpc) [tharsis#272](https://github.com/tharsis/ethermint/pull/272) do binary search to estimate gas accurately
|
* (rpc) [tharsis#272](https://github.com/tharsis/ethermint/pull/272) do binary search to estimate gas accurately
|
||||||
* (rpc) [#313](https://github.com/tharsis/ethermint/pull/313) Implement internal debug namespace (Not including logger functions nor traces).
|
* (rpc) [tharsis#313](https://github.com/tharsis/ethermint/pull/313) Implement internal debug namespace (Not including logger functions nor traces).
|
||||||
* (rpc) [#349](https://github.com/tharsis/ethermint/pull/349) Implement configurable JSON-RPC APIs to manage enabled namespaces.
|
* (rpc) [tharsis#349](https://github.com/tharsis/ethermint/pull/349) Implement configurable JSON-RPC APIs to manage enabled namespaces.
|
||||||
* (rpc) [#377](https://github.com/tharsis/ethermint/pull/377) Implement `miner_` namespace. `miner_setEtherbase` and `miner_setGasPrice` are working as intended. All the other calls are not applicable and return `unsupported`.
|
* (rpc) [tharsis#377](https://github.com/tharsis/ethermint/pull/377) Implement `miner_` namespace. `miner_setEtherbase` and `miner_setGasPrice` are working as intended. All the other calls are not applicable and return `unsupported`.
|
||||||
* (eth) [tharsis#460](https://github.com/tharsis/ethermint/issues/460) Add support for EIP-1898.
|
* (eth) [tharsis#460](https://github.com/tharsis/ethermint/issues/460) Add support for EIP-1898.
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
@@ -129,41 +352,41 @@ the Tracer type used to collect execution traces from the EVM transaction execut
|
|||||||
|
|
||||||
### API Breaking
|
### API Breaking
|
||||||
|
|
||||||
* (faucet) [\#678](https://github.com/cosmos/ethermint/pull/678) Faucet module has been removed in favor of client libraries such as [`@cosmjs/faucet`](https://github.com/cosmos/cosmjs/tree/master/packages/faucet).
|
* (faucet) [tharsis#678](https://github.com/cosmos/ethermint/pull/678) Faucet module has been removed in favor of client libraries such as [`@cosmjs/faucet`](https://github.com/cosmos/cosmjs/tree/master/packages/faucet).
|
||||||
* (evm) [\#670](https://github.com/cosmos/ethermint/pull/670) Migrate types to the ones defined by the protobuf messages, which are required for the stargate release.
|
* (evm) [tharsis#670](https://github.com/cosmos/ethermint/pull/670) Migrate types to the ones defined by the protobuf messages, which are required for the stargate release.
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* (evm) [\#799](https://github.com/cosmos/ethermint/issues/799) Fix wrong precision in calculation of gas fee.
|
* (evm) [tharsis#799](https://github.com/cosmos/ethermint/issues/799) Fix wrong precision in calculation of gas fee.
|
||||||
* (evm) [\#760](https://github.com/cosmos/ethermint/issues/760) Fix Failed to call function EstimateGas.
|
* (evm) [tharsis#760](https://github.com/cosmos/ethermint/issues/760) Fix Failed to call function EstimateGas.
|
||||||
* (evm) [\#767](https://github.com/cosmos/ethermint/issues/767) Fix error of timeout when using Truffle to deploy contract.
|
* (evm) [tharsis#767](https://github.com/cosmos/ethermint/issues/767) Fix error of timeout when using Truffle to deploy contract.
|
||||||
* (evm) [\#751](https://github.com/cosmos/ethermint/issues/751) Fix misused method to calculate block hash in evm related function.
|
* (evm) [tharsis#751](https://github.com/cosmos/ethermint/issues/751) Fix misused method to calculate block hash in evm related function.
|
||||||
* (evm) [\#721](https://github.com/cosmos/ethermint/issues/721) Fix mismatch block hash in rpc response when use eht.getBlock.
|
* (evm) [tharsis#721](https://github.com/cosmos/ethermint/issues/721) Fix mismatch block hash in rpc response when use eht.getBlock.
|
||||||
* (evm) [\#730](https://github.com/cosmos/ethermint/issues/730) Fix 'EIP2028' not open when Istanbul version has been enabled.
|
* (evm) [tharsis#730](https://github.com/cosmos/ethermint/issues/730) Fix 'EIP2028' not open when Istanbul version has been enabled.
|
||||||
* (evm) [\#749](https://github.com/cosmos/ethermint/issues/749) Fix panic in `AnteHandler` when gas price larger than 100000
|
* (evm) [tharsis#749](https://github.com/cosmos/ethermint/issues/749) Fix panic in `AnteHandler` when gas price larger than 100000
|
||||||
* (evm) [\#747](https://github.com/cosmos/ethermint/issues/747) Fix format errors in String() of QueryETHLogs
|
* (evm) [tharsis#747](https://github.com/cosmos/ethermint/issues/747) Fix format errors in String() of QueryETHLogs
|
||||||
* (evm) [\#742](https://github.com/cosmos/ethermint/issues/742) Add parameter check for evm query func.
|
* (evm) [tharsis#742](https://github.com/cosmos/ethermint/issues/742) Add parameter check for evm query func.
|
||||||
* (evm) [\#687](https://github.com/cosmos/ethermint/issues/687) Fix nonce check to explicitly check for the correct nonce, rather than a simple 'greater than' comparison.
|
* (evm) [tharsis#687](https://github.com/cosmos/ethermint/issues/687) Fix nonce check to explicitly check for the correct nonce, rather than a simple 'greater than' comparison.
|
||||||
* (api) [\#687](https://github.com/cosmos/ethermint/issues/687) Returns error for a transaction with an incorrect nonce.
|
* (api) [tharsis#687](https://github.com/cosmos/ethermint/issues/687) Returns error for a transaction with an incorrect nonce.
|
||||||
* (evm) [\#674](https://github.com/cosmos/ethermint/issues/674) Reset all cache after account data has been committed in `EndBlock` to make sure every node state consistent.
|
* (evm) [tharsis#674](https://github.com/cosmos/ethermint/issues/674) Reset all cache after account data has been committed in `EndBlock` to make sure every node state consistent.
|
||||||
* (evm) [\#672](https://github.com/cosmos/ethermint/issues/672) Fix panic of `wrong Block.Header.AppHash` when restart a node with snapshot.
|
* (evm) [tharsis#672](https://github.com/cosmos/ethermint/issues/672) Fix panic of `wrong Block.Header.AppHash` when restart a node with snapshot.
|
||||||
* (evm) [\#775](https://github.com/cosmos/ethermint/issues/775) MisUse of headHash as blockHash when create EVM context.
|
* (evm) [tharsis#775](https://github.com/cosmos/ethermint/issues/775) MisUse of headHash as blockHash when create EVM context.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
* (api) [\#821](https://github.com/cosmos/ethermint/pull/821) Individually enable the api modules. Will be implemented in the latest version of ethermint with the upcoming stargate upgrade.
|
* (api) [tharsis#821](https://github.com/cosmos/ethermint/pull/821) Individually enable the api modules. Will be implemented in the latest version of ethermint with the upcoming stargate upgrade.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
* (api) [\#825](https://github.com/cosmos/ethermint/pull/825) Individually enable the api modules. Will be implemented in the latest version of ethermint with the upcoming stargate upgrade.
|
* (api) [tharsis#825](https://github.com/cosmos/ethermint/pull/825) Individually enable the api modules. Will be implemented in the latest version of ethermint with the upcoming stargate upgrade.
|
||||||
|
|
||||||
## [v0.4.0] - 2020-12-15
|
## [v0.4.0] - 2020-12-15
|
||||||
|
|
||||||
### API Breaking
|
### API Breaking
|
||||||
|
|
||||||
* (evm) [\#661](https://github.com/cosmos/ethermint/pull/661) `Balance` field has been removed from the evm module's `GenesisState`.
|
* (evm) [tharsis#661](https://github.com/cosmos/ethermint/pull/661) `Balance` field has been removed from the evm module's `GenesisState`.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* (rpc) [\#571](https://github.com/cosmos/ethermint/pull/571) Add pending queries to JSON-RPC calls. This allows for the querying of pending transactions and other relevant information that pertains to the pending state:
|
* (rpc) [tharsis#571](https://github.com/cosmos/ethermint/pull/571) Add pending queries to JSON-RPC calls. This allows for the querying of pending transactions and other relevant information that pertains to the pending state:
|
||||||
* `eth_getBalance`
|
* `eth_getBalance`
|
||||||
* `eth_getTransactionCount`
|
* `eth_getTransactionCount`
|
||||||
* `eth_getBlockTransactionCountByNumber`
|
* `eth_getBlockTransactionCountByNumber`
|
||||||
@@ -174,149 +397,149 @@ the Tracer type used to collect execution traces from the EVM transaction execut
|
|||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
* (evm) [\#661](https://github.com/cosmos/ethermint/pull/661) Add invariant check for account balance and account nonce.
|
* (evm) [tharsis#661](https://github.com/cosmos/ethermint/pull/661) Add invariant check for account balance and account nonce.
|
||||||
* (deps) [\#654](https://github.com/cosmos/ethermint/pull/654) Bump go-ethereum version to [v1.9.25](https://github.com/ethereum/go-ethereum/releases/tag/v1.9.25)
|
* (deps) [tharsis#654](https://github.com/cosmos/ethermint/pull/654) Bump go-ethereum version to [v1.9.25](https://github.com/ethereum/go-ethereum/releases/tag/v1.9.25)
|
||||||
* (evm) [\#627](https://github.com/cosmos/ethermint/issues/627) Add extra EIPs parameter to apply custom EVM jump tables.
|
* (evm) [tharsis#627](https://github.com/cosmos/ethermint/issues/627) Add extra EIPs parameter to apply custom EVM jump tables.
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* (evm) [\#661](https://github.com/cosmos/ethermint/pull/661) Set nonce to the EVM account on genesis initialization.
|
* (evm) [tharsis#661](https://github.com/cosmos/ethermint/pull/661) Set nonce to the EVM account on genesis initialization.
|
||||||
* (rpc) [\#648](https://github.com/cosmos/ethermint/issues/648) Fix block cumulative gas used value.
|
* (rpc) [tharsis#648](https://github.com/cosmos/ethermint/issues/648) Fix block cumulative gas used value.
|
||||||
* (evm) [\#621](https://github.com/cosmos/ethermint/issues/621) EVM `GenesisAccount` fields now share the same format as the auth module `Account`.
|
* (evm) [tharsis#621](https://github.com/cosmos/ethermint/issues/621) EVM `GenesisAccount` fields now share the same format as the auth module `Account`.
|
||||||
* (evm) [\#618](https://github.com/cosmos/ethermint/issues/618) Add missing EVM `Context` `GetHash` field that retrieves a the header hash from a given block height.
|
* (evm) [tharsis#618](https://github.com/cosmos/ethermint/issues/618) Add missing EVM `Context` `GetHash` field that retrieves a the header hash from a given block height.
|
||||||
* (app) [\#617](https://github.com/cosmos/ethermint/issues/617) Fix genesis export functionality.
|
* (app) [tharsis#617](https://github.com/cosmos/ethermint/issues/617) Fix genesis export functionality.
|
||||||
* (rpc) [\#574](https://github.com/cosmos/ethermint/issues/574) Fix outdated version from `eth_protocolVersion`.
|
* (rpc) [tharsis#574](https://github.com/cosmos/ethermint/issues/574) Fix outdated version from `eth_protocolVersion`.
|
||||||
|
|
||||||
## [v0.3.1] - 2020-11-24
|
## [v0.3.1] - 2020-11-24
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
* (deps) [\#615](https://github.com/cosmos/ethermint/pull/615) Bump Cosmos SDK version to [v0.39.2](https://github.com/cosmos/cosmos-sdk/tag/v0.39.2)
|
* (deps) [tharsis#615](https://github.com/cosmos/ethermint/pull/615) Bump Cosmos SDK version to [v0.39.2](https://github.com/cosmos/cosmos-sdk/tag/v0.39.2)
|
||||||
* (deps) [\#610](https://github.com/cosmos/ethermint/pull/610) Update Go dependency to 1.15+.
|
* (deps) [tharsis#610](https://github.com/cosmos/ethermint/pull/610) Update Go dependency to 1.15+.
|
||||||
* (evm) [#603](https://github.com/cosmos/ethermint/pull/603) Add state transition params that enable or disable the EVM `Call` and `Create` operations.
|
* (evm) [tharsis#603](https://github.com/cosmos/ethermint/pull/603) Add state transition params that enable or disable the EVM `Call` and `Create` operations.
|
||||||
* (deps) [\#602](https://github.com/cosmos/ethermint/pull/602) Bump tendermint version to [v0.33.9](https://github.com/tendermint/tendermint/releases/tag/v0.33.9)
|
* (deps) [tharsis#602](https://github.com/cosmos/ethermint/pull/602) Bump tendermint version to [v0.33.9](https://github.com/tendermint/tendermint/releases/tag/v0.33.9)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* (rpc) [\#613](https://github.com/cosmos/ethermint/issues/613) Fix potential deadlock caused if the keyring `List` returned an error.
|
* (rpc) [tharsis#613](https://github.com/cosmos/ethermint/issues/613) Fix potential deadlock caused if the keyring `List` returned an error.
|
||||||
|
|
||||||
## [v0.3.0] - 2020-11-16
|
## [v0.3.0] - 2020-11-16
|
||||||
|
|
||||||
### API Breaking
|
### API Breaking
|
||||||
|
|
||||||
* (crypto) [\#559](https://github.com/cosmos/ethermint/pull/559) Refactored crypto package in preparation for the SDK's Stargate release:
|
* (crypto) [tharsis#559](https://github.com/cosmos/ethermint/pull/559) Refactored crypto package in preparation for the SDK's Stargate release:
|
||||||
* `crypto.PubKeySecp256k1` and `crypto.PrivKeySecp256k1` are now `ethsecp256k1.PubKey` and `ethsecp256k1.PrivKey`, respectively
|
* `crypto.PubKeySecp256k1` and `crypto.PrivKeySecp256k1` are now `ethsecp256k1.PubKey` and `ethsecp256k1.PrivKey`, respectively
|
||||||
* Moved SDK `SigningAlgo` implementation for Ethermint's Secp256k1 key to `crypto/hd` package.
|
* Moved SDK `SigningAlgo` implementation for Ethermint's Secp256k1 key to `crypto/hd` package.
|
||||||
* (rpc) [\#588](https://github.com/cosmos/ethermint/pull/588) The `rpc` package has been refactored to account for the separation of each
|
* (rpc) [tharsis#588](https://github.com/cosmos/ethermint/pull/588) The `rpc` package has been refactored to account for the separation of each
|
||||||
corresponding Ethereum API namespace:
|
corresponding Ethereum API namespace:
|
||||||
* `rpc/namespaces/eth`: `eth` namespace. Exposes the `PublicEthereumAPI` and the `PublicFilterAPI`.
|
* `rpc/namespaces/eth`: `eth` namespace. Exposes the `PublicEthereumAPI` and the `PublicFilterAPI`.
|
||||||
* `rpc/namespaces/personal`: `personal` namespace. Exposes the `PrivateAccountAPI`.
|
* `rpc/namespaces/personal`: `personal` namespace. Exposes the `PrivateAccountAPI`.
|
||||||
* `rpc/namespaces/net`: `net` namespace. Exposes the `PublicNetAPI`.
|
* `rpc/namespaces/net`: `net` namespace. Exposes the `PublicNetAPI`.
|
||||||
* `rpc/namespaces/web3`: `web3` namespace. Exposes the `PublicWeb3API`.
|
* `rpc/namespaces/web3`: `web3` namespace. Exposes the `PublicWeb3API`.
|
||||||
* (evm) [\#588](https://github.com/cosmos/ethermint/pull/588) The EVM transaction CLI has been removed in favor of the JSON-RPC.
|
* (evm) [tharsis#588](https://github.com/cosmos/ethermint/pull/588) The EVM transaction CLI has been removed in favor of the JSON-RPC.
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
* (deps) [\#594](https://github.com/cosmos/ethermint/pull/594) Bump go-ethereum version to [v1.9.24](https://github.com/ethereum/go-ethereum/releases/tag/v1.9.24)
|
* (deps) [tharsis#594](https://github.com/cosmos/ethermint/pull/594) Bump go-ethereum version to [v1.9.24](https://github.com/ethereum/go-ethereum/releases/tag/v1.9.24)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* (ante) [\#597](https://github.com/cosmos/ethermint/pull/597) Fix incorrect fee check on `AnteHandler`.
|
* (ante) [tharsis#597](https://github.com/cosmos/ethermint/pull/597) Fix incorrect fee check on `AnteHandler`.
|
||||||
* (evm) [\#583](https://github.com/cosmos/ethermint/pull/583) Fixes incorrect resetting of tx count and block bloom during `BeginBlock`, as well as gas consumption.
|
* (evm) [tharsis#583](https://github.com/cosmos/ethermint/pull/583) Fixes incorrect resetting of tx count and block bloom during `BeginBlock`, as well as gas consumption.
|
||||||
* (crypto) [\#577](https://github.com/cosmos/ethermint/pull/577) Fix `BIP44HDPath` that did not prepend `m/` to the path. This now uses the `DefaultBaseDerivationPath` variable from go-ethereum to ensure addresses are consistent.
|
* (crypto) [tharsis#577](https://github.com/cosmos/ethermint/pull/577) Fix `BIP44HDPath` that did not prepend `m/` to the path. This now uses the `DefaultBaseDerivationPath` variable from go-ethereum to ensure addresses are consistent.
|
||||||
|
|
||||||
## [v0.2.1] - 2020-09-30
|
## [v0.2.1] - 2020-09-30
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* (rpc) [\#552](https://github.com/cosmos/ethermint/pull/552) Implement Eth Personal namespace `personal_importRawKey`.
|
* (rpc) [tharsis#552](https://github.com/cosmos/ethermint/pull/552) Implement Eth Personal namespace `personal_importRawKey`.
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
|
||||||
* (keys) [\#554](https://github.com/cosmos/ethermint/pull/554) Fix private key derivation.
|
* (keys) [tharsis#554](https://github.com/cosmos/ethermint/pull/554) Fix private key derivation.
|
||||||
* (app/ante) [\#550](https://github.com/cosmos/ethermint/pull/550) Update ante handler nonce verification to accept any nonce greater than or equal to the expected nonce to allow to successive transactions.
|
* (app/ante) [tharsis#550](https://github.com/cosmos/ethermint/pull/550) Update ante handler nonce verification to accept any nonce greater than or equal to the expected nonce to allow to successive transactions.
|
||||||
|
|
||||||
## [v0.2.0] - 2020-09-24
|
## [v0.2.0] - 2020-09-24
|
||||||
|
|
||||||
### State Machine Breaking
|
### State Machine Breaking
|
||||||
|
|
||||||
* (app) [\#540](https://github.com/cosmos/ethermint/issues/540) Chain identifier's format has been changed to match the Cosmos `chainID` [standard](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-5.md), which is required for IBC. The epoch number of the ID is used as the EVM `chainID`.
|
* (app) [tharsis#540](https://github.com/cosmos/ethermint/issues/540) Chain identifier's format has been changed to match the Cosmos `chainID` [standard](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-5.md), which is required for IBC. The epoch number of the ID is used as the EVM `chainID`.
|
||||||
|
|
||||||
### API Breaking
|
### API Breaking
|
||||||
|
|
||||||
* (types) [\#503](https://github.com/cosmos/ethermint/pull/503) The `types.DenomDefault` constant for `"aphoton"` has been renamed to `types.AttoPhoton`.
|
* (types) [tharsis#503](https://github.com/cosmos/ethermint/pull/503) The `types.DenomDefault` constant for `"aphoton"` has been renamed to `types.AttoPhoton`.
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
* (types) [\#504](https://github.com/cosmos/ethermint/pull/504) Unmarshal a JSON `EthAccount` using an Ethereum hex address in addition to Bech32.
|
* (types) [tharsis#504](https://github.com/cosmos/ethermint/pull/504) Unmarshal a JSON `EthAccount` using an Ethereum hex address in addition to Bech32.
|
||||||
* (types) [\#503](https://github.com/cosmos/ethermint/pull/503) Add `--coin-denom` flag to testnet command that sets the given coin denomination to SDK and Ethermint parameters.
|
* (types) [tharsis#503](https://github.com/cosmos/ethermint/pull/503) Add `--coin-denom` flag to testnet command that sets the given coin denomination to SDK and Ethermint parameters.
|
||||||
* (types) [\#502](https://github.com/cosmos/ethermint/pull/502) `EthAccount` now also exposes the Ethereum hex address in `string` format to clients.
|
* (types) [tharsis#502](https://github.com/cosmos/ethermint/pull/502) `EthAccount` now also exposes the Ethereum hex address in `string` format to clients.
|
||||||
* (types) [\#494](https://github.com/cosmos/ethermint/pull/494) Update `EthAccount` public key JSON type to `string`.
|
* (types) [tharsis#494](https://github.com/cosmos/ethermint/pull/494) Update `EthAccount` public key JSON type to `string`.
|
||||||
* (app) [\#471](https://github.com/cosmos/ethermint/pull/471) Add `x/upgrade` module for managing software updates.
|
* (app) [tharsis#471](https://github.com/cosmos/ethermint/pull/471) Add `x/upgrade` module for managing software updates.
|
||||||
* (`x/evm`) [\#458](https://github.com/cosmos/ethermint/pull/458) Define parameter for token denomination used for the EVM module.
|
* (evm) [tharsis#458](https://github.com/cosmos/ethermint/pull/458) Define parameter for token denomination used for the EVM module.
|
||||||
* (`x/evm`) [\#443](https://github.com/cosmos/ethermint/issues/443) Support custom Ethereum `ChainConfig` params.
|
* (evm) [tharsis#443](https://github.com/cosmos/ethermint/issues/443) Support custom Ethereum `ChainConfig` params.
|
||||||
* (types) [\#434](https://github.com/cosmos/ethermint/issues/434) Update default denomination to Atto Photon (`aphoton`).
|
* (types) [tharsis#434](https://github.com/cosmos/ethermint/issues/434) Update default denomination to Atto Photon (`aphoton`).
|
||||||
* (types) [\#515](https://github.com/cosmos/ethermint/pull/515) Update minimum gas price to be 1.
|
* (types) [tharsis#515](https://github.com/cosmos/ethermint/pull/515) Update minimum gas price to be 1.
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* (ante) [\#525](https://github.com/cosmos/ethermint/pull/525) Add message validation decorator to `AnteHandler` for `MsgEthereumTx`.
|
* (ante) [tharsis#525](https://github.com/cosmos/ethermint/pull/525) Add message validation decorator to `AnteHandler` for `MsgEthereumTx`.
|
||||||
* (types) [\#507](https://github.com/cosmos/ethermint/pull/507) Fix hardcoded `aphoton` on `EthAccount` balance getter and setter.
|
* (types) [tharsis#507](https://github.com/cosmos/ethermint/pull/507) Fix hardcoded `aphoton` on `EthAccount` balance getter and setter.
|
||||||
* (types) [\#501](https://github.com/cosmos/ethermint/pull/501) Fix bech32 encoding error by using the compressed ethereum secp256k1 public key.
|
* (types) [tharsis#501](https://github.com/cosmos/ethermint/pull/501) Fix bech32 encoding error by using the compressed ethereum secp256k1 public key.
|
||||||
* (`x/evm`) [\#496](https://github.com/cosmos/ethermint/pull/496) Fix bugs on `journal.revert` and `CommitStateDB.Copy`.
|
* (evm) [tharsis#496](https://github.com/cosmos/ethermint/pull/496) Fix bugs on `journal.revert` and `CommitStateDB.Copy`.
|
||||||
* (types) [\#480](https://github.com/cosmos/ethermint/pull/480) Update [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) coin type to `60` to satisfy [EIP84](https://github.com/ethereum/EIPs/issues/84).
|
* (types) [tharsis#480](https://github.com/cosmos/ethermint/pull/480) Update [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) coin type to `60` to satisfy [EIP84](https://github.com/ethereum/EIPs/issues/84).
|
||||||
* (types) [\#513](https://github.com/cosmos/ethermint/pull/513) Fix simulated transaction bug that was causing a consensus error by unintentionally affecting the state.
|
* (types) [tharsis#513](https://github.com/cosmos/ethermint/pull/513) Fix simulated transaction bug that was causing a consensus error by unintentionally affecting the state.
|
||||||
|
|
||||||
## [v0.1.0] - 2020-08-23
|
## [v0.1.0] - 2020-08-23
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
* (sdk) [\#386](https://github.com/cosmos/ethermint/pull/386) Bump Cosmos SDK version to [v0.39.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.39.1)
|
* (sdk) [tharsis#386](https://github.com/cosmos/ethermint/pull/386) Bump Cosmos SDK version to [v0.39.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.39.1)
|
||||||
* (`x/evm`) [\#181](https://github.com/cosmos/ethermint/issues/181) Updated EVM module to the recommended module structure.
|
* (evm) [tharsis#181](https://github.com/cosmos/ethermint/issues/181) Updated EVM module to the recommended module structure.
|
||||||
* (app) [\#188](https://github.com/cosmos/ethermint/issues/186) Misc cleanup:
|
* (app) [tharsis#188](https://github.com/cosmos/ethermint/issues/186) Misc cleanup:
|
||||||
* (`x/evm`) Rename `EthereumTxMsg` --> `MsgEthereumTx` and `EmintMsg` --> `MsgEthermint` for consistency with SDK standards
|
* (evm) Rename `EthereumTxMsg` --> `MsgEthereumTx` and `EmintMsg` --> `MsgEthermint` for consistency with SDK standards
|
||||||
* Updated integration and unit tests to use `EthermintApp` as testing suite
|
* Updated integration and unit tests to use `EthermintApp` as testing suite
|
||||||
* Use expected `Keeper` interface for `AccountKeeper`
|
* Use expected `Keeper` interface for `AccountKeeper`
|
||||||
* Replaced `count` type in keeper with `int`
|
* Replaced `count` type in keeper with `int`
|
||||||
* Add SDK events for transactions
|
* Add SDK events for transactions
|
||||||
* [\#236](https://github.com/cosmos/ethermint/pull/236) Changes from upgrade:
|
* [tharsis#236](https://github.com/cosmos/ethermint/pull/236) Changes from upgrade:
|
||||||
* (`app/ante`) Moved `AnteHandler` implementation to `app/ante`
|
* (`app/ante`) Moved `AnteHandler` implementation to `app/ante`
|
||||||
* (keys) Marked `ExportEthKeyCommand` as **UNSAFE**
|
* (keys) Marked `ExportEthKeyCommand` as **UNSAFE**
|
||||||
* (`x/evm`) Moved `BeginBlock` and `EndBlock` to `x/evm/abci.go`
|
* (evm) Moved `BeginBlock` and `EndBlock` to `x/evm/abci.go`
|
||||||
* (`x/evm`) [\#255](https://github.com/cosmos/ethermint/pull/255) Add missing `GenesisState` fields and support `ExportGenesis` functionality.
|
* (evm) [tharsis#255](https://github.com/cosmos/ethermint/pull/255) Add missing `GenesisState` fields and support `ExportGenesis` functionality.
|
||||||
* [\#272](https://github.com/cosmos/ethermint/pull/272) Add `Logger` for evm module.
|
* [tharsis#272](https://github.com/cosmos/ethermint/pull/272) Add `Logger` for evm module.
|
||||||
* [\#317](https://github.com/cosmos/ethermint/pull/317) `GenesisAccount` validation.
|
* [tharsis#317](https://github.com/cosmos/ethermint/pull/317) `GenesisAccount` validation.
|
||||||
* (`x/evm`) [\#319](https://github.com/cosmos/ethermint/pull/319) Various evm improvements:
|
* (evm) [tharsis#319](https://github.com/cosmos/ethermint/pull/319) Various evm improvements:
|
||||||
* Add transaction `[]*ethtypes.Logs` to evm's `GenesisState` to persist logs after an upgrade.
|
* Add transaction `[]*ethtypes.Logs` to evm's `GenesisState` to persist logs after an upgrade.
|
||||||
* Remove evm `CodeKey` and `BlockKey`in favor of a prefix `Store`.
|
* Remove evm `CodeKey` and `BlockKey`in favor of a prefix `Store`.
|
||||||
* Set `BlockBloom` during `EndBlock` instead of `BeginBlock`.
|
* Set `BlockBloom` during `EndBlock` instead of `BeginBlock`.
|
||||||
* `Commit` state object and `Finalize` storage after `InitGenesis` setup.
|
* `Commit` state object and `Finalize` storage after `InitGenesis` setup.
|
||||||
* (rpc) [\#325](https://github.com/cosmos/ethermint/pull/325) `eth_coinbase` JSON-RPC query now returns the node's validator address.
|
* (rpc) [tharsis#325](https://github.com/cosmos/ethermint/pull/325) `eth_coinbase` JSON-RPC query now returns the node's validator address.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* (build) [\#378](https://github.com/cosmos/ethermint/pull/378) Create multi-node, local, automated testnet setup with `make localnet-start`.
|
* (build) [tharsis#378](https://github.com/cosmos/ethermint/pull/378) Create multi-node, local, automated testnet setup with `make localnet-start`.
|
||||||
* (rpc) [\#330](https://github.com/cosmos/ethermint/issues/330) Implement `PublicFilterAPI`'s `EventSystem` which subscribes to Tendermint events upon `Filter` creation.
|
* (rpc) [tharsis#330](https://github.com/cosmos/ethermint/issues/330) Implement `PublicFilterAPI`'s `EventSystem` which subscribes to Tendermint events upon `Filter` creation.
|
||||||
* (rpc) [\#231](https://github.com/cosmos/ethermint/issues/231) Implement `NewBlockFilter` in rpc/filters.go which instantiates a polling block filter
|
* (rpc) [tharsis#231](https://github.com/cosmos/ethermint/issues/231) Implement `NewBlockFilter` in rpc/filters.go which instantiates a polling block filter
|
||||||
* Polls for new blocks via `BlockNumber` rpc call; if block number changes, it requests the new block via `GetBlockByNumber` rpc call and adds it to its internal list of blocks
|
* Polls for new blocks via `BlockNumber` rpc call; if block number changes, it requests the new block via `GetBlockByNumber` rpc call and adds it to its internal list of blocks
|
||||||
* Update `uninstallFilter` and `getFilterChanges` accordingly
|
* Update `uninstallFilter` and `getFilterChanges` accordingly
|
||||||
* `uninstallFilter` stops the polling goroutine
|
* `uninstallFilter` stops the polling goroutine
|
||||||
* `getFilterChanges` returns the filter's internal list of block hashes and resets it
|
* `getFilterChanges` returns the filter's internal list of block hashes and resets it
|
||||||
* (rpc) [\#54](https://github.com/cosmos/ethermint/issues/54), [\#55](https://github.com/cosmos/ethermint/issues/55)
|
* (rpc) [tharsis#54](https://github.com/cosmos/ethermint/issues/54), [tharsis#55](https://github.com/cosmos/ethermint/issues/55)
|
||||||
Implement `eth_getFilterLogs` and `eth_getLogs`:
|
Implement `eth_getFilterLogs` and `eth_getLogs`:
|
||||||
* For a given filter, look through each block for transactions. If there are transactions in the block, get the logs from it, and filter using the filterLogs method
|
* For a given filter, look through each block for transactions. If there are transactions in the block, get the logs from it, and filter using the filterLogs method
|
||||||
* `eth_getLogs` and `eth_getFilterChanges` for log filters use the same underlying method as `eth_getFilterLogs`
|
* `eth_getLogs` and `eth_getFilterChanges` for log filters use the same underlying method as `eth_getFilterLogs`
|
||||||
* update `HandleMsgEthereumTx` to store logs using the ethereum hash
|
* update `HandleMsgEthereumTx` to store logs using the ethereum hash
|
||||||
* (app) [\#187](https://github.com/cosmos/ethermint/issues/187) Add support for simulations.
|
* (app) [tharsis#187](https://github.com/cosmos/ethermint/issues/187) Add support for simulations.
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* (evm) [\#767](https://github.com/cosmos/ethermint/issues/767) Fix error of timeout when using Truffle to deploy contract.
|
* (evm) [tharsis#767](https://github.com/cosmos/ethermint/issues/767) Fix error of timeout when using Truffle to deploy contract.
|
||||||
* (evm) [\#751](https://github.com/cosmos/ethermint/issues/751) Fix misused method to calculate block hash in evm related function.
|
* (evm) [tharsis#751](https://github.com/cosmos/ethermint/issues/751) Fix misused method to calculate block hash in evm related function.
|
||||||
* (evm) [\#721](https://github.com/cosmos/ethermint/issues/721) Fix mismatch block hash in rpc response when use eth.getBlock.
|
* (evm) [tharsis#721](https://github.com/cosmos/ethermint/issues/721) Fix mismatch block hash in rpc response when use eth.getBlock.
|
||||||
* (evm) [\#730](https://github.com/cosmos/ethermint/issues/730) Fix 'EIP2028' not open when Istanbul version has been enabled.
|
* (evm) [tharsis#730](https://github.com/cosmos/ethermint/issues/730) Fix 'EIP2028' not open when Istanbul version has been enabled.
|
||||||
* (app) [\#749](https://github.com/cosmos/ethermint/issues/749) Fix panic in `AnteHandler` when gas price larger than 100000
|
* (app) [tharsis#749](https://github.com/cosmos/ethermint/issues/749) Fix panic in `AnteHandler` when gas price larger than 100000
|
||||||
* (rpc) [\#305](https://github.com/cosmos/ethermint/issues/305) Update `eth_getTransactionCount` to check for account existence before getting sequence and return 0 as the nonce if it doesn't exist.
|
* (rpc) [tharsis#305](https://github.com/cosmos/ethermint/issues/305) Update `eth_getTransactionCount` to check for account existence before getting sequence and return 0 as the nonce if it doesn't exist.
|
||||||
* (`x/evm`) [\#319](https://github.com/cosmos/ethermint/pull/319) Fix `SetBlockHash` that was setting the incorrect height during `BeginBlock`.
|
* (evm) [tharsis#319](https://github.com/cosmos/ethermint/pull/319) Fix `SetBlockHash` that was setting the incorrect height during `BeginBlock`.
|
||||||
* (`x/evm`) [\#176](https://github.com/cosmos/ethermint/issues/176) Updated Web3 transaction hash from using RLP hash. Now all transaction hashes exposed are amino hashes:
|
* (evm) [tharsis#176](https://github.com/cosmos/ethermint/issues/176) Updated Web3 transaction hash from using RLP hash. Now all transaction hashes exposed are amino hashes:
|
||||||
* Removes `Hash()` (RLP) function from `MsgEthereumTx` to avoid confusion or misuse in future.
|
* Removes `Hash()` (RLP) function from `MsgEthereumTx` to avoid confusion or misuse in future.
|
||||||
|
|||||||
@@ -106,16 +106,6 @@ items. In addition, use the following review explanations:
|
|||||||
- If you sat down with the PR submitter and did a pairing review, add this information in the `Approval` or your PR comments.
|
- If you sat down with the PR submitter and did a pairing review, add this information in the `Approval` or your PR comments.
|
||||||
- If you are only making "surface level" reviews, submit any notes as `Comments` without adding a review.
|
- If you are only making "surface level" reviews, submit any notes as `Comments` without adding a review.
|
||||||
|
|
||||||
### Updating Documentation
|
|
||||||
|
|
||||||
If you open a PR on Ethermint, it is mandatory to update the relevant documentation in `/docs`.
|
|
||||||
|
|
||||||
- If your change relates to the core SDK (baseapp, store, ...), be sure to update the content in `docs/basics/`, `docs/core/` and/or `docs/building-modules/` folders.
|
|
||||||
- If your changes relate to the core of the CLI (not specifically to module's CLI/Rest), then modify the content in the `docs/run-node/` folder.
|
|
||||||
- If your changes relate to a module, then be sure to update the module's spec in `x/moduleName/docs/spec/`.
|
|
||||||
|
|
||||||
When writing documentation, follow the [Documentation Writing Guidelines](./docs/DOC_WRITING_GUIDELINES.md).
|
|
||||||
|
|
||||||
## Forking
|
## Forking
|
||||||
|
|
||||||
Go requires code to live under absolute paths, and this requirement complicates forking.
|
Go requires code to live under absolute paths, and this requirement complicates forking.
|
||||||
|
|||||||
@@ -0,0 +1,351 @@
|
|||||||
|
# Vulcanize chiba-clonk gql
|
||||||
|
|
||||||
|
> Browser : http://localhost:9473 for gql
|
||||||
|
|
||||||
|
## Start server
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./build/chibaclonkd start --gql-playground --gql-server
|
||||||
|
```
|
||||||
|
|
||||||
|
Basic node status:
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
getStatus {
|
||||||
|
version
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
network
|
||||||
|
moniker
|
||||||
|
}
|
||||||
|
sync {
|
||||||
|
latest_block_height
|
||||||
|
catching_up
|
||||||
|
}
|
||||||
|
num_peers
|
||||||
|
peers {
|
||||||
|
is_outbound
|
||||||
|
remote_ip
|
||||||
|
}
|
||||||
|
disk_usage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Full node status:
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
getStatus {
|
||||||
|
version
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
network
|
||||||
|
moniker
|
||||||
|
}
|
||||||
|
sync {
|
||||||
|
latest_block_hash
|
||||||
|
latest_block_time
|
||||||
|
latest_block_height
|
||||||
|
catching_up
|
||||||
|
}
|
||||||
|
validator {
|
||||||
|
address
|
||||||
|
voting_power
|
||||||
|
proposer_priority
|
||||||
|
}
|
||||||
|
validators {
|
||||||
|
address
|
||||||
|
voting_power
|
||||||
|
proposer_priority
|
||||||
|
}
|
||||||
|
num_peers
|
||||||
|
peers {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
network
|
||||||
|
moniker
|
||||||
|
}
|
||||||
|
is_outbound
|
||||||
|
remote_ip
|
||||||
|
}
|
||||||
|
disk_usage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Get records by IDs.
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
getRecordsByIds(ids: ["QmYDtNCKtTu6u6jaHaFAC5PWZXcj7fAmry6NoWwMaixFHz"]) {
|
||||||
|
id
|
||||||
|
names
|
||||||
|
bondId
|
||||||
|
createTime
|
||||||
|
expiryTime
|
||||||
|
owners
|
||||||
|
attributes {
|
||||||
|
key
|
||||||
|
value {
|
||||||
|
string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Query records.
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
queryRecords(attributes: [{ key: "type", value: { string: "crn:bot" } }]) {
|
||||||
|
id
|
||||||
|
names
|
||||||
|
bondId
|
||||||
|
createTime
|
||||||
|
expiryTime
|
||||||
|
owners
|
||||||
|
attributes {
|
||||||
|
key
|
||||||
|
value {
|
||||||
|
string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Get account details:
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
getAccounts(addresses: ["cosmos1wh8vvd0ymc5nt37h29z8kk2g2ays45ct2qu094"]) {
|
||||||
|
address
|
||||||
|
pubKey
|
||||||
|
number
|
||||||
|
sequence
|
||||||
|
balance {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Query bonds:
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
queryBonds(
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
key: "owner"
|
||||||
|
value: { string: "cosmos1wh8vvd0ymc5nt37h29z8kk2g2ays45ct2qu094" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
owner
|
||||||
|
balance {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Get bonds by IDs.
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
getBondsByIds(ids :
|
||||||
|
[
|
||||||
|
"1c2b677cb2a27c88cc6bf8acf675c94b69051125b40c4fd073153b10f046dd87",
|
||||||
|
"c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440"
|
||||||
|
])
|
||||||
|
{
|
||||||
|
id
|
||||||
|
owner
|
||||||
|
balance{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Query Bonds by Owner
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
queryBondsByOwner(ownerAddresses: ["ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk"])
|
||||||
|
{
|
||||||
|
owner
|
||||||
|
bonds{
|
||||||
|
id
|
||||||
|
owner
|
||||||
|
balance
|
||||||
|
{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Query auctions by ids
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
getAuctionsByIds(ids: ["be98f2073c246194276554eefdb4c95b682a35a0f06fbe619a6da57c10c93e90"]){
|
||||||
|
id
|
||||||
|
ownerAddress
|
||||||
|
createTime
|
||||||
|
minimumBid{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
commitFee{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
commitsEndTime
|
||||||
|
revealFee{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
revealsEndTime
|
||||||
|
winnerBid{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
winnerPrice{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
winnerAddress
|
||||||
|
bids{
|
||||||
|
bidderAddress
|
||||||
|
commitHash
|
||||||
|
commitTime
|
||||||
|
commitFee{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
revealFee{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
revealTime
|
||||||
|
bidAmount{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
LookUp Authorities
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
lookupAuthorities(names: []){
|
||||||
|
ownerAddress
|
||||||
|
ownerAddress
|
||||||
|
height
|
||||||
|
bondId
|
||||||
|
status
|
||||||
|
expiryTime
|
||||||
|
auction {
|
||||||
|
id
|
||||||
|
ownerAddress
|
||||||
|
createTime
|
||||||
|
minimumBid{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
commitFee{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
commitsEndTime
|
||||||
|
revealFee{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
revealsEndTime
|
||||||
|
winnerBid{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
winnerPrice{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
winnerAddress
|
||||||
|
bids{
|
||||||
|
bidderAddress
|
||||||
|
commitHash
|
||||||
|
commitTime
|
||||||
|
commitFee{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
revealFee{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
revealTime
|
||||||
|
bidAmount{
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
LookUp Names
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
lookupNames(names: ["crn://hello/test"]){
|
||||||
|
latest{
|
||||||
|
id
|
||||||
|
height
|
||||||
|
}
|
||||||
|
history{
|
||||||
|
id
|
||||||
|
height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Resolve Names
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
resolveNames(names: ["asd"]){
|
||||||
|
id
|
||||||
|
names
|
||||||
|
bondId
|
||||||
|
createTime
|
||||||
|
expiryTime
|
||||||
|
owners
|
||||||
|
attributes {
|
||||||
|
key
|
||||||
|
value {
|
||||||
|
string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
+5
-5
@@ -4,7 +4,7 @@ FROM golang:alpine AS build-env
|
|||||||
ENV PACKAGES git build-base
|
ENV PACKAGES git build-base
|
||||||
|
|
||||||
# Set working directory for the build
|
# Set working directory for the build
|
||||||
WORKDIR /go/src/github.com/tharsis/ethermint
|
WORKDIR /go/src/github.com/vulcanize/chiba-clonk
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
RUN apk add --update $PACKAGES
|
RUN apk add --update $PACKAGES
|
||||||
@@ -17,14 +17,14 @@ COPY . .
|
|||||||
RUN make build
|
RUN make build
|
||||||
|
|
||||||
# Final image
|
# Final image
|
||||||
FROM alpine
|
FROM alpine:3.15
|
||||||
|
|
||||||
# Install ca-certificates
|
# Install ca-certificates
|
||||||
RUN apk add --update ca-certificates jq
|
RUN apk add --update ca-certificates jq
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
|
|
||||||
# Copy over binaries from the build-env
|
# Copy over binaries from the build-env
|
||||||
COPY --from=build-env /go/src/github.com/tharsis/ethermint/build/ethermintd /usr/bin/ethermintd
|
COPY --from=build-env /go/src/github.com/vulcanize/chiba-clonk/build/chibaclonkd /usr/bin/chibaclonkd
|
||||||
|
|
||||||
# Run ethermintd by default
|
# Run chibaclonkd by default
|
||||||
CMD ["ethermintd"]
|
CMD ["chibaclonkd"]
|
||||||
|
|||||||
@@ -1,201 +1,165 @@
|
|||||||
Apache License
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
Version 2.0, January 2004
|
Version 3, 29 June 2007
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
This version of the GNU Lesser General Public License incorporates
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
0. Additional Definitions.
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
other entities that control, are controlled by, or are under common
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
control with that entity. For the purposes of this definition,
|
General Public License.
|
||||||
"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
|
"The Library" refers to a covered work governed by this License,
|
||||||
exercising permissions granted by this License.
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
An "Application" is any work that makes use of an interface provided
|
||||||
including but not limited to software source code, documentation
|
by the Library, but which is not otherwise based on the Library.
|
||||||
source, and configuration files.
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
transformation or translation of a Source form, including but
|
Application with the Library. The particular version of the Library
|
||||||
not limited to compiled object code, generated documentation,
|
with which the Combined Work was made is also called the "Linked
|
||||||
and conversions to other media types.
|
Version".
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
Object form, made available under the License, as indicated by a
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
copyright notice that is included in or attached to the work
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
(an example is provided in the Appendix below).
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
form, that is based on (or derived from) the Work and for which the
|
object code and/or source code for the Application, including any data
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
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
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
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
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
without being bound by section 3 of the GNU GPL.
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
2. Conveying Modified Versions.
|
||||||
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
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
facility refers to a function or data to be supplied by an Application
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
that uses the facility (other than as an argument passed when the
|
||||||
(except as stated in this section) patent license to make, have made,
|
facility is invoked), then you may convey a copy of the modified
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
version:
|
||||||
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
|
a) under this License, provided that you make a good faith effort to
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
ensure that, in the event an Application does not supply the
|
||||||
modifications, and in Source or Object form, provided that You
|
function or data, the facility still operates, and performs
|
||||||
meet the following conditions:
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
Derivative Works a copy of this License; and
|
this License applicable to that copy.
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
The object code form of an Application may incorporate material from
|
||||||
that You distribute, all copyright, patent, trademark, and
|
a header file that is part of the Library. You may convey such object
|
||||||
attribution notices from the Source form of the Work,
|
code under terms of your choice, provided that, if the incorporated
|
||||||
excluding those notices that do not pertain to any part of
|
material is not limited to numerical parameters, data structure
|
||||||
the Derivative Works; and
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
a) Give prominent notice with each copy of the object code that the
|
||||||
distribution, then any Derivative Works that You distribute must
|
Library is used in it and that the Library and its use are
|
||||||
include a readable copy of the attribution notices contained
|
covered by this License.
|
||||||
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
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
may provide additional or different license terms and conditions
|
document.
|
||||||
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,
|
4. Combined Works.
|
||||||
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
|
You may convey a Combined Work under terms of your choice that,
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
taken together, effectively do not restrict modification of the
|
||||||
except as required for reasonable and customary use in describing the
|
portions of the Library contained in the Combined Work and reverse
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
the Library is used in it and that the Library and its use are
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
covered by this License.
|
||||||
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,
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
document.
|
||||||
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
|
c) For a Combined Work that displays copyright notices during
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
execution, include the copyright notice for the Library among
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
these notices, as well as a reference directing the user to the
|
||||||
or other liability obligations and/or rights consistent with this
|
copies of the GNU GPL and this license document.
|
||||||
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
|
d) Do one of the following:
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
replaced with your own identifying information. (Don't include
|
a copy of the Library already present on the user's computer
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
system, and (b) will operate properly with a modified version
|
||||||
comment syntax for the file format. We also recommend that a
|
of the Library that is interface-compatible with the Linked
|
||||||
file or class name and description of purpose be included on the
|
Version.
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
5. Combined Libraries.
|
||||||
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
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
a) Accompany the combined library with a copy of the same work based
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
on the Library, uncombined with any other library facilities,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
conveyed under the terms of this License.
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ TMVERSION := $(shell go list -m github.com/tendermint/tendermint | sed 's:.* ::'
|
|||||||
COMMIT := $(shell git log -1 --format='%H')
|
COMMIT := $(shell git log -1 --format='%H')
|
||||||
LEDGER_ENABLED ?= true
|
LEDGER_ENABLED ?= true
|
||||||
BINDIR ?= $(GOPATH)/bin
|
BINDIR ?= $(GOPATH)/bin
|
||||||
ETHERMINT_BINARY = ethermintd
|
CHIBACLONK_BINARY = chibaclonkd
|
||||||
ETHERMINT_DIR = ethermint
|
CHIBACLONK_DIR = chibaclonk
|
||||||
BUILDDIR ?= $(CURDIR)/build
|
BUILDDIR ?= $(CURDIR)/build
|
||||||
SIMAPP = ./app
|
SIMAPP = ./app
|
||||||
HTTPS_GIT := https://github.com/tharsis/ethermint.git
|
HTTPS_GIT := https://github.com/vulcanize/chiba-clonk.git
|
||||||
DOCKER := $(shell which docker)
|
DOCKER := $(shell which docker)
|
||||||
DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf
|
DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf
|
||||||
|
PROJECT_NAME = $(shell git remote get-url origin | xargs basename -s .git)
|
||||||
|
|
||||||
export GO111MODULE = on
|
export GO111MODULE = on
|
||||||
|
|
||||||
@@ -61,8 +62,8 @@ build_tags_comma_sep := $(subst $(whitespace),$(comma),$(build_tags))
|
|||||||
|
|
||||||
# process linker flags
|
# process linker flags
|
||||||
|
|
||||||
ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=ethermint \
|
ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=chibaclonk \
|
||||||
-X github.com/cosmos/cosmos-sdk/version.AppName=$(ETHERMINT_BINARY) \
|
-X github.com/cosmos/cosmos-sdk/version.AppName=$(CHIBACLONK_BINARY) \
|
||||||
-X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
|
-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.Commit=$(COMMIT) \
|
||||||
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \
|
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \
|
||||||
@@ -72,8 +73,10 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=ethermint \
|
|||||||
ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS)))
|
ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS)))
|
||||||
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
|
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (badgerdb,$(findstring badgerdb,$(COSMOS_BUILD_OPTIONS)))
|
ifeq (badgerdb,$(findstring badgerdb,$(COSMOS_BUILD_OPTIONS)))
|
||||||
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=badgerdb
|
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=badgerdb
|
||||||
|
BUILD_TAGS += badgerdb
|
||||||
endif
|
endif
|
||||||
# handle rocksdb
|
# handle rocksdb
|
||||||
ifeq (rocksdb,$(findstring rocksdb,$(COSMOS_BUILD_OPTIONS)))
|
ifeq (rocksdb,$(findstring rocksdb,$(COSMOS_BUILD_OPTIONS)))
|
||||||
@@ -87,18 +90,27 @@ ifeq (boltdb,$(findstring boltdb,$(COSMOS_BUILD_OPTIONS)))
|
|||||||
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=boltdb
|
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=boltdb
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS)))
|
|
||||||
ldflags += -w -s
|
|
||||||
endif
|
|
||||||
ldflags += $(LDFLAGS)
|
ldflags += $(LDFLAGS)
|
||||||
ldflags := $(strip $(ldflags))
|
ldflags := $(strip $(ldflags))
|
||||||
|
|
||||||
|
build_tags += $(BUILD_TAGS)
|
||||||
|
build_tags := $(strip $(build_tags))
|
||||||
|
|
||||||
BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags)'
|
BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags)'
|
||||||
|
|
||||||
|
# Check for debug option
|
||||||
|
ifeq (debug,$(findstring debug,$(COSMOS_BUILD_OPTIONS)))
|
||||||
|
BUILD_FLAGS += -gcflags 'all=-N -l'
|
||||||
|
COSMOS_BUILD_OPTIONS += nostrip
|
||||||
|
endif
|
||||||
|
|
||||||
# check for nostrip option
|
# check for nostrip option
|
||||||
ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS)))
|
ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS)))
|
||||||
BUILD_FLAGS += -trimpath
|
BUILD_FLAGS += -trimpath
|
||||||
|
ldflags += -w -s
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
all: tools build lint test
|
||||||
# # The below include contains the tools and runsim targets.
|
# # The below include contains the tools and runsim targets.
|
||||||
# include contrib/devtools/Makefile
|
# include contrib/devtools/Makefile
|
||||||
|
|
||||||
@@ -110,14 +122,16 @@ BUILD_TARGETS := build install
|
|||||||
|
|
||||||
build: BUILD_ARGS=-o $(BUILDDIR)/
|
build: BUILD_ARGS=-o $(BUILDDIR)/
|
||||||
build-linux:
|
build-linux:
|
||||||
GOOS=linux GOARCH=amd64 LEDGER_ENABLED=false $(MAKE) build
|
GOOS=linux GOARCH=$(if $(findstring aarch64,$(shell uname -m)) || $(findstring arm64,$(shell uname -m)),arm64,amd64) LEDGER_ENABLED=false $(MAKE) build
|
||||||
|
|
||||||
$(BUILD_TARGETS): go.sum $(BUILDDIR)/
|
$(BUILD_TARGETS): go.sum $(BUILDDIR)/
|
||||||
go $@ $(BUILD_FLAGS) $(BUILD_ARGS) ./...
|
go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) ./...
|
||||||
|
|
||||||
$(BUILDDIR)/:
|
$(BUILDDIR)/:
|
||||||
mkdir -p $(BUILDDIR)/
|
mkdir -p $(BUILDDIR)/
|
||||||
|
|
||||||
|
.PHONY: build build-linux cosmovisor
|
||||||
|
|
||||||
docker-build:
|
docker-build:
|
||||||
# TODO replace with kaniko
|
# TODO replace with kaniko
|
||||||
docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .
|
docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .
|
||||||
@@ -148,6 +162,43 @@ build-all: tools build lint test
|
|||||||
|
|
||||||
.PHONY: distclean clean build-all
|
.PHONY: distclean clean build-all
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### Releasing ###
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
PACKAGE_NAME:=github.com/tharsis/ethermint
|
||||||
|
GOLANG_CROSS_VERSION = v1.17.1
|
||||||
|
GOPATH ?= '$(HOME)/go'
|
||||||
|
release-dry-run:
|
||||||
|
docker run \
|
||||||
|
--rm \
|
||||||
|
--privileged \
|
||||||
|
-e CGO_ENABLED=1 \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
|
-v `pwd`:/go/src/$(PACKAGE_NAME) \
|
||||||
|
-v ${GOPATH}/pkg:/go/pkg \
|
||||||
|
-w /go/src/$(PACKAGE_NAME) \
|
||||||
|
ghcr.io/troian/golang-cross:${GOLANG_CROSS_VERSION} \
|
||||||
|
--rm-dist --skip-validate --skip-publish
|
||||||
|
|
||||||
|
release:
|
||||||
|
@if [ ! -f ".release-env" ]; then \
|
||||||
|
echo "\033[91m.release-env is required for release\033[0m";\
|
||||||
|
exit 1;\
|
||||||
|
fi
|
||||||
|
docker run \
|
||||||
|
--rm \
|
||||||
|
--privileged \
|
||||||
|
-e CGO_ENABLED=1 \
|
||||||
|
--env-file .release-env \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
|
-v `pwd`:/go/src/$(PACKAGE_NAME) \
|
||||||
|
-w /go/src/$(PACKAGE_NAME) \
|
||||||
|
ghcr.io/troian/golang-cross:${GOLANG_CROSS_VERSION} \
|
||||||
|
release --rm-dist --skip-validate
|
||||||
|
|
||||||
|
.PHONY: release-dry-run release
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
### Tools & Dependencies ###
|
### Tools & Dependencies ###
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -215,16 +266,8 @@ else
|
|||||||
@echo "solcjs already installed; skipping..."
|
@echo "solcjs already installed; skipping..."
|
||||||
endif
|
endif
|
||||||
|
|
||||||
docs-tools:
|
|
||||||
ifeq (, $(shell which yarn))
|
|
||||||
@echo "Installing yarn..."
|
|
||||||
@npm install -g yarn
|
|
||||||
else
|
|
||||||
@echo "yarn already installed; skipping..."
|
|
||||||
endif
|
|
||||||
|
|
||||||
tools: tools-stamp
|
tools: tools-stamp
|
||||||
tools-stamp: contract-tools docs-tools proto-tools statik runsim
|
tools-stamp: contract-tools proto-tools statik runsim
|
||||||
# Create dummy file to satisfy dependency and avoid
|
# Create dummy file to satisfy dependency and avoid
|
||||||
# rebuilding when this Makefile target is hit twice
|
# rebuilding when this Makefile target is hit twice
|
||||||
# in a row.
|
# in a row.
|
||||||
@@ -234,13 +277,7 @@ tools-clean:
|
|||||||
rm -f $(RUNSIM)
|
rm -f $(RUNSIM)
|
||||||
rm -f tools-stamp
|
rm -f tools-stamp
|
||||||
|
|
||||||
docs-tools-stamp: docs-tools
|
.PHONY: runsim statik tools contract-tools proto-tools tools-stamp tools-clean
|
||||||
# Create dummy file to satisfy dependency and avoid
|
|
||||||
# rebuilding when this Makefile target is hit twice
|
|
||||||
# in a row.
|
|
||||||
touch $@
|
|
||||||
|
|
||||||
.PHONY: runsim statik tools contract-tools docs-tools proto-tools tools-stamp tools-clean docs-tools-stamp
|
|
||||||
|
|
||||||
go.sum: go.mod
|
go.sum: go.mod
|
||||||
echo "Ensure dependencies have not been modified ..." >&2
|
echo "Ensure dependencies have not been modified ..." >&2
|
||||||
@@ -265,41 +302,13 @@ godocs:
|
|||||||
@echo "--> Wait a few seconds and visit http://localhost:6060/pkg/github.com/tharsis/ethermint/types"
|
@echo "--> Wait a few seconds and visit http://localhost:6060/pkg/github.com/tharsis/ethermint/types"
|
||||||
godoc -http=:6060
|
godoc -http=:6060
|
||||||
|
|
||||||
# Start docs site at localhost:8080
|
|
||||||
docs-serve:
|
|
||||||
@cd docs && \
|
|
||||||
yarn && \
|
|
||||||
yarn run serve
|
|
||||||
|
|
||||||
# Build the site into docs/.vuepress/dist
|
|
||||||
build-docs:
|
|
||||||
@$(MAKE) docs-tools-stamp && \
|
|
||||||
cd docs && \
|
|
||||||
yarn && \
|
|
||||||
yarn run build
|
|
||||||
|
|
||||||
# This builds a docs site for each branch/tag in `./docs/versions`
|
|
||||||
# and copies each site to a version prefixed path. The last entry inside
|
|
||||||
# the `versions` file will be the default root index.html.
|
|
||||||
build-docs-versioned:
|
|
||||||
@$(MAKE) docs-tools-stamp && \
|
|
||||||
cd docs && \
|
|
||||||
while read -r branch path_prefix; do \
|
|
||||||
(git checkout $${branch} && npm install && VUEPRESS_BASE="/$${path_prefix}/" npm run build) ; \
|
|
||||||
mkdir -p ~/output/$${path_prefix} ; \
|
|
||||||
cp -r .vuepress/dist/* ~/output/$${path_prefix}/ ; \
|
|
||||||
cp ~/output/$${path_prefix}/index.html ~/output ; \
|
|
||||||
done < versions ;
|
|
||||||
|
|
||||||
.PHONY: docs-serve build-docs build-docs-versioned
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
### Tests & Simulation ###
|
### Tests & Simulation ###
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
test: test-unit
|
test: test-unit
|
||||||
test-all: test-unit test-race
|
test-all: test-unit test-race
|
||||||
PACKAGES_UNIT=$(shell go list ./...)
|
PACKAGES_UNIT=$(shell go list ./... | grep -Ev 'vendor|importer')
|
||||||
TEST_PACKAGES=./...
|
TEST_PACKAGES=./...
|
||||||
TEST_TARGETS := test-unit test-unit-cover test-race
|
TEST_TARGETS := test-unit test-unit-cover test-race
|
||||||
|
|
||||||
@@ -324,22 +333,17 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
test-import:
|
test-import:
|
||||||
@go test ./tests/importer -v --vet=off --run=TestImportBlocks --datadir tmp \
|
go test -run TestImporterTestSuite -v --vet=off github.com/tharsis/ethermint/tests/importer
|
||||||
--blockchain blockchain
|
|
||||||
rm -rf tests/importer/tmp
|
|
||||||
|
|
||||||
test-rpc:
|
test-rpc:
|
||||||
./scripts/integration-test-all.sh -t "rpc" -q 1 -z 1 -s 2 -m "rpc" -r "true"
|
./scripts/integration-test-all.sh -t "rpc" -q 1 -z 1 -s 2 -m "rpc" -r "true"
|
||||||
|
|
||||||
|
test-integration:
|
||||||
|
./scripts/integration-test-all.sh -t "integration" -q 1 -z 1 -s 2 -m "integration" -r "true"
|
||||||
|
|
||||||
test-rpc-pending:
|
test-rpc-pending:
|
||||||
./scripts/integration-test-all.sh -t "pending" -q 1 -z 1 -s 2 -m "pending" -r "true"
|
./scripts/integration-test-all.sh -t "pending" -q 1 -z 1 -s 2 -m "pending" -r "true"
|
||||||
|
|
||||||
test-contract:
|
|
||||||
@type "npm" 2> /dev/null || (echo 'Npm does not exist. Please install node.js and npm."' && exit 1)
|
|
||||||
@type "solcjs" 2> /dev/null || (echo 'Solcjs does not exist. Please install solcjs using make contract-tools."' && exit 1)
|
|
||||||
@type "protoc" 2> /dev/null || (echo 'Failed to install protoc. Please reinstall protoc using make contract-tools.' && exit 1)
|
|
||||||
bash scripts/contract-test.sh
|
|
||||||
|
|
||||||
test-solidity:
|
test-solidity:
|
||||||
@echo "Beginning solidity tests..."
|
@echo "Beginning solidity tests..."
|
||||||
./scripts/run-solidity-tests.sh
|
./scripts/run-solidity-tests.sh
|
||||||
@@ -354,8 +358,8 @@ test-sim-nondeterminism:
|
|||||||
|
|
||||||
test-sim-custom-genesis-fast:
|
test-sim-custom-genesis-fast:
|
||||||
@echo "Running custom genesis simulation..."
|
@echo "Running custom genesis simulation..."
|
||||||
@echo "By default, ${HOME}/.$(ETHERMINT_DIR)/config/genesis.json will be used."
|
@echo "By default, ${HOME}/.$(CHIBACLONK_DIR)/config/genesis.json will be used."
|
||||||
@go test -mod=readonly $(SIMAPP) -run TestFullAppSimulation -Genesis=${HOME}/.$(ETHERMINT_DIR)/config/genesis.json \
|
@go test -mod=readonly $(SIMAPP) -run TestFullAppSimulation -Genesis=${HOME}/.$(CHIBACLONK_DIR)/config/genesis.json \
|
||||||
-Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h
|
-Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h
|
||||||
|
|
||||||
test-sim-import-export: runsim
|
test-sim-import-export: runsim
|
||||||
@@ -368,8 +372,8 @@ test-sim-after-import: runsim
|
|||||||
|
|
||||||
test-sim-custom-genesis-multi-seed: runsim
|
test-sim-custom-genesis-multi-seed: runsim
|
||||||
@echo "Running multi-seed custom genesis simulation..."
|
@echo "Running multi-seed custom genesis simulation..."
|
||||||
@echo "By default, ${HOME}/.$(ETHERMINT_DIR)/config/genesis.json will be used."
|
@echo "By default, ${HOME}/.$(CHIBACLONK_DIR)/config/genesis.json will be used."
|
||||||
@$(BINDIR)/runsim -Genesis=${HOME}/.$(ETHERMINT_DIR)/config/genesis.json -SimAppPkg=$(SIMAPP) -ExitOnFail 400 5 TestFullAppSimulation
|
@$(BINDIR)/runsim -Genesis=${HOME}/.$(CHIBACLONK_DIR)/config/genesis.json -SimAppPkg=$(SIMAPP) -ExitOnFail 400 5 TestFullAppSimulation
|
||||||
|
|
||||||
test-sim-multi-seed-long: runsim
|
test-sim-multi-seed-long: runsim
|
||||||
@echo "Running long multi-seed application simulation. This may take awhile!"
|
@echo "Running long multi-seed application simulation. This may take awhile!"
|
||||||
@@ -424,23 +428,26 @@ format-fix:
|
|||||||
|
|
||||||
containerProtoVer=v0.2
|
containerProtoVer=v0.2
|
||||||
containerProtoImage=tendermintdev/sdk-proto-gen:$(containerProtoVer)
|
containerProtoImage=tendermintdev/sdk-proto-gen:$(containerProtoVer)
|
||||||
containerProtoGen=cosmos-sdk-proto-gen-$(containerProtoVer)
|
containerProtoGen=$(PROJECT_NAME)-proto-gen-$(containerProtoVer)
|
||||||
containerProtoGenSwagger=cosmos-sdk-proto-gen-swagger-$(containerProtoVer)
|
containerProtoGenSwagger=$(PROJECT_NAME)-proto-gen-swagger-$(containerProtoVer)
|
||||||
containerProtoFmt=cosmos-sdk-proto-fmt-$(containerProtoVer)
|
containerProtoFmt=$(PROJECT_NAME)-proto-fmt-$(containerProtoVer)
|
||||||
|
|
||||||
proto-all: proto-format proto-lint proto-gen
|
proto-all: proto-format proto-lint proto-gen
|
||||||
|
|
||||||
proto-gen:
|
proto-gen:
|
||||||
@echo "Generating Protobuf files"
|
@echo "Generating Protobuf files"
|
||||||
$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen sh ./scripts/protocgen.sh
|
@if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGen}$$"; then docker start -a $(containerProtoGen); else docker run --name $(containerProtoGen) -v $(CURDIR):/workspace --workdir /workspace $(containerProtoImage) \
|
||||||
|
sh ./scripts/protocgen.sh; fi
|
||||||
|
|
||||||
proto-swagger-gen:
|
proto-swagger-gen:
|
||||||
@echo "Generating Protobuf Swagger"
|
@echo "Generating Protobuf Swagger"
|
||||||
|
@./scripts/proto-tools-installer.sh
|
||||||
@./scripts/protoc-swagger-gen.sh
|
@./scripts/protoc-swagger-gen.sh
|
||||||
|
|
||||||
proto-format:
|
proto-format:
|
||||||
@echo "Formatting Protobuf files"
|
@echo "Formatting Protobuf files"
|
||||||
find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {} \;
|
@if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \
|
||||||
|
find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi
|
||||||
|
|
||||||
proto-lint:
|
proto-lint:
|
||||||
@$(DOCKER_BUF) lint --error-format=json
|
@$(DOCKER_BUF) lint --error-format=json
|
||||||
@@ -501,19 +508,19 @@ ifeq ($(OS),Windows_NT)
|
|||||||
mkdir localnet-setup &
|
mkdir localnet-setup &
|
||||||
@$(MAKE) localnet-build
|
@$(MAKE) localnet-build
|
||||||
|
|
||||||
IF not exist "build/node0/$(ETHERMINT_BINARY)/config/genesis.json" docker run --rm -v $(CURDIR)/build\ethermint\Z ethermintd/node "./ethermintd testnet --v 4 -o /ethermint --keyring-backend=test --ip-addresses ethermintdnode0,ethermintdnode1,ethermintdnode2,ethermintdnode3"
|
IF not exist "build/node0/$(CHIBACLONK_BINARY)/config/genesis.json" docker run --rm -v $(CURDIR)/build\ethermint\Z chibaclonkd/node sh -c "chibaclonkd testnet init-files --v 4 --keyring-backend=test"
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
else
|
else
|
||||||
mkdir -p localnet-setup
|
mkdir -p localnet-setup
|
||||||
@$(MAKE) localnet-build
|
@$(MAKE) localnet-build
|
||||||
|
|
||||||
if ! [ -f localnet-setup/node0/$(ETHERMINT_BINARY)/config/genesis.json ]; then docker run --rm -v $(CURDIR)/localnet-setup:/ethermint:Z ethermintd/node "./ethermintd testnet --v 4 -o /ethermint --keyring-backend=test --ip-addresses ethermintdnode0,ethermintdnode1,ethermintdnode2,ethermintdnode3"; fi
|
if ! [ -f localnet-setup/node0/$(CHIBACLONK_BINARY)/config/genesis.json ]; then docker run --rm -v $(CURDIR)/localnet-setup:/localnet-setup:Z chibaclonkd/node sh -c "chibaclonkd testnet init-files --v 4 --keyring-backend=test"; fi
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Stop testnet
|
# Stop testnet
|
||||||
localnet-stop:
|
localnet-stop:
|
||||||
docker-compose down
|
docker-compose down -v
|
||||||
|
|
||||||
# Clean testnet
|
# Clean testnet
|
||||||
localnet-clean:
|
localnet-clean:
|
||||||
@@ -524,15 +531,15 @@ localnet-clean:
|
|||||||
localnet-unsafe-reset:
|
localnet-unsafe-reset:
|
||||||
docker-compose down
|
docker-compose down
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
@docker run --rm -v $(CURDIR)\localnet-setup\node0\ethermitd:ethermint\Z ethermintd/node "./ethermintd unsafe-reset-all --home=/ethermint"
|
@docker run --rm -v $(CURDIR)\localnet-setup\node0\chibaclonkd:chibaclonk\Z chibaclonkd/node "chibaclonkd unsafe-reset-all --home=/chibaclonk"
|
||||||
@docker run --rm -v $(CURDIR)\localnet-setup\node1\ethermitd:ethermint\Z ethermintd/node "./ethermintd unsafe-reset-all --home=/ethermint"
|
@docker run --rm -v $(CURDIR)\localnet-setup\node1\chibaclonkd:chibaclonk\Z chibaclonkd/node "chibaclonkd unsafe-reset-all --home=/chibaclonk"
|
||||||
@docker run --rm -v $(CURDIR)\localnet-setup\node2\ethermitd:ethermint\Z ethermintd/node "./ethermintd unsafe-reset-all --home=/ethermint"
|
@docker run --rm -v $(CURDIR)\localnet-setup\node2\chibaclonkd:chibaclonk\Z chibaclonkd/node "chibaclonkd unsafe-reset-all --home=/chibaclonk"
|
||||||
@docker run --rm -v $(CURDIR)\localnet-setup\node3\ethermitd:ethermint\Z ethermintd/node "./ethermintd unsafe-reset-all --home=/ethermint"
|
@docker run --rm -v $(CURDIR)\localnet-setup\node3\chibaclonkd:chibaclonk\Z chibaclonkd/node "chibaclonkd unsafe-reset-all --home=/chibaclonk"
|
||||||
else
|
else
|
||||||
@docker run --rm -v $(CURDIR)/localnet-setup/node0/ethermitd:/ethermint:Z ethermintd/node "./ethermintd unsafe-reset-all --home=/ethermint"
|
@docker run --rm -v $(CURDIR)/localnet-setup/node0/chibaclonkd:/chibaclonk:Z chibaclonkd/node "chibaclonkd unsafe-reset-all --home=/chibaclonk"
|
||||||
@docker run --rm -v $(CURDIR)/localnet-setup/node1/ethermitd:/ethermint:Z ethermintd/node "./ethermintd unsafe-reset-all --home=/ethermint"
|
@docker run --rm -v $(CURDIR)/localnet-setup/node1/chibaclonkd:/chibaclonk:Z chibaclonkd/node "chibaclonkd unsafe-reset-all --home=/chibaclonk"
|
||||||
@docker run --rm -v $(CURDIR)/localnet-setup/node2/ethermitd:/ethermint:Z ethermintd/node "./ethermintd unsafe-reset-all --home=/ethermint"
|
@docker run --rm -v $(CURDIR)/localnet-setup/node2/chibaclonkd:/chibaclonk:Z chibaclonkd/node "chibaclonkd unsafe-reset-all --home=/chibaclonk"
|
||||||
@docker run --rm -v $(CURDIR)/localnet-setup/node3/ethermitd:/ethermint:Z ethermintd/node "./ethermintd unsafe-reset-all --home=/ethermint"
|
@docker run --rm -v $(CURDIR)/localnet-setup/node3/chibaclonkd:/chibaclonk:Z chibaclonkd/node "chibaclonkd unsafe-reset-all --home=/chibaclonk"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Clean testnet
|
# Clean testnet
|
||||||
@@ -540,39 +547,3 @@ localnet-show-logstream:
|
|||||||
docker-compose logs --tail=1000 -f
|
docker-compose logs --tail=1000 -f
|
||||||
|
|
||||||
.PHONY: build-docker-local-ethermint localnet-start localnet-stop
|
.PHONY: build-docker-local-ethermint localnet-start localnet-stop
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
### Releasing ###
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
PACKAGE_NAME:=github.com/tharsis/ethermint
|
|
||||||
GOLANG_CROSS_VERSION = v1.17
|
|
||||||
release-dry-run:
|
|
||||||
docker run \
|
|
||||||
--rm \
|
|
||||||
--privileged \
|
|
||||||
-e CGO_ENABLED=1 \
|
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
-v `pwd`:/go/src/$(PACKAGE_NAME) \
|
|
||||||
-v ${GOPATH}/pkg:/go/pkg \
|
|
||||||
-w /go/src/$(PACKAGE_NAME) \
|
|
||||||
troian/golang-cross:${GOLANG_CROSS_VERSION} \
|
|
||||||
--rm-dist --skip-validate --skip-publish
|
|
||||||
|
|
||||||
release:
|
|
||||||
@if [ ! -f ".release-env" ]; then \
|
|
||||||
echo "\033[91m.release-env is required for release\033[0m";\
|
|
||||||
exit 1;\
|
|
||||||
fi
|
|
||||||
docker run \
|
|
||||||
--rm \
|
|
||||||
--privileged \
|
|
||||||
-e CGO_ENABLED=1 \
|
|
||||||
--env-file .release-env \
|
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
-v `pwd`:/go/src/$(PACKAGE_NAME) \
|
|
||||||
-w /go/src/$(PACKAGE_NAME) \
|
|
||||||
troian/golang-cross:${GOLANG_CROSS_VERSION} \
|
|
||||||
release --rm-dist --skip-validate
|
|
||||||
|
|
||||||
.PHONY: release-dry-run release
|
|
||||||
|
|||||||
@@ -30,28 +30,21 @@ parent:
|
|||||||
<a href="https://discord.gg/trje9XuAmy">
|
<a href="https://discord.gg/trje9XuAmy">
|
||||||
<img alt="Discord" src="https://img.shields.io/discord/809048090249134080.svg" />
|
<img alt="Discord" src="https://img.shields.io/discord/809048090249134080.svg" />
|
||||||
</a>
|
</a>
|
||||||
<!-- <a href="https://github.com/tharsis/ethermint/actions?query=branch%3Amain+workflow%3ABuild">
|
|
||||||
<img alt="Build Status" src="https://github.com/tharsis/ethermint/actions/workflows/build.yml/badge.svg?branch=main" />
|
|
||||||
</a> -->
|
|
||||||
<a href="https://github.com/tharsis/ethermint/actions?query=branch%3Amain+workflow%3ALint">
|
<a href="https://github.com/tharsis/ethermint/actions?query=branch%3Amain+workflow%3ALint">
|
||||||
<img alt="Lint Status" src="https://github.com/tharsis/ethermint/actions/workflows/lint.yml/badge.svg?branch=main" />
|
<img alt="Lint Status" src="https://github.com/tharsis/ethermint/actions/workflows/lint.yml/badge.svg?branch=main" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://codecov.io/gh/tharsis/ethermint">
|
<a href="https://codecov.io/gh/tharsis/ethermint">
|
||||||
<img alt="Code Coverage" src="https://codecov.io/gh/tharsis/ethermint/branch/main/graph/badge.svg" />
|
<img alt="Code Coverage" src="https://codecov.io/gh/tharsis/ethermint/branch/main/graph/badge.svg" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://twitter.com/ethermint">
|
|
||||||
<img alt="Twitter Follow Ethermint" src="https://img.shields.io/twitter/follow/ethermint"/>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Ethermint is a scalable, high-throughput Proof-of-Stake blockchain that is fully compatible and
|
Ethermint is a scalable and interoperable Ethereum library, built on Proof-of-Stake with fast-finality using the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/) which runs on top of [Tendermint Core](https://github.com/tendermint/tendermint) consensus engine.
|
||||||
interoperable with Ethereum. It's build using the the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/) which runs on top of [Tendermint Core](https://github.com/tendermint/tendermint) consensus engine.
|
|
||||||
|
|
||||||
**Note**: Requires [Go 1.17+](https://golang.org/dl/)
|
**Note**: Requires [Go 1.17+](https://golang.org/dl/)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
For prerequisites and detailed build instructions please read the [Installation](https://ethermint.dev/quickstart/installation.html) instructions. Once the dependencies are installed, run:
|
For prerequisites and detailed build instructions please read the Evmos [Installation](https://evmos.dev/quickstart/installation.html) instructions. Once the dependencies are installed, run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make install
|
make install
|
||||||
@@ -61,18 +54,18 @@ Or check out the latest [release](https://github.com/tharsis/ethermint/releases)
|
|||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
To learn how the Ethermint works from a high-level perspective, go to the [Introduction](https://ethermint.dev/intro/overview.html) section from the documentation. You can also check the instructions to [Run a Node](https://ethermint.dev/quickstart/run_node.html).
|
To learn how the Ethermint works from a high-level perspective, go to the [Introduction](https://evmos.dev/intro/overview.html) section from the documentation. You can also check the instructions to [Run a Node](https://evmos.dev/quickstart/run_node.html).
|
||||||
|
|
||||||
For more, please refer to the [Ethermint Docs](./docs/), which are also hosted on [ethermint.dev](https://ethermint.dev/).
|
For an example on how Ethermint can be used on any Cosmos-SDK chain, please refer to [Evmos](https://www.github.com/tharsis/evmos).
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
The following chat channels and forums are a great spot to ask questions about Ethermint:
|
The following chat channels and forums are a great spot to ask questions about Ethermint:
|
||||||
|
|
||||||
- [Ethermint Twitter](https://twitter.com/ethermint)
|
- [Evmos Twitter](https://twitter.com/EvmosOrg)
|
||||||
- [Tharsis Twitter](https://twitter.com/ethermint)
|
- [Evmos Discord](https://discord.gg/trje9XuAmy)
|
||||||
- [Ethermint Discord](https://discord.gg/trje9XuAmy)
|
- [Evmos Telegram](https://t.me/EvmosOrg)
|
||||||
- [Ethermint Forum](https://forum.cosmos.network/c/ethermint)
|
- [Tharsis Twitter](https://twitter.com/TharsisHQ)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -82,4 +75,4 @@ For additional instructions, standards and style guides, please refer to the [Co
|
|||||||
|
|
||||||
## Careers
|
## Careers
|
||||||
|
|
||||||
See our open positions on [Cosmos Jobs](https://jobs.cosmos.network/project/ethermint-d0sk1uxuh-remote/), [Notion](https://tharsis.notion.site/Jobs-at-Tharsis-5a1642eb89b34747ae6f2db2d356fc0d), or feel free to [reach out](mailto:careers@thars.is) via email.
|
See our open positions on [Cosmos Jobs](https://jobs.cosmos.network/project/evmos-d0sk1uxuh-remote/), [Notion](https://tharsis.notion.site), or feel free to [reach out](mailto:careers@thars.is) via email.
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
|
cmdcfg "github.com/tharsis/ethermint/cmd/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// sdk config
|
||||||
|
func init() {
|
||||||
|
config := sdk.GetConfig()
|
||||||
|
cmdcfg.SetBech32Prefixes(config)
|
||||||
|
cmdcfg.SetBip44CoinType(config)
|
||||||
|
config.Seal()
|
||||||
|
|
||||||
|
cmdcfg.RegisterDenoms()
|
||||||
|
}
|
||||||
+10
-54
@@ -4,22 +4,15 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
|
||||||
"github.com/palantir/stacktrace"
|
|
||||||
|
|
||||||
tmlog "github.com/tendermint/tendermint/libs/log"
|
tmlog "github.com/tendermint/tendermint/libs/log"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
|
|
||||||
channelkeeper "github.com/cosmos/ibc-go/modules/core/04-channel/keeper"
|
|
||||||
ibcante "github.com/cosmos/ibc-go/modules/core/ante"
|
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
|
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -30,14 +23,7 @@ const (
|
|||||||
// Ethereum or SDK transaction to an internal ante handler for performing
|
// Ethereum or SDK transaction to an internal ante handler for performing
|
||||||
// transaction-level processing (e.g. fee payment, signature verification) before
|
// transaction-level processing (e.g. fee payment, signature verification) before
|
||||||
// being passed onto it's respective handler.
|
// being passed onto it's respective handler.
|
||||||
func NewAnteHandler(
|
func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {
|
||||||
ak evmtypes.AccountKeeper,
|
|
||||||
bankKeeper evmtypes.BankKeeper,
|
|
||||||
evmKeeper EVMKeeper,
|
|
||||||
feeGrantKeeper authante.FeegrantKeeper,
|
|
||||||
channelKeeper channelkeeper.Keeper,
|
|
||||||
signModeHandler authsigning.SignModeHandler,
|
|
||||||
) sdk.AnteHandler {
|
|
||||||
return func(
|
return func(
|
||||||
ctx sdk.Context, tx sdk.Tx, sim bool,
|
ctx sdk.Context, tx sdk.Tx, sim bool,
|
||||||
) (newCtx sdk.Context, err error) {
|
) (newCtx sdk.Context, err error) {
|
||||||
@@ -52,25 +38,14 @@ func NewAnteHandler(
|
|||||||
switch typeURL := opts[0].GetTypeUrl(); typeURL {
|
switch typeURL := opts[0].GetTypeUrl(); typeURL {
|
||||||
case "/ethermint.evm.v1.ExtensionOptionsEthereumTx":
|
case "/ethermint.evm.v1.ExtensionOptionsEthereumTx":
|
||||||
// handle as *evmtypes.MsgEthereumTx
|
// handle as *evmtypes.MsgEthereumTx
|
||||||
|
anteHandler = newEthAnteHandler(options)
|
||||||
anteHandler = sdk.ChainAnteDecorators(
|
case "/ethermint.types.v1.ExtensionOptionsWeb3Tx":
|
||||||
NewEthSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
|
// handle as normal Cosmos SDK tx, except signature is checked for EIP712 representation
|
||||||
authante.NewMempoolFeeDecorator(),
|
anteHandler = newCosmosAnteHandlerEip712(options)
|
||||||
authante.NewTxTimeoutHeightDecorator(),
|
|
||||||
authante.NewValidateMemoDecorator(ak),
|
|
||||||
NewEthValidateBasicDecorator(),
|
|
||||||
NewEthSigVerificationDecorator(evmKeeper),
|
|
||||||
NewEthAccountVerificationDecorator(ak, bankKeeper, evmKeeper),
|
|
||||||
NewEthNonceVerificationDecorator(ak),
|
|
||||||
NewEthGasConsumeDecorator(ak, bankKeeper, evmKeeper),
|
|
||||||
NewCanTransferDecorator(evmKeeper),
|
|
||||||
NewEthIncrementSenderSequenceDecorator(ak), // innermost AnteDecorator.
|
|
||||||
)
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrapf(
|
||||||
sdkerrors.Wrap(sdkerrors.ErrUnknownExtensionOptions, typeURL),
|
sdkerrors.ErrUnknownExtensionOptions,
|
||||||
"rejecting tx with unsupported extension option",
|
"rejecting tx with unsupported extension option: %s", typeURL,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,30 +54,11 @@ func NewAnteHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle as totally normal Cosmos SDK tx
|
// handle as totally normal Cosmos SDK tx
|
||||||
|
|
||||||
switch tx.(type) {
|
switch tx.(type) {
|
||||||
case sdk.Tx:
|
case sdk.Tx:
|
||||||
anteHandler = sdk.ChainAnteDecorators(
|
anteHandler = newCosmosAnteHandler(options)
|
||||||
authante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
|
|
||||||
authante.NewRejectExtensionOptionsDecorator(),
|
|
||||||
authante.NewMempoolFeeDecorator(),
|
|
||||||
authante.NewValidateBasicDecorator(),
|
|
||||||
authante.NewTxTimeoutHeightDecorator(),
|
|
||||||
authante.NewValidateMemoDecorator(ak),
|
|
||||||
ibcante.NewAnteDecorator(channelKeeper),
|
|
||||||
authante.NewConsumeGasForTxSizeDecorator(ak),
|
|
||||||
authante.NewSetPubKeyDecorator(ak), // SetPubKeyDecorator must be called before all signature verification decorators
|
|
||||||
authante.NewValidateSigCountDecorator(ak),
|
|
||||||
authante.NewDeductFeeDecorator(ak, bankKeeper, feeGrantKeeper),
|
|
||||||
authante.NewSigGasConsumeDecorator(ak, DefaultSigVerificationGasConsumer),
|
|
||||||
authante.NewSigVerificationDecorator(ak, signModeHandler),
|
|
||||||
authante.NewIncrementSequenceDecorator(ak), // innermost AnteDecorator
|
|
||||||
)
|
|
||||||
default:
|
default:
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx),
|
|
||||||
"transaction is not an SDK tx",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return anteHandler(ctx, tx, sim)
|
return anteHandler(ctx, tx, sim)
|
||||||
|
|||||||
+559
-19
@@ -1,16 +1,22 @@
|
|||||||
package ante_test
|
package ante_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
ethparams "github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/tharsis/ethermint/tests"
|
"github.com/tharsis/ethermint/tests"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (suite AnteTestSuite) TestAnteHandler() {
|
func (suite AnteTestSuite) TestAnteHandler() {
|
||||||
|
suite.enableFeemarket = false
|
||||||
|
suite.SetupTest() // reset
|
||||||
|
|
||||||
addr, privKey := tests.NewAddrKey()
|
addr, privKey := tests.NewAddrKey()
|
||||||
to := tests.GenerateAddress()
|
to := tests.GenerateAddress()
|
||||||
|
|
||||||
@@ -18,7 +24,9 @@ func (suite AnteTestSuite) TestAnteHandler() {
|
|||||||
suite.Require().NoError(acc.SetSequence(1))
|
suite.Require().NoError(acc.SetSequence(1))
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
||||||
|
|
||||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt(10000000000))
|
suite.app.EvmKeeper.SetBalance(suite.ctx, addr, big.NewInt(10000000000))
|
||||||
|
|
||||||
|
suite.app.FeeMarketKeeper.SetBaseFee(suite.ctx, big.NewInt(100))
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -30,10 +38,20 @@ func (suite AnteTestSuite) TestAnteHandler() {
|
|||||||
{
|
{
|
||||||
"success - DeliverTx (contract)",
|
"success - DeliverTx (contract)",
|
||||||
func() sdk.Tx {
|
func() sdk.Tx {
|
||||||
signedContractTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
signedContractTx := evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
big.NewInt(150),
|
||||||
|
big.NewInt(200),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
signedContractTx.From = addr.Hex()
|
signedContractTx.From = addr.Hex()
|
||||||
|
|
||||||
tx := suite.CreateTestTx(signedContractTx, privKey, 1, true)
|
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||||
return tx
|
return tx
|
||||||
},
|
},
|
||||||
false, false, true,
|
false, false, true,
|
||||||
@@ -41,10 +59,20 @@ func (suite AnteTestSuite) TestAnteHandler() {
|
|||||||
{
|
{
|
||||||
"success - CheckTx (contract)",
|
"success - CheckTx (contract)",
|
||||||
func() sdk.Tx {
|
func() sdk.Tx {
|
||||||
signedContractTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
signedContractTx := evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
2,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
big.NewInt(150),
|
||||||
|
big.NewInt(200),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
signedContractTx.From = addr.Hex()
|
signedContractTx.From = addr.Hex()
|
||||||
|
|
||||||
tx := suite.CreateTestTx(signedContractTx, privKey, 1, true)
|
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||||
return tx
|
return tx
|
||||||
},
|
},
|
||||||
true, false, true,
|
true, false, true,
|
||||||
@@ -52,10 +80,20 @@ func (suite AnteTestSuite) TestAnteHandler() {
|
|||||||
{
|
{
|
||||||
"success - ReCheckTx (contract)",
|
"success - ReCheckTx (contract)",
|
||||||
func() sdk.Tx {
|
func() sdk.Tx {
|
||||||
signedContractTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
signedContractTx := evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
3,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
big.NewInt(150),
|
||||||
|
big.NewInt(200),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
signedContractTx.From = addr.Hex()
|
signedContractTx.From = addr.Hex()
|
||||||
|
|
||||||
tx := suite.CreateTestTx(signedContractTx, privKey, 1, true)
|
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||||
return tx
|
return tx
|
||||||
},
|
},
|
||||||
false, true, true,
|
false, true, true,
|
||||||
@@ -63,10 +101,21 @@ func (suite AnteTestSuite) TestAnteHandler() {
|
|||||||
{
|
{
|
||||||
"success - DeliverTx",
|
"success - DeliverTx",
|
||||||
func() sdk.Tx {
|
func() sdk.Tx {
|
||||||
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
signedTx := evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
4,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
big.NewInt(150),
|
||||||
|
big.NewInt(200),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
signedTx.From = addr.Hex()
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
tx := suite.CreateTestTx(signedTx, privKey, 1, true)
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
return tx
|
return tx
|
||||||
},
|
},
|
||||||
false, false, true,
|
false, false, true,
|
||||||
@@ -74,10 +123,21 @@ func (suite AnteTestSuite) TestAnteHandler() {
|
|||||||
{
|
{
|
||||||
"success - CheckTx",
|
"success - CheckTx",
|
||||||
func() sdk.Tx {
|
func() sdk.Tx {
|
||||||
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 2, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
signedTx := evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
5,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
big.NewInt(150),
|
||||||
|
big.NewInt(200),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
signedTx.From = addr.Hex()
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
tx := suite.CreateTestTx(signedTx, privKey, 1, true)
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
return tx
|
return tx
|
||||||
},
|
},
|
||||||
true, false, true,
|
true, false, true,
|
||||||
@@ -85,17 +145,39 @@ func (suite AnteTestSuite) TestAnteHandler() {
|
|||||||
{
|
{
|
||||||
"success - ReCheckTx",
|
"success - ReCheckTx",
|
||||||
func() sdk.Tx {
|
func() sdk.Tx {
|
||||||
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 3, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
signedTx := evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
6,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
big.NewInt(150),
|
||||||
|
big.NewInt(200),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
signedTx.From = addr.Hex()
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
tx := suite.CreateTestTx(signedTx, privKey, 1, true)
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
return tx
|
return tx
|
||||||
}, false, true, true,
|
}, false, true, true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"success - CheckTx (cosmos tx not signed)",
|
"success - CheckTx (cosmos tx not signed)",
|
||||||
func() sdk.Tx {
|
func() sdk.Tx {
|
||||||
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 4, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
signedTx := evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
7,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
big.NewInt(150),
|
||||||
|
big.NewInt(200),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
signedTx.From = addr.Hex()
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
@@ -105,31 +187,212 @@ func (suite AnteTestSuite) TestAnteHandler() {
|
|||||||
{
|
{
|
||||||
"fail - CheckTx (cosmos tx is not valid)",
|
"fail - CheckTx (cosmos tx is not valid)",
|
||||||
func() sdk.Tx {
|
func() sdk.Tx {
|
||||||
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 4, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 8, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
signedTx.From = addr.Hex()
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
||||||
// bigger than MaxGasWanted
|
// bigger than MaxGasWanted
|
||||||
txBuilder.SetGasLimit(uint64(1 << 63))
|
txBuilder.SetGasLimit(uint64(1 << 63))
|
||||||
return txBuilder.GetTx()
|
return txBuilder.GetTx()
|
||||||
}, false, true, false,
|
}, true, false, false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fail - CheckTx (memo too long)",
|
"fail - CheckTx (memo too long)",
|
||||||
func() sdk.Tx {
|
func() sdk.Tx {
|
||||||
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 5, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil)
|
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 5, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
signedTx.From = addr.Hex()
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, true)
|
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
||||||
txBuilder.SetMemo(strings.Repeat("*", 257))
|
txBuilder.SetMemo(strings.Repeat("*", 257))
|
||||||
return txBuilder.GetTx()
|
return txBuilder.GetTx()
|
||||||
}, true, false, false,
|
}, true, false, false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fail - CheckTx (ExtensionOptionsEthereumTx not set)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 5, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false, true)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, true, false, false,
|
||||||
|
},
|
||||||
|
// Based on EVMBackend.SendTransaction, for cosmos tx, forcing null for some fields except ExtensionOptions, Fee, MsgEthereumTx
|
||||||
|
// should be part of consensus
|
||||||
|
{
|
||||||
|
"fail - DeliverTx (cosmos tx signed)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedTx, privKey, 1, true)
|
||||||
|
return tx
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail - DeliverTx (cosmos tx with memo)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
||||||
|
txBuilder.SetMemo("memo for cosmos tx not allowed")
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail - DeliverTx (cosmos tx with timeoutheight)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
||||||
|
txBuilder.SetTimeoutHeight(10)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail - DeliverTx (invalid fee amount)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
||||||
|
|
||||||
|
txData, err := evmtypes.UnpackTxData(signedTx.Data)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
expFee := txData.Fee()
|
||||||
|
invalidFee := new(big.Int).Add(expFee, big.NewInt(1))
|
||||||
|
invalidFeeAmount := sdk.Coins{sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(invalidFee))}
|
||||||
|
txBuilder.SetFeeAmount(invalidFeeAmount)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail - DeliverTx (invalid fee gaslimit)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
||||||
|
|
||||||
|
expGasLimit := signedTx.GetGas()
|
||||||
|
invalidGasLimit := expGasLimit + 1
|
||||||
|
txBuilder.SetGasLimit(invalidGasLimit)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - DeliverTx EIP712 signed Cosmos Tx with MsgSend",
|
||||||
|
func() sdk.Tx {
|
||||||
|
from := acc.GetAddress()
|
||||||
|
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
|
||||||
|
gas := uint64(200000)
|
||||||
|
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9000-1", gas, amount)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - DeliverTx EIP712 signed Cosmos Tx with DelegateMsg",
|
||||||
|
func() sdk.Tx {
|
||||||
|
from := acc.GetAddress()
|
||||||
|
coinAmount := sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20))
|
||||||
|
amount := sdk.NewCoins(coinAmount)
|
||||||
|
gas := uint64(200000)
|
||||||
|
txBuilder := suite.CreateTestEIP712TxBuilderMsgDelegate(from, privKey, "ethermint_9000-1", gas, amount)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fails - DeliverTx EIP712 signed Cosmos Tx with wrong Chain ID",
|
||||||
|
func() sdk.Tx {
|
||||||
|
from := acc.GetAddress()
|
||||||
|
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
|
||||||
|
gas := uint64(200000)
|
||||||
|
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9002-1", gas, amount)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fails - DeliverTx EIP712 signed Cosmos Tx with different gas fees",
|
||||||
|
func() sdk.Tx {
|
||||||
|
from := acc.GetAddress()
|
||||||
|
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
|
||||||
|
gas := uint64(200000)
|
||||||
|
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9001-1", gas, amount)
|
||||||
|
txBuilder.SetGasLimit(uint64(300000))
|
||||||
|
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(30))))
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fails - DeliverTx EIP712 signed Cosmos Tx with empty signature",
|
||||||
|
func() sdk.Tx {
|
||||||
|
from := acc.GetAddress()
|
||||||
|
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
|
||||||
|
gas := uint64(200000)
|
||||||
|
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9001-1", gas, amount)
|
||||||
|
sigsV2 := signing.SignatureV2{}
|
||||||
|
txBuilder.SetSignatures(sigsV2)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fails - DeliverTx EIP712 signed Cosmos Tx with invalid sequence",
|
||||||
|
func() sdk.Tx {
|
||||||
|
from := acc.GetAddress()
|
||||||
|
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
|
||||||
|
gas := uint64(200000)
|
||||||
|
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9001-1", gas, amount)
|
||||||
|
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
sigsV2 := signing.SignatureV2{
|
||||||
|
PubKey: privKey.PubKey(),
|
||||||
|
Data: &signing.SingleSignatureData{
|
||||||
|
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||||
|
},
|
||||||
|
Sequence: nonce - 1,
|
||||||
|
}
|
||||||
|
txBuilder.SetSignatures(sigsV2)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fails - DeliverTx EIP712 signed Cosmos Tx with invalid signMode",
|
||||||
|
func() sdk.Tx {
|
||||||
|
from := acc.GetAddress()
|
||||||
|
amount := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
|
||||||
|
gas := uint64(200000)
|
||||||
|
txBuilder := suite.CreateTestEIP712TxBuilderMsgSend(from, privKey, "ethermint_9001-1", gas, amount)
|
||||||
|
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress())
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
sigsV2 := signing.SignatureV2{
|
||||||
|
PubKey: privKey.PubKey(),
|
||||||
|
Data: &signing.SingleSignatureData{
|
||||||
|
SignMode: signing.SignMode_SIGN_MODE_UNSPECIFIED,
|
||||||
|
},
|
||||||
|
Sequence: nonce,
|
||||||
|
}
|
||||||
|
txBuilder.SetSignatures(sigsV2)
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
}, false, false, false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
suite.Run(tc.name, func() {
|
suite.Run(tc.name, func() {
|
||||||
suite.ctx = suite.ctx.WithIsCheckTx(tc.reCheckTx).WithIsReCheckTx(tc.reCheckTx)
|
suite.ctx = suite.ctx.WithIsCheckTx(tc.checkTx).WithIsReCheckTx(tc.reCheckTx)
|
||||||
|
|
||||||
// expConsumed := params.TxGasContractCreation + params.TxGas
|
// expConsumed := params.TxGasContractCreation + params.TxGas
|
||||||
_, err := suite.anteHandler(suite.ctx, tc.txFn(), false)
|
_, err := suite.anteHandler(suite.ctx, tc.txFn(), false)
|
||||||
@@ -145,3 +408,280 @@ func (suite AnteTestSuite) TestAnteHandler() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
||||||
|
addr, privKey := tests.NewAddrKey()
|
||||||
|
to := tests.GenerateAddress()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
txFn func() sdk.Tx
|
||||||
|
enableLondonHF bool
|
||||||
|
checkTx bool
|
||||||
|
reCheckTx bool
|
||||||
|
expPass bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"success - DeliverTx (contract)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedContractTx :=
|
||||||
|
evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedContractTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
false, false, true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - CheckTx (contract)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedContractTx :=
|
||||||
|
evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedContractTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
true, false, true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - ReCheckTx (contract)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedContractTx :=
|
||||||
|
evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedContractTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
false, true, true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - DeliverTx",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedTx :=
|
||||||
|
evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
false, false, true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - CheckTx",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedTx :=
|
||||||
|
evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
true, false, true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - ReCheckTx",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedTx :=
|
||||||
|
evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
false, true, true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - CheckTx (cosmos tx not signed)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedTx :=
|
||||||
|
evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
false, true, true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail - CheckTx (cosmos tx is not valid)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedTx :=
|
||||||
|
evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
||||||
|
// bigger than MaxGasWanted
|
||||||
|
txBuilder.SetGasLimit(uint64(1 << 63))
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
true, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail - CheckTx (memo too long)",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedTx :=
|
||||||
|
evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false)
|
||||||
|
txBuilder.SetMemo(strings.Repeat("*", 257))
|
||||||
|
return txBuilder.GetTx()
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
true, false, false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail - DynamicFeeTx without london hark fork",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedContractTx :=
|
||||||
|
evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedContractTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
false, false, false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
suite.Run(tc.name, func() {
|
||||||
|
suite.enableFeemarket = true
|
||||||
|
suite.enableLondonHF = tc.enableLondonHF
|
||||||
|
suite.SetupTest() // reset
|
||||||
|
|
||||||
|
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
||||||
|
suite.Require().NoError(acc.SetSequence(1))
|
||||||
|
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
||||||
|
|
||||||
|
suite.ctx = suite.ctx.WithIsCheckTx(tc.checkTx).WithIsReCheckTx(tc.reCheckTx)
|
||||||
|
suite.app.EvmKeeper.SetBalance(suite.ctx, addr, big.NewInt((ethparams.InitialBaseFee+10)*100000))
|
||||||
|
_, err := suite.anteHandler(suite.ctx, tc.txFn(), false)
|
||||||
|
if tc.expPass {
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
} else {
|
||||||
|
suite.Require().Error(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
suite.enableFeemarket = false
|
||||||
|
suite.enableLondonHF = true
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,272 @@
|
|||||||
|
package ante
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
|
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
|
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||||
|
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||||
|
|
||||||
|
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||||
|
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
|
||||||
|
"github.com/tharsis/ethermint/ethereum/eip712"
|
||||||
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ethermintCodec codec.ProtoCodecMarshaler
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry := codectypes.NewInterfaceRegistry()
|
||||||
|
ethermint.RegisterInterfaces(registry)
|
||||||
|
ethermintCodec = codec.NewProtoCodec(registry)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eip712SigVerificationDecorator Verify all signatures for a tx and return an error if any are invalid. Note,
|
||||||
|
// the Eip712SigVerificationDecorator decorator will not get executed on ReCheck.
|
||||||
|
//
|
||||||
|
// CONTRACT: Pubkeys are set in context for all signers before this decorator runs
|
||||||
|
// CONTRACT: Tx must implement SigVerifiableTx interface
|
||||||
|
type Eip712SigVerificationDecorator struct {
|
||||||
|
ak evmtypes.AccountKeeper
|
||||||
|
signModeHandler authsigning.SignModeHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEip712SigVerificationDecorator creates a new Eip712SigVerificationDecorator
|
||||||
|
func NewEip712SigVerificationDecorator(ak evmtypes.AccountKeeper, signModeHandler authsigning.SignModeHandler) Eip712SigVerificationDecorator {
|
||||||
|
return Eip712SigVerificationDecorator{
|
||||||
|
ak: ak,
|
||||||
|
signModeHandler: signModeHandler,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnteHandle handles validation of EIP712 signed cosmos txs.
|
||||||
|
// it is not run on RecheckTx
|
||||||
|
func (svd Eip712SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||||
|
// no need to verify signatures on recheck tx
|
||||||
|
if ctx.IsReCheckTx() {
|
||||||
|
return next(ctx, tx, simulate)
|
||||||
|
}
|
||||||
|
|
||||||
|
sigTx, ok := tx.(authsigning.SigVerifiableTx)
|
||||||
|
if !ok {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "tx %T doesn't implement authsigning.SigVerifiableTx", tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
authSignTx, ok := tx.(authsigning.Tx)
|
||||||
|
if !ok {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "tx %T doesn't implement the authsigning.Tx interface", tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// stdSigs contains the sequence number, account number, and signatures.
|
||||||
|
// When simulating, this would just be a 0-length slice.
|
||||||
|
sigs, err := sigTx.GetSignaturesV2()
|
||||||
|
if err != nil {
|
||||||
|
return ctx, err
|
||||||
|
}
|
||||||
|
|
||||||
|
signerAddrs := sigTx.GetSigners()
|
||||||
|
|
||||||
|
// EIP712 allows just one signature
|
||||||
|
if len(sigs) != 1 {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signers (%d); EIP712 signatures allows just one signature", len(sigs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that signer length and signature length are the same
|
||||||
|
if len(sigs) != len(signerAddrs) {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signerAddrs), len(sigs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// EIP712 has just one signature, avoid looping here and only read index 0
|
||||||
|
i := 0
|
||||||
|
sig := sigs[i]
|
||||||
|
|
||||||
|
acc, err := authante.GetSignerAcc(ctx, svd.ak, signerAddrs[i])
|
||||||
|
if err != nil {
|
||||||
|
return ctx, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve pubkey
|
||||||
|
pubKey := acc.GetPubKey()
|
||||||
|
if !simulate && pubKey == nil {
|
||||||
|
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check account sequence number.
|
||||||
|
if sig.Sequence != acc.GetSequence() {
|
||||||
|
return ctx, sdkerrors.Wrapf(
|
||||||
|
sdkerrors.ErrWrongSequence,
|
||||||
|
"account sequence mismatch, expected %d, got %d", acc.GetSequence(), sig.Sequence,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve signer data
|
||||||
|
genesis := ctx.BlockHeight() == 0
|
||||||
|
chainID := ctx.ChainID()
|
||||||
|
|
||||||
|
var accNum uint64
|
||||||
|
if !genesis {
|
||||||
|
accNum = acc.GetAccountNumber()
|
||||||
|
}
|
||||||
|
|
||||||
|
signerData := authsigning.SignerData{
|
||||||
|
ChainID: chainID,
|
||||||
|
AccountNumber: accNum,
|
||||||
|
Sequence: acc.GetSequence(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if simulate {
|
||||||
|
return next(ctx, tx, simulate)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := VerifySignature(pubKey, signerData, sig.Data, svd.signModeHandler, authSignTx); err != nil {
|
||||||
|
errMsg := fmt.Errorf("signature verification failed; please verify account number (%d) and chain-id (%s): %w", accNum, chainID, err)
|
||||||
|
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, errMsg.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return next(ctx, tx, simulate)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifySignature verifies a transaction signature contained in SignatureData abstracting over different signing modes
|
||||||
|
// and single vs multi-signatures.
|
||||||
|
func VerifySignature(
|
||||||
|
pubKey cryptotypes.PubKey,
|
||||||
|
signerData authsigning.SignerData,
|
||||||
|
sigData signing.SignatureData,
|
||||||
|
_ authsigning.SignModeHandler,
|
||||||
|
tx authsigning.Tx,
|
||||||
|
) error {
|
||||||
|
switch data := sigData.(type) {
|
||||||
|
case *signing.SingleSignatureData:
|
||||||
|
if data.SignMode != signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON {
|
||||||
|
return sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "unexpected SignatureData %T: wrong SignMode", sigData)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: this prevents the user from sending thrash data in the signature field
|
||||||
|
if len(data.Signature) != 0 {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrTooManySignatures, "invalid signature value; EIP712 must have the cosmos transaction signature empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// @contract: this code is reached only when Msg has Web3Tx extension (so this custom Ante handler flow),
|
||||||
|
// and the signature is SIGN_MODE_LEGACY_AMINO_JSON which is supported for EIP712 for now
|
||||||
|
|
||||||
|
msgs := tx.GetMsgs()
|
||||||
|
if len(msgs) == 0 {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrNoSignatures, "tx doesn't contain any msgs to verify signature")
|
||||||
|
}
|
||||||
|
|
||||||
|
txBytes := legacytx.StdSignBytes(
|
||||||
|
signerData.ChainID,
|
||||||
|
signerData.AccountNumber,
|
||||||
|
signerData.Sequence,
|
||||||
|
tx.GetTimeoutHeight(),
|
||||||
|
legacytx.StdFee{
|
||||||
|
Amount: tx.GetFee(),
|
||||||
|
Gas: tx.GetGas(),
|
||||||
|
},
|
||||||
|
msgs, tx.GetMemo(), tx.GetTip(),
|
||||||
|
)
|
||||||
|
|
||||||
|
signerChainID, err := ethermint.ParseChainID(signerData.ChainID)
|
||||||
|
if err != nil {
|
||||||
|
return sdkerrors.Wrapf(err, "failed to parse chainID: %s", signerData.ChainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
txWithExtensions, ok := tx.(authante.HasExtensionOptionsTx)
|
||||||
|
if !ok {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrUnknownExtensionOptions, "tx doesnt contain any extensions")
|
||||||
|
}
|
||||||
|
opts := txWithExtensions.GetExtensionOptions()
|
||||||
|
if len(opts) != 1 {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrUnknownExtensionOptions, "tx doesnt contain expected amount of extension options")
|
||||||
|
}
|
||||||
|
|
||||||
|
var optIface ethermint.ExtensionOptionsWeb3TxI
|
||||||
|
|
||||||
|
if err := ethermintCodec.UnpackAny(opts[0], &optIface); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "failed to proto-unpack ExtensionOptionsWeb3Tx")
|
||||||
|
}
|
||||||
|
|
||||||
|
extOpt, ok := optIface.(*ethermint.ExtensionOptionsWeb3Tx)
|
||||||
|
if !ok {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidChainID, "unknown extension option")
|
||||||
|
}
|
||||||
|
|
||||||
|
if extOpt.TypedDataChainID != signerChainID.Uint64() {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidChainID, "invalid chainID")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(extOpt.FeePayer) == 0 {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrUnknownExtensionOptions, "no feePayer on ExtensionOptionsWeb3Tx")
|
||||||
|
}
|
||||||
|
feePayer, err := sdk.AccAddressFromBech32(extOpt.FeePayer)
|
||||||
|
if err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "failed to parse feePayer from ExtensionOptionsWeb3Tx")
|
||||||
|
}
|
||||||
|
|
||||||
|
feeDelegation := &eip712.FeeDelegationOptions{
|
||||||
|
FeePayer: feePayer,
|
||||||
|
}
|
||||||
|
|
||||||
|
typedData, err := eip712.WrapTxToTypedData(ethermintCodec, extOpt.TypedDataChainID, msgs[0], txBytes, feeDelegation)
|
||||||
|
if err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "failed to pack tx data in EIP712 object")
|
||||||
|
}
|
||||||
|
|
||||||
|
sigHash, err := eip712.ComputeTypedDataHash(typedData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
feePayerSig := extOpt.FeePayerSig
|
||||||
|
if len(feePayerSig) != ethcrypto.SignatureLength {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "signature length doesn't match typical [R||S||V] signature 65 bytes")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the recovery offset if needed (ie. Metamask eip712 signature)
|
||||||
|
if feePayerSig[ethcrypto.RecoveryIDOffset] == 27 || feePayerSig[ethcrypto.RecoveryIDOffset] == 28 {
|
||||||
|
feePayerSig[ethcrypto.RecoveryIDOffset] -= 27
|
||||||
|
}
|
||||||
|
|
||||||
|
feePayerPubkey, err := secp256k1.RecoverPubkey(sigHash, feePayerSig)
|
||||||
|
if err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "failed to recover delegated fee payer from sig")
|
||||||
|
}
|
||||||
|
|
||||||
|
ecPubKey, err := ethcrypto.UnmarshalPubkey(feePayerPubkey)
|
||||||
|
if err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "failed to unmarshal recovered fee payer pubkey")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk := ðsecp256k1.PubKey{
|
||||||
|
Key: ethcrypto.CompressPubkey(ecPubKey),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !pubKey.Equals(pk) {
|
||||||
|
return sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, "feePayer pubkey %s is different from transaction pubkey %s", pubKey, pk)
|
||||||
|
}
|
||||||
|
|
||||||
|
recoveredFeePayerAcc := sdk.AccAddress(pk.Address().Bytes())
|
||||||
|
|
||||||
|
if !recoveredFeePayerAcc.Equals(feePayer) {
|
||||||
|
return sdkerrors.Wrapf(sdkerrors.ErrorInvalidSigner, "failed to verify delegated fee payer %s signature", recoveredFeePayerAcc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifySignature of ethsecp256k1 accepts 64 byte signature [R||S]
|
||||||
|
// WARNING! Under NO CIRCUMSTANCES try to use pubKey.VerifySignature there
|
||||||
|
if !secp256k1.VerifySignature(pubKey.Bytes(), sigHash, feePayerSig[:len(feePayerSig)-1]) {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "unable to verify signer signature of EIP712 typed data")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return sdkerrors.Wrapf(sdkerrors.ErrTooManySignatures, "unexpected SignatureData %T", sigData)
|
||||||
|
}
|
||||||
|
}
|
||||||
+250
-264
@@ -7,31 +7,16 @@ import (
|
|||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||||
"github.com/palantir/stacktrace"
|
|
||||||
|
|
||||||
ethermint "github.com/tharsis/ethermint/types"
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
|
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
|
||||||
|
"github.com/tharsis/ethermint/x/evm/statedb"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// EVMKeeper defines the expected keeper interface used on the Eth AnteHandler
|
|
||||||
type EVMKeeper interface {
|
|
||||||
vm.StateDB
|
|
||||||
|
|
||||||
ChainID() *big.Int
|
|
||||||
GetParams(ctx sdk.Context) evmtypes.Params
|
|
||||||
WithContext(ctx sdk.Context)
|
|
||||||
ResetRefundTransient(ctx sdk.Context)
|
|
||||||
NewEVM(msg core.Message, config *params.ChainConfig, params evmtypes.Params, coinbase common.Address, tracer vm.Tracer) *vm.EVM
|
|
||||||
GetCodeHash(addr common.Address) common.Hash
|
|
||||||
}
|
|
||||||
|
|
||||||
// EthSigVerificationDecorator validates an ethereum signatures
|
// EthSigVerificationDecorator validates an ethereum signatures
|
||||||
type EthSigVerificationDecorator struct {
|
type EthSigVerificationDecorator struct {
|
||||||
evmKeeper EVMKeeper
|
evmKeeper EVMKeeper
|
||||||
@@ -50,13 +35,6 @@ func NewEthSigVerificationDecorator(ek EVMKeeper) EthSigVerificationDecorator {
|
|||||||
// Failure in RecheckTx will prevent tx to be included into block, especially when CheckTx succeed, in which case user
|
// Failure in RecheckTx will prevent tx to be included into block, especially when CheckTx succeed, in which case user
|
||||||
// won't see the error message.
|
// won't see the error message.
|
||||||
func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||||
if tx == nil || len(tx.GetMsgs()) != 1 {
|
|
||||||
return ctx, stacktrace.Propagate(
|
|
||||||
sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "only 1 ethereum msg supported per tx"),
|
|
||||||
"",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
chainID := esvd.evmKeeper.ChainID()
|
chainID := esvd.evmKeeper.ChainID()
|
||||||
|
|
||||||
params := esvd.evmKeeper.GetParams(ctx)
|
params := esvd.evmKeeper.GetParams(ctx)
|
||||||
@@ -65,28 +43,27 @@ func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s
|
|||||||
blockNum := big.NewInt(ctx.BlockHeight())
|
blockNum := big.NewInt(ctx.BlockHeight())
|
||||||
signer := ethtypes.MakeSigner(ethCfg, blockNum)
|
signer := ethtypes.MakeSigner(ethCfg, blockNum)
|
||||||
|
|
||||||
msg := tx.GetMsgs()[0]
|
for _, msg := range tx.GetMsgs() {
|
||||||
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}),
|
}
|
||||||
"failed to cast transaction",
|
|
||||||
)
|
sender, err := signer.Sender(msgEthTx.AsTransaction())
|
||||||
|
if err != nil {
|
||||||
|
return ctx, sdkerrors.Wrapf(
|
||||||
|
sdkerrors.ErrorInvalidSigner,
|
||||||
|
"couldn't retrieve sender address ('%s') from the ethereum transaction: %s",
|
||||||
|
msgEthTx.From,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up the sender to the transaction field if not already
|
||||||
|
msgEthTx.From = sender.Hex()
|
||||||
}
|
}
|
||||||
|
|
||||||
sender, err := signer.Sender(msgEthTx.AsTransaction())
|
return next(ctx, tx, simulate)
|
||||||
if err != nil {
|
|
||||||
return ctx, stacktrace.Propagate(
|
|
||||||
sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, err.Error()),
|
|
||||||
"couldn't retrieve sender address ('%s') from the ethereum transaction",
|
|
||||||
msgEthTx.From,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set up the sender to the transaction field if not already
|
|
||||||
msgEthTx.From = sender.Hex()
|
|
||||||
|
|
||||||
return next(ctx, msgEthTx, simulate)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthAccountVerificationDecorator validates an account balance checks
|
// EthAccountVerificationDecorator validates an account balance checks
|
||||||
@@ -116,128 +93,59 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx
|
|||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
avd.evmKeeper.WithContext(ctx)
|
|
||||||
evmDenom := avd.evmKeeper.GetParams(ctx).EvmDenom
|
|
||||||
|
|
||||||
for i, msg := range tx.GetMsgs() {
|
for i, msg := range tx.GetMsgs() {
|
||||||
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}),
|
|
||||||
"failed to cast transaction %d", i,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, stacktrace.Propagate(err, "failed to unpack tx data any for tx %d", i)
|
return ctx, sdkerrors.Wrapf(err, "failed to unpack tx data any for tx %d", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sender address should be in the tx cache from the previous AnteHandle call
|
// sender address should be in the tx cache from the previous AnteHandle call
|
||||||
from := msgEthTx.GetFrom()
|
from := msgEthTx.GetFrom()
|
||||||
if from.Empty() {
|
if from.Empty() {
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "from address cannot be empty")
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "from address cannot be empty"),
|
|
||||||
"sender address should have been in the tx field from the previous AnteHandle call",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether the sender address is EOA
|
// check whether the sender address is EOA
|
||||||
fromAddr := common.BytesToAddress(from)
|
fromAddr := common.BytesToAddress(from)
|
||||||
codeHash := avd.evmKeeper.GetCodeHash(fromAddr)
|
acct := avd.evmKeeper.GetAccount(ctx, fromAddr)
|
||||||
if codeHash != common.BytesToHash(evmtypes.EmptyCodeHash) {
|
|
||||||
return ctx, stacktrace.Propagate(sdkerrors.Wrapf(sdkerrors.ErrInvalidType,
|
|
||||||
"the sender is not EOA: address <%v>, codeHash <%s>", fromAddr, codeHash), "")
|
|
||||||
}
|
|
||||||
|
|
||||||
acc := avd.ak.GetAccount(ctx, from)
|
if acct == nil {
|
||||||
if acc == nil {
|
acc := avd.ak.NewAccountWithAddress(ctx, from)
|
||||||
acc = avd.ak.NewAccountWithAddress(ctx, from)
|
|
||||||
avd.ak.SetAccount(ctx, acc)
|
avd.ak.SetAccount(ctx, acc)
|
||||||
|
acct = statedb.NewEmptyAccount()
|
||||||
|
} else if acct.IsContract() {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidType,
|
||||||
|
"the sender is not EOA: address %s, codeHash <%s>", fromAddr, acct.CodeHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := evmkeeper.CheckSenderBalance(ctx, avd.bankKeeper, from, txData, evmDenom); err != nil {
|
if err := evmkeeper.CheckSenderBalance(sdk.NewIntFromBigInt(acct.Balance), txData); err != nil {
|
||||||
return ctx, stacktrace.Propagate(err, "failed to check sender balance")
|
return ctx, sdkerrors.Wrap(err, "failed to check sender balance")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// recover the original gas meter
|
|
||||||
avd.evmKeeper.WithContext(ctx)
|
|
||||||
return next(ctx, tx, simulate)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EthNonceVerificationDecorator checks that the account nonce from the transaction matches
|
|
||||||
// the sender account sequence.
|
|
||||||
type EthNonceVerificationDecorator struct {
|
|
||||||
ak evmtypes.AccountKeeper
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEthNonceVerificationDecorator creates a new EthNonceVerificationDecorator
|
|
||||||
func NewEthNonceVerificationDecorator(ak evmtypes.AccountKeeper) EthNonceVerificationDecorator {
|
|
||||||
return EthNonceVerificationDecorator{
|
|
||||||
ak: ak,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnteHandle validates that the transaction nonces are valid and equivalent to the sender account’s
|
|
||||||
// current nonce.
|
|
||||||
func (nvd EthNonceVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
|
||||||
// no need to check the nonce on ReCheckTx
|
|
||||||
if ctx.IsReCheckTx() {
|
|
||||||
return next(ctx, tx, simulate)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, msg := range tx.GetMsgs() {
|
|
||||||
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
|
||||||
if !ok {
|
|
||||||
return ctx, stacktrace.Propagate(
|
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}),
|
|
||||||
"failed to cast transaction %d", i,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// sender address should be in the tx cache from the previous AnteHandle call
|
|
||||||
seq, err := nvd.ak.GetSequence(ctx, msgEthTx.GetFrom())
|
|
||||||
if err != nil {
|
|
||||||
return ctx, stacktrace.Propagate(err, "sequence not found for address %s", msgEthTx.From)
|
|
||||||
}
|
|
||||||
|
|
||||||
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
|
||||||
if err != nil {
|
|
||||||
return ctx, stacktrace.Propagate(err, "failed to unpack tx data")
|
|
||||||
}
|
|
||||||
|
|
||||||
// if multiple transactions are submitted in succession with increasing nonces,
|
|
||||||
// all will be rejected except the first, since the first needs to be included in a block
|
|
||||||
// before the sequence increments
|
|
||||||
if txData.GetNonce() != seq {
|
|
||||||
return ctx, stacktrace.Propagate(
|
|
||||||
sdkerrors.Wrapf(
|
|
||||||
sdkerrors.ErrInvalidSequence,
|
|
||||||
"invalid nonce; got %d, expected %d", txData.GetNonce(), seq,
|
|
||||||
),
|
|
||||||
"",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthGasConsumeDecorator validates enough intrinsic gas for the transaction and
|
// EthGasConsumeDecorator validates enough intrinsic gas for the transaction and
|
||||||
// gas consumption.
|
// gas consumption.
|
||||||
type EthGasConsumeDecorator struct {
|
type EthGasConsumeDecorator struct {
|
||||||
ak evmtypes.AccountKeeper
|
evmKeeper EVMKeeper
|
||||||
bankKeeper evmtypes.BankKeeper
|
maxGasWanted uint64
|
||||||
evmKeeper EVMKeeper
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEthGasConsumeDecorator creates a new EthGasConsumeDecorator
|
// NewEthGasConsumeDecorator creates a new EthGasConsumeDecorator
|
||||||
func NewEthGasConsumeDecorator(ak evmtypes.AccountKeeper, bankKeeper evmtypes.BankKeeper, ek EVMKeeper) EthGasConsumeDecorator {
|
func NewEthGasConsumeDecorator(
|
||||||
|
evmKeeper EVMKeeper,
|
||||||
|
maxGasWanted uint64,
|
||||||
|
) EthGasConsumeDecorator {
|
||||||
return EthGasConsumeDecorator{
|
return EthGasConsumeDecorator{
|
||||||
ak: ak,
|
evmKeeper,
|
||||||
bankKeeper: bankKeeper,
|
maxGasWanted,
|
||||||
evmKeeper: ek,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,16 +157,13 @@ func NewEthGasConsumeDecorator(ak evmtypes.AccountKeeper, bankKeeper evmtypes.Ba
|
|||||||
// of data supplied with the transaction.
|
// of data supplied with the transaction.
|
||||||
//
|
//
|
||||||
// This AnteHandler decorator will fail if:
|
// This AnteHandler decorator will fail if:
|
||||||
// - the transaction contains more than one message
|
|
||||||
// - the message is not a MsgEthereumTx
|
// - the message is not a MsgEthereumTx
|
||||||
// - sender account cannot be found
|
// - sender account cannot be found
|
||||||
// - transaction's gas limit is lower than the intrinsic gas
|
// - transaction's gas limit is lower than the intrinsic gas
|
||||||
// - user doesn't have enough balance to deduct the transaction fees (gas_limit * gas_price)
|
// - user doesn't have enough balance to deduct the transaction fees (gas_limit * gas_price)
|
||||||
// - transaction or block gas meter runs out of gas
|
// - transaction or block gas meter runs out of gas
|
||||||
|
// - sets the gas meter limit
|
||||||
func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||||
// reset the refund gas value in the keeper for the current transaction
|
|
||||||
egcd.evmKeeper.ResetRefundTransient(ctx)
|
|
||||||
|
|
||||||
params := egcd.evmKeeper.GetParams(ctx)
|
params := egcd.evmKeeper.GetParams(ctx)
|
||||||
|
|
||||||
ethCfg := params.ChainConfig.EthereumConfig(egcd.evmKeeper.ChainID())
|
ethCfg := params.ChainConfig.EthereumConfig(egcd.evmKeeper.ChainID())
|
||||||
@@ -266,36 +171,44 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
|||||||
blockHeight := big.NewInt(ctx.BlockHeight())
|
blockHeight := big.NewInt(ctx.BlockHeight())
|
||||||
homestead := ethCfg.IsHomestead(blockHeight)
|
homestead := ethCfg.IsHomestead(blockHeight)
|
||||||
istanbul := ethCfg.IsIstanbul(blockHeight)
|
istanbul := ethCfg.IsIstanbul(blockHeight)
|
||||||
|
london := ethCfg.IsLondon(blockHeight)
|
||||||
evmDenom := params.EvmDenom
|
evmDenom := params.EvmDenom
|
||||||
|
gasWanted := uint64(0)
|
||||||
var events sdk.Events
|
var events sdk.Events
|
||||||
|
|
||||||
for i, msg := range tx.GetMsgs() {
|
for _, msg := range tx.GetMsgs() {
|
||||||
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}),
|
|
||||||
"failed to cast transaction %d", i,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, stacktrace.Propagate(err, "failed to unpack tx data")
|
return ctx, sdkerrors.Wrap(err, "failed to unpack tx data")
|
||||||
}
|
}
|
||||||
|
|
||||||
fees, err := evmkeeper.DeductTxCostsFromUserBalance(
|
if ctx.IsCheckTx() {
|
||||||
|
// We can't trust the tx gas limit, because we'll refund the unused gas.
|
||||||
|
if txData.GetGas() > egcd.maxGasWanted {
|
||||||
|
gasWanted += egcd.maxGasWanted
|
||||||
|
} else {
|
||||||
|
gasWanted += txData.GetGas()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gasWanted += txData.GetGas()
|
||||||
|
}
|
||||||
|
|
||||||
|
fees, err := egcd.evmKeeper.DeductTxCostsFromUserBalance(
|
||||||
ctx,
|
ctx,
|
||||||
egcd.bankKeeper,
|
|
||||||
egcd.ak,
|
|
||||||
*msgEthTx,
|
*msgEthTx,
|
||||||
txData,
|
txData,
|
||||||
evmDenom,
|
evmDenom,
|
||||||
homestead,
|
homestead,
|
||||||
istanbul,
|
istanbul,
|
||||||
|
london,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, stacktrace.Propagate(err, "failed to deduct transaction costs from user balance")
|
return ctx, sdkerrors.Wrapf(err, "failed to deduct transaction costs from user balance")
|
||||||
}
|
}
|
||||||
|
|
||||||
events = append(events, sdk.NewEvent(sdk.EventTypeTx, sdk.NewAttribute(sdk.AttributeKeyFee, fees.String())))
|
events = append(events, sdk.NewEvent(sdk.EventTypeTx, sdk.NewAttribute(sdk.AttributeKeyFee, fees.String())))
|
||||||
@@ -315,9 +228,12 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
|||||||
gasPool.ConsumeGas(ctx.GasMeter().GasConsumedToLimit(), "gas pool check")
|
gasPool.ConsumeGas(ctx.GasMeter().GasConsumedToLimit(), "gas pool check")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set ctx.GasMeter with a limit of GasWanted (gasLimit)
|
||||||
|
gasConsumed := ctx.GasMeter().GasConsumed()
|
||||||
|
ctx = ctx.WithGasMeter(ethermint.NewInfiniteGasMeterWithLimit(gasWanted))
|
||||||
|
ctx.GasMeter().ConsumeGas(gasConsumed, "copy gas consumed")
|
||||||
|
|
||||||
// we know that we have enough gas on the pool to cover the intrinsic gas
|
// we know that we have enough gas on the pool to cover the intrinsic gas
|
||||||
// set up the updated context to the evm Keeper
|
|
||||||
egcd.evmKeeper.WithContext(ctx)
|
|
||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,106 +253,64 @@ func NewCanTransferDecorator(evmKeeper EVMKeeper) CanTransferDecorator {
|
|||||||
// AnteHandle creates an EVM from the message and calls the BlockContext CanTransfer function to
|
// AnteHandle creates an EVM from the message and calls the BlockContext CanTransfer function to
|
||||||
// see if the address can execute the transaction.
|
// see if the address can execute the transaction.
|
||||||
func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
||||||
ctd.evmKeeper.WithContext(ctx)
|
|
||||||
|
|
||||||
params := ctd.evmKeeper.GetParams(ctx)
|
params := ctd.evmKeeper.GetParams(ctx)
|
||||||
|
|
||||||
ethCfg := params.ChainConfig.EthereumConfig(ctd.evmKeeper.ChainID())
|
ethCfg := params.ChainConfig.EthereumConfig(ctd.evmKeeper.ChainID())
|
||||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
||||||
|
|
||||||
for i, msg := range tx.GetMsgs() {
|
for _, msg := range tx.GetMsgs() {
|
||||||
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}),
|
|
||||||
"failed to cast transaction %d", i,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
coreMsg, err := msgEthTx.AsMessage(signer)
|
baseFee := ctd.evmKeeper.BaseFee(ctx, ethCfg)
|
||||||
|
|
||||||
|
coreMsg, err := msgEthTx.AsMessage(signer, baseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrapf(
|
||||||
err,
|
err,
|
||||||
"failed to create an ethereum core.Message from signer %T", signer,
|
"failed to create an ethereum core.Message from signer %T", signer,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: pass in an empty coinbase address and nil tracer as we don't need them for the check below
|
// NOTE: pass in an empty coinbase address and nil tracer as we don't need them for the check below
|
||||||
evm := ctd.evmKeeper.NewEVM(coreMsg, ethCfg, params, common.Address{}, nil)
|
cfg := &evmtypes.EVMConfig{
|
||||||
|
ChainConfig: ethCfg,
|
||||||
|
Params: params,
|
||||||
|
CoinBase: common.Address{},
|
||||||
|
BaseFee: baseFee,
|
||||||
|
}
|
||||||
|
stateDB := statedb.New(ctx, ctd.evmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes())))
|
||||||
|
evm := ctd.evmKeeper.NewEVM(ctx, coreMsg, cfg, evmtypes.NewNoOpTracer(), stateDB)
|
||||||
|
|
||||||
// check that caller has enough balance to cover asset transfer for **topmost** call
|
// check that caller has enough balance to cover asset transfer for **topmost** call
|
||||||
// NOTE: here the gas consumed is from the context with the infinite gas meter
|
// NOTE: here the gas consumed is from the context with the infinite gas meter
|
||||||
if coreMsg.Value().Sign() > 0 && !evm.Context.CanTransfer(ctd.evmKeeper, coreMsg.From(), coreMsg.Value()) {
|
if coreMsg.Value().Sign() > 0 && !evm.Context.CanTransfer(stateDB, coreMsg.From(), coreMsg.Value()) {
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrapf(
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "address %s", coreMsg.From()),
|
sdkerrors.ErrInsufficientFunds,
|
||||||
"failed to transfer %s using the EVM block context transfer function", coreMsg.Value(),
|
"failed to transfer %s from address %s using the EVM block context transfer function",
|
||||||
)
|
coreMsg.Value(),
|
||||||
}
|
coreMsg.From(),
|
||||||
}
|
|
||||||
|
|
||||||
ctd.evmKeeper.WithContext(ctx)
|
|
||||||
|
|
||||||
// set the original gas meter
|
|
||||||
return next(ctx, tx, simulate)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AccessListDecorator prepare an access list for the sender if Yolov3/Berlin/EIPs 2929 and 2930 are
|
|
||||||
// applicable at the current block number.
|
|
||||||
type AccessListDecorator struct {
|
|
||||||
evmKeeper EVMKeeper
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAccessListDecorator creates a new AccessListDecorator.
|
|
||||||
func NewAccessListDecorator(evmKeeper EVMKeeper) AccessListDecorator {
|
|
||||||
return AccessListDecorator{
|
|
||||||
evmKeeper: evmKeeper,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnteHandle handles the preparatory steps for executing an EVM state transition with
|
|
||||||
// regards to both EIP-2929 and EIP-2930:
|
|
||||||
//
|
|
||||||
// - Add sender to access list (2929)
|
|
||||||
// - Add destination to access list (2929)
|
|
||||||
// - Add precompiles to access list (2929)
|
|
||||||
// - Add the contents of the optional tx access list (2930)
|
|
||||||
//
|
|
||||||
// The AnteHandler will only prepare the access list if Yolov3/Berlin/EIPs 2929 and 2930 are applicable at the current number.
|
|
||||||
func (ald AccessListDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
|
||||||
params := ald.evmKeeper.GetParams(ctx)
|
|
||||||
ethCfg := params.ChainConfig.EthereumConfig(ald.evmKeeper.ChainID())
|
|
||||||
|
|
||||||
rules := ethCfg.Rules(big.NewInt(ctx.BlockHeight()))
|
|
||||||
|
|
||||||
// we don't need to prepare the access list if the chain is not currently on the Berlin upgrade
|
|
||||||
if !rules.IsBerlin {
|
|
||||||
return next(ctx, tx, simulate)
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup the keeper context before setting the access list
|
|
||||||
ald.evmKeeper.WithContext(ctx)
|
|
||||||
|
|
||||||
for i, msg := range tx.GetMsgs() {
|
|
||||||
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
|
||||||
if !ok {
|
|
||||||
return ctx, stacktrace.Propagate(
|
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}),
|
|
||||||
"failed to cast transaction %d", i,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
sender := common.BytesToAddress(msgEthTx.GetFrom())
|
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) {
|
||||||
|
if baseFee == nil {
|
||||||
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
return ctx, sdkerrors.Wrap(
|
||||||
if err != nil {
|
evmtypes.ErrInvalidBaseFee,
|
||||||
return ctx, stacktrace.Propagate(err, "failed to unpack tx data")
|
"base fee is supported but evm block context value is nil",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if coreMsg.GasFeeCap().Cmp(baseFee) < 0 {
|
||||||
|
return ctx, sdkerrors.Wrapf(
|
||||||
|
sdkerrors.ErrInsufficientFee,
|
||||||
|
"max fee per gas less than block base fee (%s < %s)",
|
||||||
|
coreMsg.GasFeeCap(), baseFee,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ald.evmKeeper.PrepareAccessList(sender, txData.GetTo(), vm.ActivePrecompiles(rules), txData.GetAccessList())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the original gas meter
|
|
||||||
ald.evmKeeper.WithContext(ctx)
|
|
||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,60 +330,56 @@ func NewEthIncrementSenderSequenceDecorator(ak evmtypes.AccountKeeper) EthIncrem
|
|||||||
// contract creation, the nonce will be incremented during the transaction execution and not within
|
// contract creation, the nonce will be incremented during the transaction execution and not within
|
||||||
// this AnteHandler decorator.
|
// this AnteHandler decorator.
|
||||||
func (issd EthIncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
func (issd EthIncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
||||||
for i, msg := range tx.GetMsgs() {
|
for _, msg := range tx.GetMsgs() {
|
||||||
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ctx, stacktrace.Propagate(
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
||||||
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, &evmtypes.MsgEthereumTx{}),
|
|
||||||
"failed to cast transaction %d", i,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, stacktrace.Propagate(err, "failed to unpack tx data")
|
return ctx, sdkerrors.Wrap(err, "failed to unpack tx data")
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: on contract creation, the nonce is incremented within the EVM Create function during tx execution
|
// increase sequence of sender
|
||||||
// and not previous to the state transition ¯\_(ツ)_/¯
|
acc := issd.ak.GetAccount(ctx, msgEthTx.GetFrom())
|
||||||
if txData.GetTo() == nil {
|
if acc == nil {
|
||||||
// contract creation, don't increment sequence on AnteHandler but on tx execution
|
return ctx, sdkerrors.Wrapf(
|
||||||
// continue to the next item
|
sdkerrors.ErrUnknownAddress,
|
||||||
continue
|
"account %s is nil", common.BytesToAddress(msgEthTx.GetFrom().Bytes()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
nonce := acc.GetSequence()
|
||||||
|
|
||||||
|
// we merged the nonce verification to nonce increment, so when tx includes multiple messages
|
||||||
|
// with same sender, they'll be accepted.
|
||||||
|
if txData.GetNonce() != nonce {
|
||||||
|
return ctx, sdkerrors.Wrapf(
|
||||||
|
sdkerrors.ErrInvalidSequence,
|
||||||
|
"invalid nonce; got %d, expected %d", txData.GetNonce(), nonce,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment sequence of all signers
|
if err := acc.SetSequence(nonce + 1); err != nil {
|
||||||
for _, addr := range msg.GetSigners() {
|
return ctx, sdkerrors.Wrapf(err, "failed to set sequence to %d", acc.GetSequence()+1)
|
||||||
acc := issd.ak.GetAccount(ctx, addr)
|
|
||||||
|
|
||||||
if acc == nil {
|
|
||||||
return ctx, stacktrace.Propagate(
|
|
||||||
sdkerrors.Wrapf(
|
|
||||||
sdkerrors.ErrUnknownAddress,
|
|
||||||
"account %s (%s) is nil", common.BytesToAddress(addr.Bytes()), addr,
|
|
||||||
),
|
|
||||||
"signer account not found",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
|
|
||||||
return ctx, stacktrace.Propagate(err, "failed to set sequence to %d", acc.GetSequence()+1)
|
|
||||||
}
|
|
||||||
|
|
||||||
issd.ak.SetAccount(ctx, acc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issd.ak.SetAccount(ctx, acc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the original gas meter
|
|
||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthValidateBasicDecorator is adapted from ValidateBasicDecorator from cosmos-sdk, it ignores ErrNoSignatures
|
// EthValidateBasicDecorator is adapted from ValidateBasicDecorator from cosmos-sdk, it ignores ErrNoSignatures
|
||||||
type EthValidateBasicDecorator struct{}
|
type EthValidateBasicDecorator struct {
|
||||||
|
evmKeeper EVMKeeper
|
||||||
|
}
|
||||||
|
|
||||||
// NewEthValidateBasicDecorator creates a new EthValidateBasicDecorator
|
// NewEthValidateBasicDecorator creates a new EthValidateBasicDecorator
|
||||||
func NewEthValidateBasicDecorator() EthValidateBasicDecorator {
|
func NewEthValidateBasicDecorator(ek EVMKeeper) EthValidateBasicDecorator {
|
||||||
return EthValidateBasicDecorator{}
|
return EthValidateBasicDecorator{
|
||||||
|
evmKeeper: ek,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnteHandle handles basic validation of tx
|
// AnteHandle handles basic validation of tx
|
||||||
@@ -522,7 +392,70 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
|
|||||||
err := tx.ValidateBasic()
|
err := tx.ValidateBasic()
|
||||||
// ErrNoSignatures is fine with eth tx
|
// ErrNoSignatures is fine with eth tx
|
||||||
if err != nil && !errors.Is(err, sdkerrors.ErrNoSignatures) {
|
if err != nil && !errors.Is(err, sdkerrors.ErrNoSignatures) {
|
||||||
return ctx, stacktrace.Propagate(err, "tx basic validation failed")
|
return ctx, sdkerrors.Wrap(err, "tx basic validation failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// For eth type cosmos tx, some fields should be veified as zero values,
|
||||||
|
// since we will only verify the signature against the hash of the MsgEthereumTx.Data
|
||||||
|
if wrapperTx, ok := tx.(protoTxProvider); ok {
|
||||||
|
protoTx := wrapperTx.GetProtoTx()
|
||||||
|
body := protoTx.Body
|
||||||
|
if body.Memo != "" || body.TimeoutHeight != uint64(0) || len(body.NonCriticalExtensionOptions) > 0 {
|
||||||
|
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest,
|
||||||
|
"for eth tx body Memo TimeoutHeight NonCriticalExtensionOptions should be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(body.ExtensionOptions) != 1 {
|
||||||
|
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx length of ExtensionOptions should be 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
txFee := sdk.Coins{}
|
||||||
|
txGasLimit := uint64(0)
|
||||||
|
|
||||||
|
for _, msg := range protoTx.GetMsgs() {
|
||||||
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
|
if !ok {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
||||||
|
}
|
||||||
|
txGasLimit += msgEthTx.GetGas()
|
||||||
|
|
||||||
|
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
||||||
|
if err != nil {
|
||||||
|
return ctx, sdkerrors.Wrap(err, "failed to unpack MsgEthereumTx Data")
|
||||||
|
}
|
||||||
|
|
||||||
|
params := vbd.evmKeeper.GetParams(ctx)
|
||||||
|
chainID := vbd.evmKeeper.ChainID()
|
||||||
|
ethCfg := params.ChainConfig.EthereumConfig(chainID)
|
||||||
|
baseFee := vbd.evmKeeper.BaseFee(ctx, ethCfg)
|
||||||
|
if baseFee == nil && txData.TxType() == ethtypes.DynamicFeeTxType {
|
||||||
|
return ctx, sdkerrors.Wrap(ethtypes.ErrTxTypeNotSupported, "dynamic fee tx not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
txFee = txFee.Add(sdk.NewCoin(params.EvmDenom, sdk.NewIntFromBigInt(txData.Fee())))
|
||||||
|
}
|
||||||
|
|
||||||
|
authInfo := protoTx.AuthInfo
|
||||||
|
if len(authInfo.SignerInfos) > 0 {
|
||||||
|
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx AuthInfo SignerInfos should be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if authInfo.Fee.Payer != "" || authInfo.Fee.Granter != "" {
|
||||||
|
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx AuthInfo Fee payer and granter should be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !authInfo.Fee.Amount.IsEqual(txFee) {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid AuthInfo Fee Amount (%s != %s)", authInfo.Fee.Amount, txFee)
|
||||||
|
}
|
||||||
|
|
||||||
|
if authInfo.Fee.GasLimit != txGasLimit {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid AuthInfo Fee GasLimit (%d != %d)", authInfo.Fee.GasLimit, txGasLimit)
|
||||||
|
}
|
||||||
|
|
||||||
|
sigs := protoTx.Signatures
|
||||||
|
if len(sigs) > 0 {
|
||||||
|
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx Signatures should be empty")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
@@ -530,10 +463,14 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
|
|||||||
|
|
||||||
// EthSetupContextDecorator is adapted from SetUpContextDecorator from cosmos-sdk, it ignores gas consumption
|
// EthSetupContextDecorator is adapted from SetUpContextDecorator from cosmos-sdk, it ignores gas consumption
|
||||||
// by setting the gas meter to infinite
|
// by setting the gas meter to infinite
|
||||||
type EthSetupContextDecorator struct{}
|
type EthSetupContextDecorator struct {
|
||||||
|
evmKeeper EVMKeeper
|
||||||
|
}
|
||||||
|
|
||||||
func NewEthSetUpContextDecorator() EthSetupContextDecorator {
|
func NewEthSetUpContextDecorator(evmKeeper EVMKeeper) EthSetupContextDecorator {
|
||||||
return EthSetupContextDecorator{}
|
return EthSetupContextDecorator{
|
||||||
|
evmKeeper: evmKeeper,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (esc EthSetupContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
func (esc EthSetupContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||||
@@ -544,5 +481,54 @@ func (esc EthSetupContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
|
|||||||
}
|
}
|
||||||
|
|
||||||
newCtx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
newCtx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
|
// Reset transient gas used to prepare the execution of current cosmos tx.
|
||||||
|
// Transient gas-used is necessary to sum the gas-used of cosmos tx, when it contains multiple eth msgs.
|
||||||
|
esc.evmKeeper.ResetTransientGasUsed(ctx)
|
||||||
return next(newCtx, tx, simulate)
|
return next(newCtx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EthMempoolFeeDecorator will check if the transaction's effective fee is at least as large
|
||||||
|
// as the local validator's minimum gasFee (defined in validator config).
|
||||||
|
// If fee is too low, decorator returns error and tx is rejected from mempool.
|
||||||
|
// Note this only applies when ctx.CheckTx = true
|
||||||
|
// If fee is high enough or not CheckTx, then call next AnteHandler
|
||||||
|
// CONTRACT: Tx must implement FeeTx to use MempoolFeeDecorator
|
||||||
|
type EthMempoolFeeDecorator struct {
|
||||||
|
evmKeeper EVMKeeper
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEthMempoolFeeDecorator(ek EVMKeeper) EthMempoolFeeDecorator {
|
||||||
|
return EthMempoolFeeDecorator{
|
||||||
|
evmKeeper: ek,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnteHandle ensures that the provided fees meet a minimum threshold for the validator,
|
||||||
|
// if this is a CheckTx. This is only for local mempool purposes, and thus
|
||||||
|
// is only ran on check tx.
|
||||||
|
// It only do the check if london hardfork not enabled or feemarket not enabled, because in that case feemarket will take over the task.
|
||||||
|
func (mfd EthMempoolFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||||
|
if ctx.IsCheckTx() && !simulate {
|
||||||
|
params := mfd.evmKeeper.GetParams(ctx)
|
||||||
|
ethCfg := params.ChainConfig.EthereumConfig(mfd.evmKeeper.ChainID())
|
||||||
|
baseFee := mfd.evmKeeper.BaseFee(ctx, ethCfg)
|
||||||
|
if baseFee == nil {
|
||||||
|
for _, msg := range tx.GetMsgs() {
|
||||||
|
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
|
if !ok {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
evmDenom := params.EvmDenom
|
||||||
|
feeAmt := ethMsg.GetFee()
|
||||||
|
glDec := sdk.NewDec(int64(ethMsg.GetGas()))
|
||||||
|
requiredFee := ctx.MinGasPrices().AmountOf(evmDenom).Mul(glDec)
|
||||||
|
if sdk.NewDecFromBigInt(feeAmt).LT(requiredFee) {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeAmt, requiredFee)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next(ctx, tx, simulate)
|
||||||
|
}
|
||||||
|
|||||||
+91
-120
@@ -6,10 +6,11 @@ import (
|
|||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/app/ante"
|
"github.com/tharsis/ethermint/app/ante"
|
||||||
|
"github.com/tharsis/ethermint/server/config"
|
||||||
"github.com/tharsis/ethermint/tests"
|
"github.com/tharsis/ethermint/tests"
|
||||||
|
"github.com/tharsis/ethermint/x/evm/statedb"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ func (suite AnteTestSuite) TestEthSigVerificationDecorator() {
|
|||||||
dec := ante.NewEthSigVerificationDecorator(suite.app.EvmKeeper)
|
dec := ante.NewEthSigVerificationDecorator(suite.app.EvmKeeper)
|
||||||
addr, privKey := tests.NewAddrKey()
|
addr, privKey := tests.NewAddrKey()
|
||||||
|
|
||||||
signedTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil)
|
signedTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
signedTx.From = addr.Hex()
|
signedTx.From = addr.Hex()
|
||||||
err := signedTx.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
err := signedTx.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
@@ -32,11 +33,11 @@ func (suite AnteTestSuite) TestEthSigVerificationDecorator() {
|
|||||||
reCheckTx bool
|
reCheckTx bool
|
||||||
expPass bool
|
expPass bool
|
||||||
}{
|
}{
|
||||||
{"ReCheckTx", nil, true, false},
|
{"ReCheckTx", &invalidTx{}, true, false},
|
||||||
{"invalid transaction type", &invalidTx{}, false, false},
|
{"invalid transaction type", &invalidTx{}, false, false},
|
||||||
{
|
{
|
||||||
"invalid sender",
|
"invalid sender",
|
||||||
evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &addr, big.NewInt(10), 1000, big.NewInt(1), nil, nil),
|
evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &addr, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
@@ -63,9 +64,11 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
|||||||
|
|
||||||
addr := tests.GenerateAddress()
|
addr := tests.GenerateAddress()
|
||||||
|
|
||||||
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil)
|
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
tx.From = addr.Hex()
|
tx.From = addr.Hex()
|
||||||
|
|
||||||
|
var vmdb *statedb.StateDB
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
tx sdk.Tx
|
tx sdk.Tx
|
||||||
@@ -77,7 +80,7 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
|||||||
{"invalid transaction type", &invalidTx{}, func() {}, true, false},
|
{"invalid transaction type", &invalidTx{}, func() {}, true, false},
|
||||||
{
|
{
|
||||||
"sender not set to msg",
|
"sender not set to msg",
|
||||||
evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil),
|
evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
|
||||||
func() {},
|
func() {},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
@@ -87,7 +90,7 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
|||||||
tx,
|
tx,
|
||||||
func() {
|
func() {
|
||||||
// set not as an EOA
|
// set not as an EOA
|
||||||
suite.app.EvmKeeper.SetCode(addr, []byte("1"))
|
vmdb.SetCode(addr, []byte("1"))
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
@@ -97,7 +100,7 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
|||||||
tx,
|
tx,
|
||||||
func() {
|
func() {
|
||||||
// reset back to EOA
|
// reset back to EOA
|
||||||
suite.app.EvmKeeper.SetCode(addr, nil)
|
vmdb.SetCode(addr, nil)
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
@@ -106,7 +109,7 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
|||||||
"success new account",
|
"success new account",
|
||||||
tx,
|
tx,
|
||||||
func() {
|
func() {
|
||||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt(1000000))
|
vmdb.AddBalance(addr, big.NewInt(1000000))
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
@@ -118,7 +121,7 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
|||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
||||||
|
|
||||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt(1000000))
|
vmdb.AddBalance(addr, big.NewInt(1000000))
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
@@ -127,7 +130,10 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
|||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
suite.Run(tc.name, func() {
|
suite.Run(tc.name, func() {
|
||||||
|
vmdb = suite.StateDB()
|
||||||
tc.malleate()
|
tc.malleate()
|
||||||
|
suite.Require().NoError(vmdb.Commit())
|
||||||
|
|
||||||
_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(tc.checkTx), tc.tx, false, nextFn)
|
_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(tc.checkTx), tc.tx, false, nextFn)
|
||||||
|
|
||||||
if tc.expPass {
|
if tc.expPass {
|
||||||
@@ -140,11 +146,12 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite AnteTestSuite) TestEthNonceVerificationDecorator() {
|
func (suite AnteTestSuite) TestEthNonceVerificationDecorator() {
|
||||||
dec := ante.NewEthNonceVerificationDecorator(suite.app.AccountKeeper)
|
suite.SetupTest()
|
||||||
|
dec := ante.NewEthIncrementSenderSequenceDecorator(suite.app.AccountKeeper)
|
||||||
|
|
||||||
addr := tests.GenerateAddress()
|
addr := tests.GenerateAddress()
|
||||||
|
|
||||||
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil)
|
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
tx.From = addr.Hex()
|
tx.From = addr.Hex()
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@@ -154,7 +161,7 @@ func (suite AnteTestSuite) TestEthNonceVerificationDecorator() {
|
|||||||
reCheckTx bool
|
reCheckTx bool
|
||||||
expPass bool
|
expPass bool
|
||||||
}{
|
}{
|
||||||
{"ReCheckTx", nil, func() {}, true, true},
|
{"ReCheckTx", &invalidTx{}, func() {}, true, false},
|
||||||
{"invalid transaction type", &invalidTx{}, func() {}, false, false},
|
{"invalid transaction type", &invalidTx{}, func() {}, false, false},
|
||||||
{"sender account not found", tx, func() {}, false, false},
|
{"sender account not found", tx, func() {}, false, false},
|
||||||
{
|
{
|
||||||
@@ -195,69 +202,65 @@ func (suite AnteTestSuite) TestEthNonceVerificationDecorator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite AnteTestSuite) TestEthGasConsumeDecorator() {
|
func (suite AnteTestSuite) TestEthGasConsumeDecorator() {
|
||||||
dec := ante.NewEthGasConsumeDecorator(
|
dec := ante.NewEthGasConsumeDecorator(suite.app.EvmKeeper, config.DefaultMaxTxGasWanted)
|
||||||
suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.EvmKeeper,
|
|
||||||
)
|
|
||||||
|
|
||||||
addr := tests.GenerateAddress()
|
addr := tests.GenerateAddress()
|
||||||
|
|
||||||
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil)
|
txGasLimit := uint64(1000)
|
||||||
|
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), txGasLimit, big.NewInt(1), nil, nil, nil, nil)
|
||||||
tx.From = addr.Hex()
|
tx.From = addr.Hex()
|
||||||
|
|
||||||
tx2 := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000000, big.NewInt(1), nil, ðtypes.AccessList{{Address: addr, StorageKeys: nil}})
|
tx2GasLimit := uint64(1000000)
|
||||||
|
tx2 := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), tx2GasLimit, big.NewInt(1), nil, nil, nil, ðtypes.AccessList{{Address: addr, StorageKeys: nil}})
|
||||||
tx2.From = addr.Hex()
|
tx2.From = addr.Hex()
|
||||||
|
|
||||||
|
var vmdb *statedb.StateDB
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
tx sdk.Tx
|
tx sdk.Tx
|
||||||
|
gasLimit uint64
|
||||||
malleate func()
|
malleate func()
|
||||||
expPass bool
|
expPass bool
|
||||||
expPanic bool
|
expPanic bool
|
||||||
}{
|
}{
|
||||||
{"invalid transaction type", &invalidTx{}, func() {}, false, false},
|
{"invalid transaction type", &invalidTx{}, 0, func() {}, false, false},
|
||||||
{
|
{
|
||||||
"sender not found",
|
"sender not found",
|
||||||
evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil),
|
evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
|
||||||
|
0,
|
||||||
func() {},
|
func() {},
|
||||||
false, false,
|
false, false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"gas limit too low",
|
"gas limit too low",
|
||||||
tx,
|
tx,
|
||||||
func() {
|
0,
|
||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
func() {},
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
|
||||||
},
|
|
||||||
false, false,
|
false, false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"not enough balance for fees",
|
"not enough balance for fees",
|
||||||
tx2,
|
tx2,
|
||||||
func() {
|
0,
|
||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
func() {},
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
|
||||||
},
|
|
||||||
false, false,
|
false, false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"not enough tx gas",
|
"not enough tx gas",
|
||||||
tx2,
|
tx2,
|
||||||
|
0,
|
||||||
func() {
|
func() {
|
||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
vmdb.AddBalance(addr, big.NewInt(1000000))
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
|
||||||
|
|
||||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt(1000000))
|
|
||||||
},
|
},
|
||||||
false, true,
|
false, true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"not enough block gas",
|
"not enough block gas",
|
||||||
tx2,
|
tx2,
|
||||||
|
0,
|
||||||
func() {
|
func() {
|
||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
vmdb.AddBalance(addr, big.NewInt(1000000))
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
|
||||||
|
|
||||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt(1000000))
|
|
||||||
|
|
||||||
suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(1))
|
suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(1))
|
||||||
},
|
},
|
||||||
@@ -266,11 +269,9 @@ func (suite AnteTestSuite) TestEthGasConsumeDecorator() {
|
|||||||
{
|
{
|
||||||
"success",
|
"success",
|
||||||
tx2,
|
tx2,
|
||||||
|
config.DefaultMaxTxGasWanted, // it's capped
|
||||||
func() {
|
func() {
|
||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
vmdb.AddBalance(addr, big.NewInt(1000000))
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
|
||||||
|
|
||||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt(1000000))
|
|
||||||
|
|
||||||
suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(10000000000000000000))
|
suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(10000000000000000000))
|
||||||
},
|
},
|
||||||
@@ -280,7 +281,9 @@ func (suite AnteTestSuite) TestEthGasConsumeDecorator() {
|
|||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
suite.Run(tc.name, func() {
|
suite.Run(tc.name, func() {
|
||||||
|
vmdb = suite.StateDB()
|
||||||
tc.malleate()
|
tc.malleate()
|
||||||
|
suite.Require().NoError(vmdb.Commit())
|
||||||
|
|
||||||
if tc.expPanic {
|
if tc.expPanic {
|
||||||
suite.Require().Panics(func() {
|
suite.Require().Panics(func() {
|
||||||
@@ -289,12 +292,14 @@ func (suite AnteTestSuite) TestEthGasConsumeDecorator() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(true), tc.tx, false, nextFn)
|
_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(true).WithGasMeter(sdk.NewInfiniteGasMeter()), tc.tx, false, nextFn)
|
||||||
if tc.expPass {
|
if tc.expPass {
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
} else {
|
} else {
|
||||||
suite.Require().Error(err)
|
suite.Require().Error(err)
|
||||||
}
|
}
|
||||||
|
// TODO: needs to check the gasmeter limit issue
|
||||||
|
// suite.Require().Equal(tc.gasLimit, ctx.GasMeter().Limit())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,14 +309,38 @@ func (suite AnteTestSuite) TestCanTransferDecorator() {
|
|||||||
|
|
||||||
addr, privKey := tests.NewAddrKey()
|
addr, privKey := tests.NewAddrKey()
|
||||||
|
|
||||||
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, ðtypes.AccessList{})
|
suite.app.FeeMarketKeeper.SetBaseFee(suite.ctx, big.NewInt(100))
|
||||||
tx2 := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, ðtypes.AccessList{})
|
|
||||||
|
tx := evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
big.NewInt(10),
|
||||||
|
1000,
|
||||||
|
big.NewInt(150),
|
||||||
|
big.NewInt(200),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
ðtypes.AccessList{},
|
||||||
|
)
|
||||||
|
tx2 := evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
big.NewInt(10),
|
||||||
|
1000,
|
||||||
|
big.NewInt(150),
|
||||||
|
big.NewInt(200),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
ðtypes.AccessList{},
|
||||||
|
)
|
||||||
|
|
||||||
tx.From = addr.Hex()
|
tx.From = addr.Hex()
|
||||||
|
|
||||||
err := tx.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
err := tx.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
var vmdb *statedb.StateDB
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
tx sdk.Tx
|
tx sdk.Tx
|
||||||
@@ -336,7 +365,7 @@ func (suite AnteTestSuite) TestCanTransferDecorator() {
|
|||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
||||||
|
|
||||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt(1000000))
|
vmdb.AddBalance(addr, big.NewInt(1000000))
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
@@ -344,7 +373,9 @@ func (suite AnteTestSuite) TestCanTransferDecorator() {
|
|||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
suite.Run(tc.name, func() {
|
suite.Run(tc.name, func() {
|
||||||
|
vmdb = suite.StateDB()
|
||||||
tc.malleate()
|
tc.malleate()
|
||||||
|
suite.Require().NoError(vmdb.Commit())
|
||||||
|
|
||||||
_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(true), tc.tx, false, nextFn)
|
_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(true), tc.tx, false, nextFn)
|
||||||
|
|
||||||
@@ -357,82 +388,26 @@ func (suite AnteTestSuite) TestCanTransferDecorator() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite AnteTestSuite) TestAccessListDecorator() {
|
|
||||||
dec := ante.NewAccessListDecorator(suite.app.EvmKeeper)
|
|
||||||
|
|
||||||
addr := tests.GenerateAddress()
|
|
||||||
al := ðtypes.AccessList{
|
|
||||||
{Address: addr, StorageKeys: []common.Hash{{}}},
|
|
||||||
}
|
|
||||||
|
|
||||||
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil)
|
|
||||||
tx2 := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, al)
|
|
||||||
|
|
||||||
tx.From = addr.Hex()
|
|
||||||
tx2.From = addr.Hex()
|
|
||||||
|
|
||||||
testCases := []struct {
|
|
||||||
name string
|
|
||||||
tx sdk.Tx
|
|
||||||
malleate func()
|
|
||||||
expPass bool
|
|
||||||
}{
|
|
||||||
{"invalid transaction type", &invalidTx{}, func() {}, false},
|
|
||||||
{
|
|
||||||
"success - no access list",
|
|
||||||
tx,
|
|
||||||
func() {
|
|
||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
|
||||||
|
|
||||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt(1000000))
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"success - with access list",
|
|
||||||
tx2,
|
|
||||||
func() {
|
|
||||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
|
||||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
|
||||||
|
|
||||||
suite.app.EvmKeeper.AddBalance(addr, big.NewInt(1000000))
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
|
||||||
suite.Run(tc.name, func() {
|
|
||||||
tc.malleate()
|
|
||||||
_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(true), tc.tx, false, nextFn)
|
|
||||||
|
|
||||||
if tc.expPass {
|
|
||||||
suite.Require().NoError(err)
|
|
||||||
} else {
|
|
||||||
suite.Require().Error(err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
|
func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
|
||||||
dec := ante.NewEthIncrementSenderSequenceDecorator(suite.app.AccountKeeper)
|
dec := ante.NewEthIncrementSenderSequenceDecorator(suite.app.AccountKeeper)
|
||||||
addr, privKey := tests.NewAddrKey()
|
addr, privKey := tests.NewAddrKey()
|
||||||
|
|
||||||
contract := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 0, big.NewInt(10), 1000, big.NewInt(1), nil, nil)
|
contract := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 0, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
contract.From = addr.Hex()
|
contract.From = addr.Hex()
|
||||||
|
|
||||||
to := tests.GenerateAddress()
|
|
||||||
tx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 0, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil)
|
|
||||||
tx.From = addr.Hex()
|
|
||||||
|
|
||||||
err := contract.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
err := contract.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
to := tests.GenerateAddress()
|
||||||
|
tx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 0, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
tx.From = addr.Hex()
|
||||||
err = tx.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
err = tx.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
tx2 := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
tx2.From = addr.Hex()
|
||||||
|
err = tx2.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
tx sdk.Tx
|
tx sdk.Tx
|
||||||
@@ -448,9 +423,9 @@ func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"no signers",
|
"no signers",
|
||||||
evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil),
|
evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
|
||||||
func() {},
|
func() {},
|
||||||
false, true,
|
false, false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"account not set to store",
|
"account not set to store",
|
||||||
@@ -469,7 +444,7 @@ func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"success - call",
|
"success - call",
|
||||||
tx,
|
tx2,
|
||||||
func() {},
|
func() {},
|
||||||
true, false,
|
true, false,
|
||||||
},
|
},
|
||||||
@@ -495,12 +470,8 @@ func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
|
|||||||
txData, err := evmtypes.UnpackTxData(msg.Data)
|
txData, err := evmtypes.UnpackTxData(msg.Data)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
nonce := suite.app.EvmKeeper.GetNonce(addr)
|
nonce := suite.app.EvmKeeper.GetNonce(suite.ctx, addr)
|
||||||
if txData.GetTo() == nil {
|
suite.Require().Equal(txData.GetNonce()+1, nonce)
|
||||||
suite.Require().Equal(txData.GetNonce(), nonce)
|
|
||||||
} else {
|
|
||||||
suite.Require().Equal(txData.GetNonce()+1, nonce)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
suite.Require().Error(err)
|
suite.Require().Error(err)
|
||||||
}
|
}
|
||||||
@@ -509,8 +480,8 @@ func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite AnteTestSuite) TestEthSetupContextDecorator() {
|
func (suite AnteTestSuite) TestEthSetupContextDecorator() {
|
||||||
dec := ante.NewEthSetUpContextDecorator()
|
dec := ante.NewEthSetUpContextDecorator(suite.app.EvmKeeper)
|
||||||
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil)
|
tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package ante
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||||
|
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||||
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
|
|
||||||
|
ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante"
|
||||||
|
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
|
||||||
|
|
||||||
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC
|
||||||
|
// channel keeper, EVM Keeper and Fee Market Keeper.
|
||||||
|
type HandlerOptions struct {
|
||||||
|
AccountKeeper evmtypes.AccountKeeper
|
||||||
|
BankKeeper evmtypes.BankKeeper
|
||||||
|
IBCKeeper *ibckeeper.Keeper
|
||||||
|
FeeMarketKeeper evmtypes.FeeMarketKeeper
|
||||||
|
EvmKeeper EVMKeeper
|
||||||
|
FeegrantKeeper ante.FeegrantKeeper
|
||||||
|
SignModeHandler authsigning.SignModeHandler
|
||||||
|
SigGasConsumer func(meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params) error
|
||||||
|
MaxTxGasWanted uint64
|
||||||
|
TxFeeChecker ante.TxFeeChecker
|
||||||
|
}
|
||||||
|
|
||||||
|
func (options HandlerOptions) Validate() error {
|
||||||
|
if options.AccountKeeper == nil {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler")
|
||||||
|
}
|
||||||
|
if options.BankKeeper == nil {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler")
|
||||||
|
}
|
||||||
|
if options.SignModeHandler == nil {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder")
|
||||||
|
}
|
||||||
|
if options.FeeMarketKeeper == nil {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrLogic, "fee market keeper is required for AnteHandler")
|
||||||
|
}
|
||||||
|
if options.EvmKeeper == nil {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrLogic, "evm keeper is required for AnteHandler")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newEthAnteHandler(options HandlerOptions) sdk.AnteHandler {
|
||||||
|
return sdk.ChainAnteDecorators(
|
||||||
|
NewEthSetUpContextDecorator(options.EvmKeeper), // outermost AnteDecorator. SetUpContext must be called first
|
||||||
|
NewEthMempoolFeeDecorator(options.EvmKeeper), // Check eth effective gas price against minimal-gas-prices
|
||||||
|
NewEthValidateBasicDecorator(options.EvmKeeper),
|
||||||
|
NewEthSigVerificationDecorator(options.EvmKeeper),
|
||||||
|
NewEthAccountVerificationDecorator(options.AccountKeeper, options.BankKeeper, options.EvmKeeper),
|
||||||
|
NewEthGasConsumeDecorator(options.EvmKeeper, options.MaxTxGasWanted),
|
||||||
|
NewCanTransferDecorator(options.EvmKeeper),
|
||||||
|
NewEthIncrementSenderSequenceDecorator(options.AccountKeeper), // innermost AnteDecorator.
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCosmosAnteHandler(options HandlerOptions) sdk.AnteHandler {
|
||||||
|
return sdk.ChainAnteDecorators(
|
||||||
|
RejectMessagesDecorator{}, // reject MsgEthereumTxs
|
||||||
|
ante.NewSetUpContextDecorator(),
|
||||||
|
ante.NewValidateBasicDecorator(),
|
||||||
|
ante.NewTxTimeoutHeightDecorator(),
|
||||||
|
ante.NewValidateMemoDecorator(options.AccountKeeper),
|
||||||
|
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
|
||||||
|
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
|
||||||
|
// SetPubKeyDecorator must be called before all signature verification decorators
|
||||||
|
ante.NewSetPubKeyDecorator(options.AccountKeeper),
|
||||||
|
ante.NewValidateSigCountDecorator(options.AccountKeeper),
|
||||||
|
ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer),
|
||||||
|
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
|
||||||
|
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
|
||||||
|
ibcante.NewAnteDecorator(options.IBCKeeper),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCosmosAnteHandlerEip712(options HandlerOptions) sdk.AnteHandler {
|
||||||
|
return sdk.ChainAnteDecorators(
|
||||||
|
RejectMessagesDecorator{}, // reject MsgEthereumTxs
|
||||||
|
ante.NewSetUpContextDecorator(),
|
||||||
|
// NOTE: extensions option decorator removed
|
||||||
|
// ante.NewRejectExtensionOptionsDecorator(),
|
||||||
|
ante.NewValidateBasicDecorator(),
|
||||||
|
ante.NewTxTimeoutHeightDecorator(),
|
||||||
|
ante.NewValidateMemoDecorator(options.AccountKeeper),
|
||||||
|
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
|
||||||
|
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
|
||||||
|
// SetPubKeyDecorator must be called before all signature verification decorators
|
||||||
|
ante.NewSetPubKeyDecorator(options.AccountKeeper),
|
||||||
|
ante.NewValidateSigCountDecorator(options.AccountKeeper),
|
||||||
|
ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer),
|
||||||
|
// Note: signature verification uses EIP instead of the cosmos signature validator
|
||||||
|
NewEip712SigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
|
||||||
|
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
|
||||||
|
ibcante.NewAnteDecorator(options.IBCKeeper),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package ante
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
tx "github.com/cosmos/cosmos-sdk/types/tx"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/tharsis/ethermint/x/evm/statedb"
|
||||||
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EVMKeeper defines the expected keeper interface used on the Eth AnteHandler
|
||||||
|
type EVMKeeper interface {
|
||||||
|
statedb.Keeper
|
||||||
|
|
||||||
|
ChainID() *big.Int
|
||||||
|
GetParams(ctx sdk.Context) evmtypes.Params
|
||||||
|
NewEVM(ctx sdk.Context, msg core.Message, cfg *evmtypes.EVMConfig, tracer vm.EVMLogger, stateDB vm.StateDB) *vm.EVM
|
||||||
|
DeductTxCostsFromUserBalance(
|
||||||
|
ctx sdk.Context, msgEthTx evmtypes.MsgEthereumTx, txData evmtypes.TxData, denom string, homestead, istanbul, london bool,
|
||||||
|
) (sdk.Coins, error)
|
||||||
|
BaseFee(ctx sdk.Context, ethCfg *params.ChainConfig) *big.Int
|
||||||
|
GetBalance(ctx sdk.Context, addr common.Address) *big.Int
|
||||||
|
ResetTransientGasUsed(ctx sdk.Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
type protoTxProvider interface {
|
||||||
|
GetProtoTx() *tx.Tx
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package ante
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RejectMessagesDecorator prevents invalid msg types from being executed
|
||||||
|
type RejectMessagesDecorator struct{}
|
||||||
|
|
||||||
|
// AnteHandle rejects messages that requires ethereum-specific authentication.
|
||||||
|
// For example `MsgEthereumTx` requires fee to be deducted in the antehandler in
|
||||||
|
// order to perform the refund.
|
||||||
|
func (rmd RejectMessagesDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||||
|
for _, msg := range tx.GetMsgs() {
|
||||||
|
if _, ok := msg.(*evmtypes.MsgEthereumTx); ok {
|
||||||
|
return ctx, sdkerrors.Wrapf(
|
||||||
|
sdkerrors.ErrInvalidType,
|
||||||
|
"MsgEthereumTx needs to be contained within a tx with 'ExtensionOptionsEthereumTx' option",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return next(ctx, tx, simulate)
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package ante_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/tharsis/ethermint/tests"
|
||||||
|
"github.com/tharsis/ethermint/x/evm/statedb"
|
||||||
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (suite AnteTestSuite) TestSignatures() {
|
||||||
|
suite.enableFeemarket = false
|
||||||
|
suite.SetupTest() // reset
|
||||||
|
|
||||||
|
addr, privKey := tests.NewAddrKey()
|
||||||
|
to := tests.GenerateAddress()
|
||||||
|
|
||||||
|
acc := statedb.NewEmptyAccount()
|
||||||
|
acc.Nonce = 1
|
||||||
|
acc.Balance = big.NewInt(10000000000)
|
||||||
|
|
||||||
|
suite.app.EvmKeeper.SetAccount(suite.ctx, addr, *acc)
|
||||||
|
msgEthereumTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
msgEthereumTx.From = addr.Hex()
|
||||||
|
|
||||||
|
// CreateTestTx will sign the msgEthereumTx but not sign the cosmos tx since we have signCosmosTx as false
|
||||||
|
tx := suite.CreateTestTx(msgEthereumTx, privKey, 1, false)
|
||||||
|
sigs, err := tx.GetSignaturesV2()
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
// signatures of cosmos tx should be empty
|
||||||
|
suite.Require().Equal(len(sigs), 0)
|
||||||
|
|
||||||
|
txData, err := evmtypes.UnpackTxData(msgEthereumTx.Data)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
msgV, msgR, msgS := txData.GetRawSignatureValues()
|
||||||
|
|
||||||
|
ethTx := msgEthereumTx.AsTransaction()
|
||||||
|
ethV, ethR, ethS := ethTx.RawSignatureValues()
|
||||||
|
|
||||||
|
// The signatures of MsgehtereumTx should be the same with the corresponding eth tx
|
||||||
|
suite.Require().Equal(msgV, ethV)
|
||||||
|
suite.Require().Equal(msgR, ethR)
|
||||||
|
suite.Require().Equal(msgS, ethS)
|
||||||
|
}
|
||||||
+157
-12
@@ -1,9 +1,19 @@
|
|||||||
package ante_test
|
package ante_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||||
|
types2 "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
|
types3 "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/tharsis/ethermint/ethereum/eip712"
|
||||||
|
"github.com/tharsis/ethermint/types"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
@@ -12,6 +22,7 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
@@ -23,7 +34,9 @@ import (
|
|||||||
ante "github.com/tharsis/ethermint/app/ante"
|
ante "github.com/tharsis/ethermint/app/ante"
|
||||||
"github.com/tharsis/ethermint/encoding"
|
"github.com/tharsis/ethermint/encoding"
|
||||||
"github.com/tharsis/ethermint/tests"
|
"github.com/tharsis/ethermint/tests"
|
||||||
|
"github.com/tharsis/ethermint/x/evm/statedb"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
||||||
|
|
||||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||||
)
|
)
|
||||||
@@ -31,16 +44,44 @@ import (
|
|||||||
type AnteTestSuite struct {
|
type AnteTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
|
|
||||||
ctx sdk.Context
|
ctx sdk.Context
|
||||||
app *app.EthermintApp
|
app *app.EthermintApp
|
||||||
clientCtx client.Context
|
clientCtx client.Context
|
||||||
anteHandler sdk.AnteHandler
|
anteHandler sdk.AnteHandler
|
||||||
ethSigner ethtypes.Signer
|
ethSigner ethtypes.Signer
|
||||||
|
enableFeemarket bool
|
||||||
|
enableLondonHF bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *AnteTestSuite) StateDB() *statedb.StateDB {
|
||||||
|
return statedb.New(suite.ctx, suite.app.EvmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(suite.ctx.HeaderHash().Bytes())))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *AnteTestSuite) SetupTest() {
|
func (suite *AnteTestSuite) SetupTest() {
|
||||||
checkTx := false
|
checkTx := false
|
||||||
suite.app = app.Setup(checkTx)
|
|
||||||
|
suite.app = app.Setup(suite.T(), checkTx, func(app *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||||
|
if suite.enableFeemarket {
|
||||||
|
// setup feemarketGenesis params
|
||||||
|
feemarketGenesis := feemarkettypes.DefaultGenesisState()
|
||||||
|
feemarketGenesis.Params.EnableHeight = 1
|
||||||
|
feemarketGenesis.Params.NoBaseFee = false
|
||||||
|
// Verify feeMarket genesis
|
||||||
|
err := feemarketGenesis.Validate()
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
genesis[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
|
||||||
|
}
|
||||||
|
if !suite.enableLondonHF {
|
||||||
|
evmGenesis := evmtypes.DefaultGenesisState()
|
||||||
|
maxInt := sdk.NewInt(math.MaxInt64)
|
||||||
|
evmGenesis.Params.ChainConfig.LondonBlock = &maxInt
|
||||||
|
evmGenesis.Params.ChainConfig.ArrowGlacierBlock = &maxInt
|
||||||
|
evmGenesis.Params.ChainConfig.MergeForkBlock = &maxInt
|
||||||
|
genesis[evmtypes.ModuleName] = app.AppCodec().MustMarshalJSON(evmGenesis)
|
||||||
|
}
|
||||||
|
return genesis
|
||||||
|
})
|
||||||
|
|
||||||
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 2, ChainID: "ethermint_9000-1", Time: time.Now().UTC()})
|
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 2, ChainID: "ethermint_9000-1", Time: time.Now().UTC()})
|
||||||
suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins(sdk.NewDecCoin(evmtypes.DefaultEVMDenom, sdk.OneInt())))
|
suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins(sdk.NewDecCoin(evmtypes.DefaultEVMDenom, sdk.OneInt())))
|
||||||
suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(1000000000000000000))
|
suite.ctx = suite.ctx.WithBlockGasMeter(sdk.NewGasMeter(1000000000000000000))
|
||||||
@@ -48,7 +89,6 @@ func (suite *AnteTestSuite) SetupTest() {
|
|||||||
|
|
||||||
infCtx := suite.ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
infCtx := suite.ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
suite.app.AccountKeeper.SetParams(infCtx, authtypes.DefaultParams())
|
suite.app.AccountKeeper.SetParams(infCtx, authtypes.DefaultParams())
|
||||||
suite.app.EvmKeeper.SetParams(infCtx, evmtypes.DefaultParams())
|
|
||||||
|
|
||||||
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
|
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
|
||||||
// We're using TestMsg amino encoding in some tests, so register it here.
|
// We're using TestMsg amino encoding in some tests, so register it here.
|
||||||
@@ -56,17 +96,33 @@ func (suite *AnteTestSuite) SetupTest() {
|
|||||||
|
|
||||||
suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig)
|
suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig)
|
||||||
|
|
||||||
suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.EvmKeeper, suite.app.FeeGrantKeeper, suite.app.IBCKeeper.ChannelKeeper, encodingConfig.TxConfig.SignModeHandler())
|
options := ante.HandlerOptions{
|
||||||
|
AccountKeeper: suite.app.AccountKeeper,
|
||||||
|
BankKeeper: suite.app.BankKeeper,
|
||||||
|
EvmKeeper: suite.app.EvmKeeper,
|
||||||
|
FeegrantKeeper: suite.app.FeeGrantKeeper,
|
||||||
|
IBCKeeper: suite.app.IBCKeeper,
|
||||||
|
FeeMarketKeeper: suite.app.FeeMarketKeeper,
|
||||||
|
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
|
||||||
|
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
|
||||||
|
}
|
||||||
|
|
||||||
|
suite.Require().NoError(options.Validate())
|
||||||
|
|
||||||
|
suite.anteHandler = ante.NewAnteHandler(options)
|
||||||
suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
|
suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAnteTestSuite(t *testing.T) {
|
func TestAnteTestSuite(t *testing.T) {
|
||||||
suite.Run(t, new(AnteTestSuite))
|
suite.Run(t, &AnteTestSuite{
|
||||||
|
enableLondonHF: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateTestTx is a helper function to create a tx given multiple inputs.
|
// CreateTestTx is a helper function to create a tx given multiple inputs.
|
||||||
func (suite *AnteTestSuite) CreateTestTx(
|
func (suite *AnteTestSuite) CreateTestTx(
|
||||||
msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey, accNum uint64, signCosmosTx bool,
|
msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey, accNum uint64, signCosmosTx bool,
|
||||||
|
unsetExtensionOptions ...bool,
|
||||||
) authsigning.Tx {
|
) authsigning.Tx {
|
||||||
return suite.CreateTestTxBuilder(msg, priv, accNum, signCosmosTx).GetTx()
|
return suite.CreateTestTxBuilder(msg, priv, accNum, signCosmosTx).GetTx()
|
||||||
}
|
}
|
||||||
@@ -74,15 +130,22 @@ func (suite *AnteTestSuite) CreateTestTx(
|
|||||||
// CreateTestTxBuilder is a helper function to create a tx builder given multiple inputs.
|
// CreateTestTxBuilder is a helper function to create a tx builder given multiple inputs.
|
||||||
func (suite *AnteTestSuite) CreateTestTxBuilder(
|
func (suite *AnteTestSuite) CreateTestTxBuilder(
|
||||||
msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey, accNum uint64, signCosmosTx bool,
|
msg *evmtypes.MsgEthereumTx, priv cryptotypes.PrivKey, accNum uint64, signCosmosTx bool,
|
||||||
|
unsetExtensionOptions ...bool,
|
||||||
) client.TxBuilder {
|
) client.TxBuilder {
|
||||||
option, err := codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{})
|
var option *codectypes.Any
|
||||||
suite.Require().NoError(err)
|
var err error
|
||||||
|
if len(unsetExtensionOptions) == 0 {
|
||||||
|
option, err = codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{})
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
txBuilder := suite.clientCtx.TxConfig.NewTxBuilder()
|
txBuilder := suite.clientCtx.TxConfig.NewTxBuilder()
|
||||||
builder, ok := txBuilder.(authtx.ExtensionOptionsTxBuilder)
|
builder, ok := txBuilder.(authtx.ExtensionOptionsTxBuilder)
|
||||||
suite.Require().True(ok)
|
suite.Require().True(ok)
|
||||||
|
|
||||||
builder.SetExtensionOptions(option)
|
if len(unsetExtensionOptions) == 0 {
|
||||||
|
builder.SetExtensionOptions(option)
|
||||||
|
}
|
||||||
|
|
||||||
err = msg.Sign(suite.ethSigner, tests.NewSigner(priv))
|
err = msg.Sign(suite.ethSigner, tests.NewSigner(priv))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
@@ -136,6 +199,88 @@ func (suite *AnteTestSuite) CreateTestTxBuilder(
|
|||||||
return txBuilder
|
return txBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *AnteTestSuite) CreateTestEIP712TxBuilderMsgSend(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
|
||||||
|
// Build MsgSend
|
||||||
|
recipient := sdk.AccAddress(common.Address{}.Bytes())
|
||||||
|
msgSend := types2.NewMsgSend(from, recipient, sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(1))))
|
||||||
|
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgSend)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *AnteTestSuite) CreateTestEIP712TxBuilderMsgDelegate(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
|
||||||
|
// Build MsgSend
|
||||||
|
valEthAddr := tests.GenerateAddress()
|
||||||
|
valAddr := sdk.ValAddress(valEthAddr.Bytes())
|
||||||
|
msgSend := types3.NewMsgDelegate(from, valAddr, sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)))
|
||||||
|
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgSend)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *AnteTestSuite) CreateTestEIP712CosmosTxBuilder(
|
||||||
|
from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins, msg sdk.Msg,
|
||||||
|
) client.TxBuilder {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, from)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
pc, err := types.ParseChainID(chainId)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
ethChainId := pc.Uint64()
|
||||||
|
|
||||||
|
// GenerateTypedData TypedData
|
||||||
|
var ethermintCodec codec.ProtoCodecMarshaler
|
||||||
|
fee := legacytx.NewStdFee(gas, gasAmount)
|
||||||
|
accNumber := suite.app.AccountKeeper.GetAccount(suite.ctx, from).GetAccountNumber()
|
||||||
|
|
||||||
|
data := legacytx.StdSignBytes(chainId, accNumber, nonce, 0, fee, []sdk.Msg{msg}, "", nil)
|
||||||
|
typedData, err := eip712.WrapTxToTypedData(ethermintCodec, ethChainId, msg, data, &eip712.FeeDelegationOptions{
|
||||||
|
FeePayer: from,
|
||||||
|
})
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
sigHash, err := eip712.ComputeTypedDataHash(typedData)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
// Sign typedData
|
||||||
|
keyringSigner := tests.NewSigner(priv)
|
||||||
|
signature, pubKey, err := keyringSigner.SignByAddress(from, sigHash)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
|
||||||
|
|
||||||
|
// Add ExtensionOptionsWeb3Tx extension
|
||||||
|
var option *codectypes.Any
|
||||||
|
option, err = codectypes.NewAnyWithValue(&types.ExtensionOptionsWeb3Tx{
|
||||||
|
FeePayer: from.String(),
|
||||||
|
TypedDataChainID: ethChainId,
|
||||||
|
FeePayerSig: signature,
|
||||||
|
})
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
suite.clientCtx.TxConfig.SignModeHandler()
|
||||||
|
txBuilder := suite.clientCtx.TxConfig.NewTxBuilder()
|
||||||
|
builder, ok := txBuilder.(authtx.ExtensionOptionsTxBuilder)
|
||||||
|
suite.Require().True(ok)
|
||||||
|
|
||||||
|
builder.SetExtensionOptions(option)
|
||||||
|
builder.SetFeeAmount(gasAmount)
|
||||||
|
builder.SetGasLimit(gas)
|
||||||
|
|
||||||
|
sigsV2 := signing.SignatureV2{
|
||||||
|
PubKey: pubKey,
|
||||||
|
Data: &signing.SingleSignatureData{
|
||||||
|
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||||
|
},
|
||||||
|
Sequence: nonce,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = builder.SetSignatures(sigsV2)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
err = builder.SetMsgs(msg)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
return builder
|
||||||
|
}
|
||||||
|
|
||||||
var _ sdk.Tx = &invalidTx{}
|
var _ sdk.Tx = &invalidTx{}
|
||||||
|
|
||||||
type invalidTx struct{}
|
type invalidTx struct{}
|
||||||
|
|||||||
+300
-112
@@ -11,22 +11,24 @@ import (
|
|||||||
"github.com/rakyll/statik/fs"
|
"github.com/rakyll/statik/fs"
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
|
||||||
tmos "github.com/tendermint/tendermint/libs/os"
|
|
||||||
dbm "github.com/tendermint/tm-db"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
|
"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"
|
||||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/db"
|
||||||
"github.com/cosmos/cosmos-sdk/server/api"
|
"github.com/cosmos/cosmos-sdk/server/api"
|
||||||
"github.com/cosmos/cosmos-sdk/server/config"
|
"github.com/cosmos/cosmos-sdk/server/config"
|
||||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||||
"github.com/cosmos/cosmos-sdk/simapp"
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
|
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
|
||||||
|
"github.com/tharsis/ethermint/app/ante"
|
||||||
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
|
||||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||||
|
"github.com/cosmos/cosmos-sdk/store/streaming"
|
||||||
|
storetypes "github.com/cosmos/cosmos-sdk/store/v2alpha1"
|
||||||
|
"github.com/cosmos/cosmos-sdk/store/v2alpha1/multi"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/module"
|
"github.com/cosmos/cosmos-sdk/types/module"
|
||||||
"github.com/cosmos/cosmos-sdk/version"
|
"github.com/cosmos/cosmos-sdk/version"
|
||||||
@@ -36,6 +38,7 @@ import (
|
|||||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
|
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
|
||||||
|
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||||
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||||
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
|
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
|
||||||
@@ -61,8 +64,10 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||||
|
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
|
||||||
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
||||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||||
|
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
||||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||||
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
|
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
|
||||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||||
@@ -82,29 +87,46 @@ import (
|
|||||||
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
|
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
|
||||||
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||||
|
|
||||||
"github.com/cosmos/ibc-go/modules/apps/transfer"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
ibctransferkeeper "github.com/cosmos/ibc-go/modules/apps/transfer/keeper"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
ibctransfertypes "github.com/cosmos/ibc-go/modules/apps/transfer/types"
|
tmos "github.com/tendermint/tendermint/libs/os"
|
||||||
ibc "github.com/cosmos/ibc-go/modules/core"
|
|
||||||
ibcclient "github.com/cosmos/ibc-go/modules/core/02-client"
|
"github.com/cosmos/ibc-go/v3/modules/apps/transfer"
|
||||||
ibcclientclient "github.com/cosmos/ibc-go/modules/core/02-client/client"
|
ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper"
|
||||||
porttypes "github.com/cosmos/ibc-go/modules/core/05-port/types"
|
ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
|
||||||
ibchost "github.com/cosmos/ibc-go/modules/core/24-host"
|
ibc "github.com/cosmos/ibc-go/v3/modules/core"
|
||||||
ibckeeper "github.com/cosmos/ibc-go/modules/core/keeper"
|
ibcclient "github.com/cosmos/ibc-go/v3/modules/core/02-client"
|
||||||
|
ibcclientclient "github.com/cosmos/ibc-go/v3/modules/core/02-client/client"
|
||||||
|
porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types"
|
||||||
|
ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host"
|
||||||
|
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
|
||||||
|
|
||||||
// unnamed import of statik for swagger UI support
|
// unnamed import of statik for swagger UI support
|
||||||
_ "github.com/tharsis/ethermint/client/docs/statik"
|
_ "github.com/tharsis/ethermint/client/docs/statik"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/app/ante"
|
|
||||||
srvflags "github.com/tharsis/ethermint/server/flags"
|
srvflags "github.com/tharsis/ethermint/server/flags"
|
||||||
ethermint "github.com/tharsis/ethermint/types"
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
"github.com/tharsis/ethermint/x/evm"
|
"github.com/tharsis/ethermint/x/evm"
|
||||||
evmrest "github.com/tharsis/ethermint/x/evm/client/rest"
|
|
||||||
|
// evmrest "github.com/tharsis/ethermint/x/evm/client/rest"
|
||||||
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
|
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
|
||||||
"github.com/tharsis/ethermint/x/feemarket"
|
"github.com/tharsis/ethermint/x/feemarket"
|
||||||
feemarketkeeper "github.com/tharsis/ethermint/x/feemarket/keeper"
|
feemarketkeeper "github.com/tharsis/ethermint/x/feemarket/keeper"
|
||||||
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
||||||
|
|
||||||
|
// Force-load the tracer engines to trigger registration due to Go-Ethereum v1.10.15 changes
|
||||||
|
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
|
||||||
|
_ "github.com/ethereum/go-ethereum/eth/tracers/native"
|
||||||
|
|
||||||
|
"github.com/tharsis/ethermint/x/auction"
|
||||||
|
auctionkeeper "github.com/tharsis/ethermint/x/auction/keeper"
|
||||||
|
auctiontypes "github.com/tharsis/ethermint/x/auction/types"
|
||||||
|
"github.com/tharsis/ethermint/x/bond"
|
||||||
|
bondkeeper "github.com/tharsis/ethermint/x/bond/keeper"
|
||||||
|
bondtypes "github.com/tharsis/ethermint/x/bond/types"
|
||||||
|
"github.com/tharsis/ethermint/x/nameservice"
|
||||||
|
nameservicekeeper "github.com/tharsis/ethermint/x/nameservice/keeper"
|
||||||
|
nameservicetypes "github.com/tharsis/ethermint/x/nameservice/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -113,10 +135,10 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultNodeHome = filepath.Join(userHomeDir, ".ethermintd")
|
DefaultNodeHome = filepath.Join(userHomeDir, ".chibaclonkd")
|
||||||
}
|
}
|
||||||
|
|
||||||
const appName = "ethermintd"
|
const appName = "chibaclonkd"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// DefaultNodeHome default home directories for the application daemon
|
// DefaultNodeHome default home directories for the application daemon
|
||||||
@@ -134,8 +156,8 @@ var (
|
|||||||
mint.AppModuleBasic{},
|
mint.AppModuleBasic{},
|
||||||
distr.AppModuleBasic{},
|
distr.AppModuleBasic{},
|
||||||
gov.NewAppModuleBasic(
|
gov.NewAppModuleBasic(
|
||||||
paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler,
|
[]govclient.ProposalHandler{paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.LegacyProposalHandler, upgradeclient.LegacyCancelProposalHandler,
|
||||||
ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler,
|
ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler},
|
||||||
),
|
),
|
||||||
params.AppModuleBasic{},
|
params.AppModuleBasic{},
|
||||||
crisis.AppModuleBasic{},
|
crisis.AppModuleBasic{},
|
||||||
@@ -150,18 +172,28 @@ var (
|
|||||||
// Ethermint modules
|
// Ethermint modules
|
||||||
evm.AppModuleBasic{},
|
evm.AppModuleBasic{},
|
||||||
feemarket.AppModuleBasic{},
|
feemarket.AppModuleBasic{},
|
||||||
|
// Vulcanize chiba-clonk modules
|
||||||
|
auction.AppModuleBasic{},
|
||||||
|
bond.AppModuleBasic{},
|
||||||
|
nameservice.AppModuleBasic{},
|
||||||
)
|
)
|
||||||
|
|
||||||
// module account permissions
|
// module account permissions
|
||||||
maccPerms = map[string][]string{
|
maccPerms = map[string][]string{
|
||||||
authtypes.FeeCollectorName: nil,
|
authtypes.FeeCollectorName: nil,
|
||||||
distrtypes.ModuleName: nil,
|
distrtypes.ModuleName: nil,
|
||||||
minttypes.ModuleName: {authtypes.Minter},
|
minttypes.ModuleName: {authtypes.Minter},
|
||||||
stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
|
stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
|
||||||
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
|
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
|
||||||
govtypes.ModuleName: {authtypes.Burner},
|
govtypes.ModuleName: {authtypes.Burner},
|
||||||
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
|
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
|
||||||
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
|
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
|
||||||
|
auctiontypes.ModuleName: nil,
|
||||||
|
auctiontypes.AuctionBurnModuleAccountName: nil,
|
||||||
|
nameservicetypes.ModuleName: nil,
|
||||||
|
nameservicetypes.RecordRentModuleAccountName: nil,
|
||||||
|
nameservicetypes.AuthorityRentModuleAccountName: nil,
|
||||||
|
bondtypes.ModuleName: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
// module accounts that are allowed to receive tokens
|
// module accounts that are allowed to receive tokens
|
||||||
@@ -184,13 +216,12 @@ type EthermintApp struct {
|
|||||||
cdc *codec.LegacyAmino
|
cdc *codec.LegacyAmino
|
||||||
appCodec codec.Codec
|
appCodec codec.Codec
|
||||||
interfaceRegistry types.InterfaceRegistry
|
interfaceRegistry types.InterfaceRegistry
|
||||||
|
invCheckPeriod uint
|
||||||
invCheckPeriod uint
|
|
||||||
|
|
||||||
// keys to access the substores
|
// keys to access the substores
|
||||||
keys map[string]*sdk.KVStoreKey
|
keys map[string]*storetypes.KVStoreKey
|
||||||
tkeys map[string]*sdk.TransientStoreKey
|
tkeys map[string]*storetypes.TransientStoreKey
|
||||||
memKeys map[string]*sdk.MemoryStoreKey
|
memKeys map[string]*storetypes.MemoryStoreKey
|
||||||
|
|
||||||
// keepers
|
// keepers
|
||||||
AccountKeeper authkeeper.AccountKeeper
|
AccountKeeper authkeeper.AccountKeeper
|
||||||
@@ -218,6 +249,12 @@ type EthermintApp struct {
|
|||||||
EvmKeeper *evmkeeper.Keeper
|
EvmKeeper *evmkeeper.Keeper
|
||||||
FeeMarketKeeper feemarketkeeper.Keeper
|
FeeMarketKeeper feemarketkeeper.Keeper
|
||||||
|
|
||||||
|
// chiba-clonk keepers
|
||||||
|
AuctionKeeper auctionkeeper.Keeper
|
||||||
|
BondKeeper bondkeeper.Keeper
|
||||||
|
NameServiceKeeper nameservicekeeper.Keeper
|
||||||
|
NameServiceRecordKeeper nameservicekeeper.RecordKeeper
|
||||||
|
|
||||||
// the module manager
|
// the module manager
|
||||||
mm *module.Manager
|
mm *module.Manager
|
||||||
|
|
||||||
@@ -231,7 +268,7 @@ type EthermintApp struct {
|
|||||||
// NewEthermintApp returns a reference to a new initialized Ethermint application.
|
// NewEthermintApp returns a reference to a new initialized Ethermint application.
|
||||||
func NewEthermintApp(
|
func NewEthermintApp(
|
||||||
logger log.Logger,
|
logger log.Logger,
|
||||||
db dbm.DB,
|
db db.DBConnection,
|
||||||
traceStore io.Writer,
|
traceStore io.Writer,
|
||||||
loadLatest bool,
|
loadLatest bool,
|
||||||
skipUpgradeHeights map[int64]bool,
|
skipUpgradeHeights map[int64]bool,
|
||||||
@@ -239,12 +276,67 @@ func NewEthermintApp(
|
|||||||
invCheckPeriod uint,
|
invCheckPeriod uint,
|
||||||
encodingConfig simappparams.EncodingConfig,
|
encodingConfig simappparams.EncodingConfig,
|
||||||
appOpts servertypes.AppOptions,
|
appOpts servertypes.AppOptions,
|
||||||
baseAppOptions ...func(*baseapp.BaseApp),
|
baseAppOptions ...baseapp.AppOption,
|
||||||
) *EthermintApp {
|
) *EthermintApp {
|
||||||
appCodec := encodingConfig.Marshaler
|
appCodec := encodingConfig.Codec
|
||||||
cdc := encodingConfig.Amino
|
cdc := encodingConfig.Amino
|
||||||
interfaceRegistry := encodingConfig.InterfaceRegistry
|
interfaceRegistry := encodingConfig.InterfaceRegistry
|
||||||
|
|
||||||
|
keys := sdk.NewKVStoreKeys(
|
||||||
|
// SDK keys
|
||||||
|
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
|
||||||
|
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
|
||||||
|
govtypes.StoreKey, paramstypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
|
||||||
|
evidencetypes.StoreKey, capabilitytypes.StoreKey,
|
||||||
|
authzkeeper.StoreKey,
|
||||||
|
// ibc keys
|
||||||
|
ibchost.StoreKey, ibctransfertypes.StoreKey,
|
||||||
|
// ethermint keys
|
||||||
|
evmtypes.StoreKey, feemarkettypes.StoreKey,
|
||||||
|
// chiba-clonk keys
|
||||||
|
auctiontypes.StoreKey,
|
||||||
|
bondtypes.StoreKey,
|
||||||
|
nameservicetypes.StoreKey,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Add the EVM transient store key
|
||||||
|
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey)
|
||||||
|
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
|
||||||
|
|
||||||
|
// initialize stores
|
||||||
|
setNamespaces := func(config *multi.StoreParams, ver uint64) error {
|
||||||
|
for _, key := range keys {
|
||||||
|
typ, err := storetypes.StoreKeyToType(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = config.RegisterSubstore(key, typ); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, key := range memKeys {
|
||||||
|
typ, err := storetypes.StoreKeyToType(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = config.RegisterSubstore(key, typ); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, key := range tkeys {
|
||||||
|
typ, err := storetypes.StoreKeyToType(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = config.RegisterSubstore(key, typ); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
baseAppOptions = append(baseAppOptions, baseapp.StoreOption(setNamespaces))
|
||||||
|
|
||||||
// NOTE we use custom transaction decoder that supports the sdk.Tx interface instead of sdk.StdTx
|
// NOTE we use custom transaction decoder that supports the sdk.Tx interface instead of sdk.StdTx
|
||||||
bApp := baseapp.NewBaseApp(
|
bApp := baseapp.NewBaseApp(
|
||||||
appName,
|
appName,
|
||||||
@@ -255,24 +347,15 @@ func NewEthermintApp(
|
|||||||
)
|
)
|
||||||
bApp.SetCommitMultiStoreTracer(traceStore)
|
bApp.SetCommitMultiStoreTracer(traceStore)
|
||||||
bApp.SetVersion(version.Version)
|
bApp.SetVersion(version.Version)
|
||||||
|
|
||||||
|
evmtypes.RegisterInterfaces(interfaceRegistry)
|
||||||
bApp.SetInterfaceRegistry(interfaceRegistry)
|
bApp.SetInterfaceRegistry(interfaceRegistry)
|
||||||
|
|
||||||
keys := sdk.NewKVStoreKeys(
|
// configure state listening capabilities using AppOptions
|
||||||
// SDK keys
|
// we are doing nothing with the returned streamingServices and waitGroup in this case
|
||||||
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
|
if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, keys); err != nil {
|
||||||
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
|
tmos.Exit(err.Error())
|
||||||
govtypes.StoreKey, paramstypes.StoreKey, upgradetypes.StoreKey,
|
}
|
||||||
evidencetypes.StoreKey, capabilitytypes.StoreKey,
|
|
||||||
feegrant.StoreKey, authzkeeper.StoreKey,
|
|
||||||
// ibc keys
|
|
||||||
ibchost.StoreKey, ibctransfertypes.StoreKey,
|
|
||||||
// ethermint keys
|
|
||||||
evmtypes.StoreKey, feemarkettypes.StoreKey,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Add the EVM transient store key
|
|
||||||
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey)
|
|
||||||
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
|
|
||||||
|
|
||||||
app := &EthermintApp{
|
app := &EthermintApp{
|
||||||
BaseApp: bApp,
|
BaseApp: bApp,
|
||||||
@@ -288,7 +371,7 @@ func NewEthermintApp(
|
|||||||
// init params keeper and subspaces
|
// init params keeper and subspaces
|
||||||
app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey])
|
app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey])
|
||||||
// set the BaseApp's parameter store
|
// set the BaseApp's parameter store
|
||||||
bApp.SetParamStore(app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramskeeper.ConsensusParamsKeyTable()))
|
bApp.SetParamStore(app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramstypes.ConsensusParamsKeyTable()))
|
||||||
|
|
||||||
// add capability keeper and ScopeToModule for ibc module
|
// add capability keeper and ScopeToModule for ibc module
|
||||||
app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
|
app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
|
||||||
@@ -302,7 +385,7 @@ func NewEthermintApp(
|
|||||||
|
|
||||||
// use custom Ethermint account for contracts
|
// use custom Ethermint account for contracts
|
||||||
app.AccountKeeper = authkeeper.NewAccountKeeper(
|
app.AccountKeeper = authkeeper.NewAccountKeeper(
|
||||||
appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), ethermint.ProtoAccount, maccPerms,
|
appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), ethermint.ProtoAccount, maccPerms, sdk.Bech32MainPrefix,
|
||||||
)
|
)
|
||||||
app.BankKeeper = bankkeeper.NewBaseKeeper(
|
app.BankKeeper = bankkeeper.NewBaseKeeper(
|
||||||
appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.BlockedAddrs(),
|
appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.BlockedAddrs(),
|
||||||
@@ -316,7 +399,7 @@ func NewEthermintApp(
|
|||||||
)
|
)
|
||||||
app.DistrKeeper = distrkeeper.NewKeeper(
|
app.DistrKeeper = distrkeeper.NewKeeper(
|
||||||
appCodec, keys[distrtypes.StoreKey], app.GetSubspace(distrtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
|
appCodec, keys[distrtypes.StoreKey], app.GetSubspace(distrtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
|
||||||
&stakingKeeper, authtypes.FeeCollectorName, app.ModuleAccountAddrs(),
|
&stakingKeeper, authtypes.FeeCollectorName,
|
||||||
)
|
)
|
||||||
app.SlashingKeeper = slashingkeeper.NewKeeper(
|
app.SlashingKeeper = slashingkeeper.NewKeeper(
|
||||||
appCodec, keys[slashingtypes.StoreKey], &stakingKeeper, app.GetSubspace(slashingtypes.ModuleName),
|
appCodec, keys[slashingtypes.StoreKey], &stakingKeeper, app.GetSubspace(slashingtypes.ModuleName),
|
||||||
@@ -325,7 +408,7 @@ func NewEthermintApp(
|
|||||||
app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName,
|
app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName,
|
||||||
)
|
)
|
||||||
app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper)
|
app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper)
|
||||||
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp)
|
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp, authtypes.NewModuleAddress(govtypes.ModuleName).String())
|
||||||
|
|
||||||
// register the staking hooks
|
// register the staking hooks
|
||||||
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
|
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
|
||||||
@@ -333,37 +416,64 @@ func NewEthermintApp(
|
|||||||
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
|
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
|
||||||
)
|
)
|
||||||
|
|
||||||
app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.BaseApp.MsgServiceRouter())
|
app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.MsgServiceRouter(), app.AccountKeeper)
|
||||||
|
|
||||||
tracer := cast.ToString(appOpts.Get(srvflags.EVMTracer))
|
tracer := cast.ToString(appOpts.Get(srvflags.EVMTracer))
|
||||||
|
|
||||||
// Create Ethermint keepers
|
// Create Ethermint keepers
|
||||||
app.EvmKeeper = evmkeeper.NewKeeper(
|
|
||||||
appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], app.GetSubspace(evmtypes.ModuleName),
|
|
||||||
app.AccountKeeper, app.BankKeeper, app.StakingKeeper,
|
|
||||||
tracer, bApp.Trace(), // debug EVM based on Baseapp options
|
|
||||||
)
|
|
||||||
|
|
||||||
app.FeeMarketKeeper = feemarketkeeper.NewKeeper(
|
app.FeeMarketKeeper = feemarketkeeper.NewKeeper(
|
||||||
appCodec, keys[feemarkettypes.StoreKey], app.GetSubspace(feemarkettypes.ModuleName),
|
appCodec, keys[feemarkettypes.StoreKey], app.GetSubspace(feemarkettypes.ModuleName),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Create Vulcanize chiba-clonk keepers
|
||||||
|
app.AuctionKeeper = auctionkeeper.NewKeeper(
|
||||||
|
app.AccountKeeper, app.BankKeeper, keys[auctiontypes.StoreKey],
|
||||||
|
appCodec, app.GetSubspace(auctiontypes.ModuleName),
|
||||||
|
)
|
||||||
|
|
||||||
|
app.NameServiceRecordKeeper = nameservicekeeper.NewRecordKeeper(app.AuctionKeeper, keys[nameservicetypes.StoreKey], appCodec)
|
||||||
|
|
||||||
|
app.AuctionKeeper.SetUsageKeepers([]auctiontypes.AuctionUsageKeeper{app.NameServiceRecordKeeper})
|
||||||
|
|
||||||
|
app.BondKeeper = bondkeeper.NewKeeper(
|
||||||
|
appCodec, app.AccountKeeper, app.BankKeeper,
|
||||||
|
[]bondtypes.BondUsageKeeper{app.NameServiceRecordKeeper}, keys[bondtypes.StoreKey], app.GetSubspace(bondtypes.ModuleName),
|
||||||
|
)
|
||||||
|
|
||||||
|
app.NameServiceKeeper = nameservicekeeper.NewKeeper(
|
||||||
|
appCodec, app.AccountKeeper, app.BankKeeper,
|
||||||
|
app.NameServiceRecordKeeper, app.BondKeeper, app.AuctionKeeper,
|
||||||
|
keys[nameservicetypes.StoreKey], app.GetSubspace(nameservicetypes.ModuleName),
|
||||||
|
)
|
||||||
|
|
||||||
|
app.EvmKeeper = evmkeeper.NewKeeper(
|
||||||
|
appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], app.GetSubspace(evmtypes.ModuleName),
|
||||||
|
app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.FeeMarketKeeper,
|
||||||
|
tracer,
|
||||||
|
)
|
||||||
|
|
||||||
// Create IBC Keeper
|
// Create IBC Keeper
|
||||||
app.IBCKeeper = ibckeeper.NewKeeper(
|
app.IBCKeeper = ibckeeper.NewKeeper(
|
||||||
appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper,
|
appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper,
|
||||||
)
|
)
|
||||||
|
|
||||||
// register the proposal types
|
// register the proposal types
|
||||||
govRouter := govtypes.NewRouter()
|
govRouter := govv1beta1.NewRouter()
|
||||||
govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
|
govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler).
|
||||||
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
|
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
|
||||||
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
|
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
|
||||||
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
|
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
|
||||||
AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))
|
AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))
|
||||||
|
|
||||||
|
govConfig := govtypes.DefaultConfig()
|
||||||
|
/*
|
||||||
|
Example of setting gov params:
|
||||||
|
govConfig.MaxMetadataLen = 10000
|
||||||
|
*/
|
||||||
|
|
||||||
govKeeper := govkeeper.NewKeeper(
|
govKeeper := govkeeper.NewKeeper(
|
||||||
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
|
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
|
||||||
&stakingKeeper, govRouter,
|
&stakingKeeper, govRouter, app.MsgServiceRouter(), govConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
app.GovKeeper = *govKeeper.SetHooks(
|
app.GovKeeper = *govKeeper.SetHooks(
|
||||||
@@ -375,14 +485,15 @@ func NewEthermintApp(
|
|||||||
// Create Transfer Keepers
|
// Create Transfer Keepers
|
||||||
app.TransferKeeper = ibctransferkeeper.NewKeeper(
|
app.TransferKeeper = ibctransferkeeper.NewKeeper(
|
||||||
appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
|
appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
|
||||||
app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper,
|
app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper,
|
||||||
app.AccountKeeper, app.BankKeeper, scopedTransferKeeper,
|
app.AccountKeeper, app.BankKeeper, scopedTransferKeeper,
|
||||||
)
|
)
|
||||||
transferModule := transfer.NewAppModule(app.TransferKeeper)
|
transferModule := transfer.NewAppModule(app.TransferKeeper)
|
||||||
|
transferIBCModule := transfer.NewIBCModule(app.TransferKeeper)
|
||||||
|
|
||||||
// Create static IBC router, add transfer route, then set and seal it
|
//Create static IBC router, add transfer route, then set and seal it
|
||||||
ibcRouter := porttypes.NewRouter()
|
ibcRouter := porttypes.NewRouter()
|
||||||
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule)
|
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule)
|
||||||
app.IBCKeeper.SetRouter(ibcRouter)
|
app.IBCKeeper.SetRouter(ibcRouter)
|
||||||
|
|
||||||
// create evidence keeper with router
|
// create evidence keeper with router
|
||||||
@@ -412,7 +523,7 @@ func NewEthermintApp(
|
|||||||
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
|
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
|
||||||
crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants),
|
crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants),
|
||||||
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
|
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
|
||||||
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper),
|
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
|
||||||
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
||||||
distr.NewAppModule(appCodec, app.DistrKeeper, 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),
|
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
|
||||||
@@ -421,13 +532,16 @@ func NewEthermintApp(
|
|||||||
params.NewAppModule(app.ParamsKeeper),
|
params.NewAppModule(app.ParamsKeeper),
|
||||||
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
|
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
|
||||||
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
|
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
|
||||||
|
|
||||||
// ibc modules
|
// ibc modules
|
||||||
ibc.NewAppModule(app.IBCKeeper),
|
ibc.NewAppModule(app.IBCKeeper),
|
||||||
transferModule,
|
transferModule,
|
||||||
// Ethermint app modules
|
// Ethermint app modules
|
||||||
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
|
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
|
||||||
feemarket.NewAppModule(app.FeeMarketKeeper),
|
feemarket.NewAppModule(app.FeeMarketKeeper),
|
||||||
|
// chiba-clonk modules
|
||||||
|
auction.NewAppModule(appCodec, app.AuctionKeeper),
|
||||||
|
bond.NewAppModule(appCodec, app.BondKeeper),
|
||||||
|
nameservice.NewAppModule(app.NameServiceKeeper),
|
||||||
)
|
)
|
||||||
|
|
||||||
// During begin block slashing happens after distr.BeginBlocker so that
|
// During begin block slashing happens after distr.BeginBlocker so that
|
||||||
@@ -439,15 +553,58 @@ func NewEthermintApp(
|
|||||||
app.mm.SetOrderBeginBlockers(
|
app.mm.SetOrderBeginBlockers(
|
||||||
upgradetypes.ModuleName,
|
upgradetypes.ModuleName,
|
||||||
capabilitytypes.ModuleName,
|
capabilitytypes.ModuleName,
|
||||||
|
feemarkettypes.ModuleName,
|
||||||
evmtypes.ModuleName,
|
evmtypes.ModuleName,
|
||||||
minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName,
|
minttypes.ModuleName,
|
||||||
evidencetypes.ModuleName, stakingtypes.ModuleName, ibchost.ModuleName,
|
distrtypes.ModuleName,
|
||||||
|
slashingtypes.ModuleName,
|
||||||
|
evidencetypes.ModuleName,
|
||||||
|
stakingtypes.ModuleName,
|
||||||
|
ibchost.ModuleName,
|
||||||
|
// no-op modules
|
||||||
|
ibctransfertypes.ModuleName,
|
||||||
|
authtypes.ModuleName,
|
||||||
|
banktypes.ModuleName,
|
||||||
|
govtypes.ModuleName,
|
||||||
|
crisistypes.ModuleName,
|
||||||
|
genutiltypes.ModuleName,
|
||||||
|
authz.ModuleName,
|
||||||
|
feegrant.ModuleName,
|
||||||
|
paramstypes.ModuleName,
|
||||||
|
vestingtypes.ModuleName,
|
||||||
|
// chiba-clonk modules
|
||||||
|
auctiontypes.ModuleName,
|
||||||
|
bondtypes.ModuleName,
|
||||||
|
nameservicetypes.ModuleName,
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE: fee market module must go last in order to retrieve the block gas used.
|
// NOTE: fee market module must go last in order to retrieve the block gas used.
|
||||||
app.mm.SetOrderEndBlockers(
|
app.mm.SetOrderEndBlockers(
|
||||||
crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName,
|
crisistypes.ModuleName,
|
||||||
evmtypes.ModuleName, feemarkettypes.ModuleName,
|
govtypes.ModuleName,
|
||||||
|
stakingtypes.ModuleName,
|
||||||
|
evmtypes.ModuleName,
|
||||||
|
feemarkettypes.ModuleName,
|
||||||
|
// no-op modules
|
||||||
|
ibchost.ModuleName,
|
||||||
|
ibctransfertypes.ModuleName,
|
||||||
|
capabilitytypes.ModuleName,
|
||||||
|
authtypes.ModuleName,
|
||||||
|
banktypes.ModuleName,
|
||||||
|
distrtypes.ModuleName,
|
||||||
|
slashingtypes.ModuleName,
|
||||||
|
minttypes.ModuleName,
|
||||||
|
genutiltypes.ModuleName,
|
||||||
|
evidencetypes.ModuleName,
|
||||||
|
authz.ModuleName,
|
||||||
|
feegrant.ModuleName,
|
||||||
|
paramstypes.ModuleName,
|
||||||
|
upgradetypes.ModuleName,
|
||||||
|
vestingtypes.ModuleName,
|
||||||
|
// chiba-clonk modules
|
||||||
|
auctiontypes.ModuleName,
|
||||||
|
bondtypes.ModuleName,
|
||||||
|
nameservicetypes.ModuleName,
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE: The genutils module must occur after staking so that pools are
|
// NOTE: The genutils module must occur after staking so that pools are
|
||||||
@@ -457,12 +614,30 @@ func NewEthermintApp(
|
|||||||
// can do so safely.
|
// can do so safely.
|
||||||
app.mm.SetOrderInitGenesis(
|
app.mm.SetOrderInitGenesis(
|
||||||
// SDK modules
|
// SDK modules
|
||||||
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName,
|
capabilitytypes.ModuleName,
|
||||||
slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName,
|
authtypes.ModuleName,
|
||||||
ibchost.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, ibctransfertypes.ModuleName,
|
banktypes.ModuleName,
|
||||||
authz.ModuleName, feegrant.ModuleName,
|
distrtypes.ModuleName,
|
||||||
|
stakingtypes.ModuleName,
|
||||||
|
slashingtypes.ModuleName,
|
||||||
|
govtypes.ModuleName,
|
||||||
|
minttypes.ModuleName,
|
||||||
|
ibchost.ModuleName,
|
||||||
|
genutiltypes.ModuleName,
|
||||||
|
evidencetypes.ModuleName,
|
||||||
|
ibctransfertypes.ModuleName,
|
||||||
|
authz.ModuleName,
|
||||||
|
feegrant.ModuleName,
|
||||||
|
paramstypes.ModuleName,
|
||||||
|
upgradetypes.ModuleName,
|
||||||
|
vestingtypes.ModuleName,
|
||||||
// Ethermint modules
|
// Ethermint modules
|
||||||
evmtypes.ModuleName, feemarkettypes.ModuleName,
|
evmtypes.ModuleName,
|
||||||
|
feemarkettypes.ModuleName,
|
||||||
|
// chiba-clonk modules
|
||||||
|
auctiontypes.ModuleName,
|
||||||
|
bondtypes.ModuleName,
|
||||||
|
nameservicetypes.ModuleName,
|
||||||
|
|
||||||
// NOTE: crisis module must go at the end to check for invariants on each module
|
// NOTE: crisis module must go at the end to check for invariants on each module
|
||||||
crisistypes.ModuleName,
|
crisistypes.ModuleName,
|
||||||
@@ -485,7 +660,7 @@ func NewEthermintApp(
|
|||||||
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
|
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
|
||||||
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
|
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
|
||||||
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
|
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
|
||||||
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper),
|
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
|
||||||
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
|
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
|
||||||
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
||||||
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
||||||
@@ -495,35 +670,38 @@ func NewEthermintApp(
|
|||||||
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
|
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
|
||||||
ibc.NewAppModule(app.IBCKeeper),
|
ibc.NewAppModule(app.IBCKeeper),
|
||||||
transferModule,
|
transferModule,
|
||||||
|
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
|
||||||
|
feemarket.NewAppModule(app.FeeMarketKeeper),
|
||||||
)
|
)
|
||||||
|
|
||||||
app.sm.RegisterStoreDecoders()
|
app.sm.RegisterStoreDecoders()
|
||||||
|
|
||||||
// initialize stores
|
|
||||||
app.MountKVStores(keys)
|
|
||||||
app.MountTransientStores(tkeys)
|
|
||||||
app.MountMemoryStores(memKeys)
|
|
||||||
|
|
||||||
// initialize BaseApp
|
// initialize BaseApp
|
||||||
app.SetInitChainer(app.InitChainer)
|
app.SetInitChainer(app.InitChainer)
|
||||||
app.SetBeginBlocker(app.BeginBlocker)
|
app.SetBeginBlocker(app.BeginBlocker)
|
||||||
|
|
||||||
// use Ethermint's custom AnteHandler
|
// use Ethermint's custom AnteHandler
|
||||||
app.SetAnteHandler(
|
|
||||||
ante.NewAnteHandler(
|
|
||||||
app.AccountKeeper, app.BankKeeper, app.EvmKeeper, app.FeeGrantKeeper, app.IBCKeeper.ChannelKeeper,
|
|
||||||
encodingConfig.TxConfig.SignModeHandler(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
app.SetEndBlocker(app.EndBlocker)
|
maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted))
|
||||||
|
options := ante.HandlerOptions{
|
||||||
if loadLatest {
|
AccountKeeper: app.AccountKeeper,
|
||||||
if err := app.LoadLatestVersion(); err != nil {
|
BankKeeper: app.BankKeeper,
|
||||||
tmos.Exit(err.Error())
|
EvmKeeper: app.EvmKeeper,
|
||||||
}
|
FeegrantKeeper: app.FeeGrantKeeper,
|
||||||
|
IBCKeeper: app.IBCKeeper,
|
||||||
|
FeeMarketKeeper: app.FeeMarketKeeper,
|
||||||
|
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
|
||||||
|
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
|
||||||
|
MaxTxGasWanted: maxGasWanted,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := options.Validate(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
app.SetAnteHandler(ante.NewAnteHandler(options))
|
||||||
|
app.SetEndBlocker(app.EndBlocker)
|
||||||
|
|
||||||
app.ScopedIBCKeeper = scopedIBCKeeper
|
app.ScopedIBCKeeper = scopedIBCKeeper
|
||||||
app.ScopedTransferKeeper = scopedTransferKeeper
|
app.ScopedTransferKeeper = scopedTransferKeeper
|
||||||
|
|
||||||
@@ -555,7 +733,8 @@ func (app *EthermintApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain)
|
|||||||
|
|
||||||
// LoadHeight loads state at a particular height
|
// LoadHeight loads state at a particular height
|
||||||
func (app *EthermintApp) LoadHeight(height int64) error {
|
func (app *EthermintApp) LoadHeight(height int64) error {
|
||||||
return app.LoadVersion(height)
|
// return app.LoadVersion(height)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ModuleAccountAddrs returns all the app's module account addresses.
|
// ModuleAccountAddrs returns all the app's module account addresses.
|
||||||
@@ -603,21 +782,21 @@ func (app *EthermintApp) InterfaceRegistry() types.InterfaceRegistry {
|
|||||||
// GetKey returns the KVStoreKey for the provided store key.
|
// GetKey returns the KVStoreKey for the provided store key.
|
||||||
//
|
//
|
||||||
// NOTE: This is solely to be used for testing purposes.
|
// NOTE: This is solely to be used for testing purposes.
|
||||||
func (app *EthermintApp) GetKey(storeKey string) *sdk.KVStoreKey {
|
func (app *EthermintApp) GetKey(storeKey string) *storetypes.KVStoreKey {
|
||||||
return app.keys[storeKey]
|
return app.keys[storeKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTKey returns the TransientStoreKey for the provided store key.
|
// GetTKey returns the TransientStoreKey for the provided store key.
|
||||||
//
|
//
|
||||||
// NOTE: This is solely to be used for testing purposes.
|
// NOTE: This is solely to be used for testing purposes.
|
||||||
func (app *EthermintApp) GetTKey(storeKey string) *sdk.TransientStoreKey {
|
func (app *EthermintApp) GetTKey(storeKey string) *storetypes.TransientStoreKey {
|
||||||
return app.tkeys[storeKey]
|
return app.tkeys[storeKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMemKey returns the MemStoreKey for the provided mem key.
|
// GetMemKey returns the MemStoreKey for the provided mem key.
|
||||||
//
|
//
|
||||||
// NOTE: This is solely used for testing purposes.
|
// NOTE: This is solely used for testing purposes.
|
||||||
func (app *EthermintApp) GetMemKey(storeKey string) *sdk.MemoryStoreKey {
|
func (app *EthermintApp) GetMemKey(storeKey string) *storetypes.MemoryStoreKey {
|
||||||
return app.memKeys[storeKey]
|
return app.memKeys[storeKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,17 +817,16 @@ func (app *EthermintApp) SimulationManager() *module.SimulationManager {
|
|||||||
// API server.
|
// API server.
|
||||||
func (app *EthermintApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
|
func (app *EthermintApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
|
||||||
clientCtx := apiSvr.ClientCtx
|
clientCtx := apiSvr.ClientCtx
|
||||||
rpc.RegisterRoutes(clientCtx, apiSvr.Router)
|
// NOTE: in v0.46 legacy routes are removed
|
||||||
|
// rpc.RegisterRoutes(clientCtx, apiSvr.Router)
|
||||||
evmrest.RegisterTxRoutes(clientCtx, apiSvr.Router)
|
// evmrest.RegisterTxRoutes(clientCtx, apiSvr.Router)
|
||||||
|
|
||||||
// Register new tx routes from grpc-gateway.
|
// Register new tx routes from grpc-gateway.
|
||||||
authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
||||||
// Register new tendermint queries routes from grpc-gateway.
|
// Register new tendermint queries routes from grpc-gateway.
|
||||||
tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
||||||
|
|
||||||
// Register legacy and grpc-gateway routes for all modules.
|
// Register grpc-gateway routes for all modules.
|
||||||
ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router)
|
|
||||||
ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
||||||
|
|
||||||
// register swagger API from root so that other applications can override easily
|
// register swagger API from root so that other applications can override easily
|
||||||
@@ -662,7 +840,12 @@ func (app *EthermintApp) RegisterTxService(clientCtx client.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *EthermintApp) RegisterTendermintService(clientCtx client.Context) {
|
func (app *EthermintApp) RegisterTendermintService(clientCtx client.Context) {
|
||||||
tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry)
|
tmservice.RegisterTendermintService(
|
||||||
|
clientCtx,
|
||||||
|
app.BaseApp.GRPCQueryRouter(),
|
||||||
|
app.interfaceRegistry,
|
||||||
|
app.Query,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterSwaggerAPI registers swagger route with API Server
|
// RegisterSwaggerAPI registers swagger route with API Server
|
||||||
@@ -688,7 +871,8 @@ func GetMaccPerms() map[string][]string {
|
|||||||
|
|
||||||
// initParamsKeeper init params keeper and its subspaces
|
// initParamsKeeper init params keeper and its subspaces
|
||||||
func initParamsKeeper(
|
func initParamsKeeper(
|
||||||
appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper {
|
appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey,
|
||||||
|
) paramskeeper.Keeper {
|
||||||
paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)
|
paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)
|
||||||
|
|
||||||
// SDK subspaces
|
// SDK subspaces
|
||||||
@@ -698,12 +882,16 @@ func initParamsKeeper(
|
|||||||
paramsKeeper.Subspace(minttypes.ModuleName)
|
paramsKeeper.Subspace(minttypes.ModuleName)
|
||||||
paramsKeeper.Subspace(distrtypes.ModuleName)
|
paramsKeeper.Subspace(distrtypes.ModuleName)
|
||||||
paramsKeeper.Subspace(slashingtypes.ModuleName)
|
paramsKeeper.Subspace(slashingtypes.ModuleName)
|
||||||
paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable())
|
paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govv1.ParamKeyTable())
|
||||||
paramsKeeper.Subspace(crisistypes.ModuleName)
|
paramsKeeper.Subspace(crisistypes.ModuleName)
|
||||||
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
|
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
|
||||||
paramsKeeper.Subspace(ibchost.ModuleName)
|
paramsKeeper.Subspace(ibchost.ModuleName)
|
||||||
// ethermint subspaces
|
// ethermint subspaces
|
||||||
paramsKeeper.Subspace(evmtypes.ModuleName)
|
paramsKeeper.Subspace(evmtypes.ModuleName)
|
||||||
paramsKeeper.Subspace(feemarkettypes.ModuleName)
|
paramsKeeper.Subspace(feemarkettypes.ModuleName)
|
||||||
|
// chiba-clonk subspaces
|
||||||
|
paramsKeeper.Subspace(auctiontypes.ModuleName)
|
||||||
|
paramsKeeper.Subspace(bondtypes.ModuleName)
|
||||||
|
paramsKeeper.Subspace(nameservicetypes.ModuleName)
|
||||||
return paramsKeeper
|
return paramsKeeper
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-21
@@ -1,41 +1,45 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
memdb "github.com/cosmos/cosmos-sdk/db/memdb"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/simapp"
|
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
dbm "github.com/tendermint/tm-db"
|
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/encoding"
|
"github.com/tharsis/ethermint/encoding"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEthermintAppExport(t *testing.T) {
|
func TestEthermintAppExport(t *testing.T) {
|
||||||
db := dbm.NewMemDB()
|
encCfg := encoding.MakeConfig(ModuleBasics)
|
||||||
app := NewEthermintApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
db := memdb.NewDB()
|
||||||
|
logger, _ := log.NewDefaultLogger("plain", "info", false)
|
||||||
|
app := NewTestAppWithCustomOptions(t, false, SetupOptions{
|
||||||
|
Logger: logger,
|
||||||
|
DB: db,
|
||||||
|
InvCheckPeriod: 0,
|
||||||
|
EncConfig: encCfg,
|
||||||
|
HomePath: DefaultNodeHome,
|
||||||
|
SkipUpgradeHeights: map[int64]bool{},
|
||||||
|
AppOpts: EmptyAppOptions{},
|
||||||
|
})
|
||||||
|
|
||||||
genesisState := NewDefaultGenesisState()
|
for acc := range allowedReceivingModAcc {
|
||||||
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
|
// check module account is not blocked in bank
|
||||||
require.NoError(t, err)
|
require.False(
|
||||||
|
t,
|
||||||
|
app.BankKeeper.BlockedAddr(app.AccountKeeper.GetModuleAddress(acc)),
|
||||||
|
"ensure that blocked addresses %s are properly set in bank keeper",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the chain
|
|
||||||
app.InitChain(
|
|
||||||
abci.RequestInitChain{
|
|
||||||
ChainId: "ethermint_9000-1",
|
|
||||||
Validators: []abci.ValidatorUpdate{},
|
|
||||||
AppStateBytes: stateBytes,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
app.Commit()
|
app.Commit()
|
||||||
|
logger2, _ := log.NewDefaultLogger("plain", "info", false)
|
||||||
|
|
||||||
// Making a new app object with the db, so that initchain hasn't been called
|
// Making a new app object with the db, so that initchain hasn't been called
|
||||||
app2 := NewEthermintApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
app2 := NewEthermintApp(logger2, db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{})
|
||||||
_, err = app2.ExportAppStateAndValidators(false, []string{})
|
require.NoError(t, app2.Init())
|
||||||
|
_, err := app2.ExportAppStateAndValidators(false, []string{})
|
||||||
require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
|
require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,21 @@ package app
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/db/memdb"
|
||||||
"github.com/cosmos/cosmos-sdk/simapp"
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
dbm "github.com/tendermint/tm-db"
|
|
||||||
"github.com/tharsis/ethermint/encoding"
|
"github.com/tharsis/ethermint/encoding"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkEthermintApp_ExportAppStateAndValidators(b *testing.B) {
|
func BenchmarkEthermintApp_ExportAppStateAndValidators(b *testing.B) {
|
||||||
db := dbm.NewMemDB()
|
db := memdb.NewDB()
|
||||||
app := NewEthermintApp(log.NewTMLogger(io.Discard), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
logger, _ := log.NewDefaultLogger("plain", "info", false)
|
||||||
|
app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
||||||
|
|
||||||
genesisState := NewDefaultGenesisState()
|
genesisState := NewDefaultGenesisState(app.appCodec)
|
||||||
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
|
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
@@ -36,7 +36,7 @@ func BenchmarkEthermintApp_ExportAppStateAndValidators(b *testing.B) {
|
|||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
// Making a new app object with the db, so that initchain hasn't been called
|
// Making a new app object with the db, so that initchain hasn't been called
|
||||||
app2 := NewEthermintApp(log.NewTMLogger(log.NewSyncWriter(io.Discard)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
app2 := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
||||||
if _, err := app2.ExportAppStateAndValidators(false, []string{}); err != nil {
|
if _, err := app2.ExportAppStateAndValidators(false, []string{}); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-8
@@ -6,20 +6,18 @@ import (
|
|||||||
|
|
||||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||||
"github.com/cosmos/cosmos-sdk/simapp"
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/encoding"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewDefaultGenesisState generates the default state for the application.
|
// NewDefaultGenesisState generates the default state for the application.
|
||||||
func NewDefaultGenesisState() simapp.GenesisState {
|
func NewDefaultGenesisState(cdc codec.JSONCodec) simapp.GenesisState {
|
||||||
encCfg := encoding.MakeConfig(ModuleBasics)
|
return ModuleBasics.DefaultGenesis(cdc)
|
||||||
return ModuleBasics.DefaultGenesis(encCfg.Marshaler)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExportAppStateAndValidators exports the state of the application for a genesis
|
// ExportAppStateAndValidators exports the state of the application for a genesis
|
||||||
@@ -170,7 +168,6 @@ func (app *EthermintApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAd
|
|||||||
// update bond intra-tx counters.
|
// update bond intra-tx counters.
|
||||||
store := ctx.KVStore(app.keys[stakingtypes.StoreKey])
|
store := ctx.KVStore(app.keys[stakingtypes.StoreKey])
|
||||||
iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
|
iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
|
||||||
counter := int16(0)
|
|
||||||
|
|
||||||
for ; iter.Valid(); iter.Next() {
|
for ; iter.Valid(); iter.Next() {
|
||||||
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
|
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
|
||||||
@@ -185,10 +182,11 @@ func (app *EthermintApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.StakingKeeper.SetValidator(ctx, validator)
|
app.StakingKeeper.SetValidator(ctx, validator)
|
||||||
counter++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iter.Close()
|
if err := iter.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx); err != nil {
|
if _, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+349
-338
@@ -1,340 +1,351 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
// disable for now, enable it once SDK side fix the simulator issue for custom keys
|
// TODO: COsmos SDK fix for the simulator issue for custom keys
|
||||||
//import (
|
import (
|
||||||
// "encoding/json"
|
"encoding/json"
|
||||||
// "fmt"
|
"fmt"
|
||||||
// "math/rand"
|
"math/rand"
|
||||||
// "os"
|
"os"
|
||||||
// "testing"
|
"testing"
|
||||||
//
|
|
||||||
// "github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
//
|
|
||||||
// abci "github.com/tendermint/tendermint/abci/types"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
// "github.com/tendermint/tendermint/libs/log"
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
// tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
"github.com/cosmos/cosmos-sdk/simapp/params"
|
||||||
// dbm "github.com/tendermint/tm-db"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
//
|
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||||
// "github.com/cosmos/cosmos-sdk/baseapp"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
// "github.com/cosmos/cosmos-sdk/simapp"
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
// "github.com/cosmos/cosmos-sdk/simapp/helpers"
|
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
||||||
// "github.com/cosmos/cosmos-sdk/store"
|
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
// sdk "github.com/cosmos/cosmos-sdk/types"
|
evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
|
||||||
// simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||||
// authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||||
// banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
// capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||||
// distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||||
// evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
|
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
// govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
|
||||||
// ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types"
|
"github.com/cosmos/cosmos-sdk/db/memdb"
|
||||||
// ibchost "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
|
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||||
// minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
|
||||||
// paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host"
|
||||||
// "github.com/cosmos/cosmos-sdk/x/simulation"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
// slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
// stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||||
//)
|
evmenc "github.com/tharsis/ethermint/encoding"
|
||||||
//
|
)
|
||||||
//func init() {
|
|
||||||
// simapp.GetSimulatorFlags()
|
// MakeEncodingConfig creates the EncodingConfig
|
||||||
//}
|
func MakeEncodingConfig() params.EncodingConfig {
|
||||||
//
|
return evmenc.MakeConfig(ModuleBasics)
|
||||||
//type storeKeysPrefixes struct {
|
}
|
||||||
// A sdk.StoreKey
|
|
||||||
// B sdk.StoreKey
|
func init() {
|
||||||
// Prefixes [][]byte
|
simapp.GetSimulatorFlags()
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//// fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of
|
const SimAppChainID = "simulation_777-1"
|
||||||
//// an IAVLStore for faster simulation speed.
|
|
||||||
//func fauxMerkleModeOpt(bapp *baseapp.BaseApp) {
|
type storeKeysPrefixes struct {
|
||||||
// bapp.SetFauxMerkleMode()
|
A storetypes.StoreKey
|
||||||
//}
|
B storetypes.StoreKey
|
||||||
//
|
Prefixes [][]byte
|
||||||
//// interBlockCacheOpt returns a BaseApp option function that sets the persistent
|
}
|
||||||
//// inter-block write-through cache.
|
|
||||||
//func interBlockCacheOpt() func(*baseapp.BaseApp) {
|
// fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of
|
||||||
// return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager())
|
// an IAVLStore for faster simulation speed.
|
||||||
//}
|
var fauxMerkleModeOpt = baseapp.AppOptionFunc(func(bapp *baseapp.BaseApp) {
|
||||||
//
|
bapp.SetFauxMerkleMode()
|
||||||
//func TestFullAppSimulation(t *testing.T) {
|
})
|
||||||
// config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
|
||||||
// if skip {
|
// interBlockCacheOpt returns a BaseApp option function that sets the persistent
|
||||||
// t.Skip("skipping application simulation")
|
// inter-block write-through cache.
|
||||||
// }
|
// TODO: implement this cache as enhancement to v2 multistore
|
||||||
// require.NoError(t, err, "simulation setup failed")
|
func interBlockCacheOpt() baseapp.AppOptionFunc {
|
||||||
//
|
return func(*baseapp.BaseApp) {}
|
||||||
// defer func() {
|
}
|
||||||
// db.Close()
|
|
||||||
// require.NoError(t, os.RemoveAll(dir))
|
func TestFullAppSimulation(t *testing.T) {
|
||||||
// }()
|
config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
||||||
//
|
if skip {
|
||||||
// app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
t.Skip("skipping application simulation")
|
||||||
// require.Equal(t, appName, app.Name())
|
}
|
||||||
//
|
require.NoError(t, err, "simulation setup failed")
|
||||||
// // run randomized simulation
|
|
||||||
// _, simParams, simErr := simulation.SimulateFromSeed(
|
defer func() {
|
||||||
// t,
|
db.Close()
|
||||||
// os.Stdout,
|
require.NoError(t, os.RemoveAll(dir))
|
||||||
// app.BaseApp,
|
}()
|
||||||
// simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
|
||||||
// simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
||||||
// simapp.SimulationOperations(app, app.AppCodec(), config),
|
require.Equal(t, appName, app.Name())
|
||||||
// app.ModuleAccountAddrs(),
|
|
||||||
// config,
|
// run randomized simulation
|
||||||
// app.AppCodec(),
|
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||||
// )
|
t,
|
||||||
//
|
os.Stdout,
|
||||||
// // export state and simParams before the simulation error is checked
|
app.BaseApp,
|
||||||
// err = simapp.CheckExportSimulation(app, config, simParams)
|
simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||||
// require.NoError(t, err)
|
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||||
// require.NoError(t, simErr)
|
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||||
//
|
app.ModuleAccountAddrs(),
|
||||||
// if config.Commit {
|
config,
|
||||||
// simapp.PrintStats(db)
|
app.AppCodec(),
|
||||||
// }
|
)
|
||||||
//}
|
|
||||||
//
|
// export state and simParams before the simulation error is checked
|
||||||
//func TestAppImportExport(t *testing.T) {
|
err = simapp.CheckExportSimulation(app, config, simParams)
|
||||||
// config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
require.NoError(t, err)
|
||||||
// if skip {
|
require.NoError(t, simErr)
|
||||||
// t.Skip("skipping application import/export simulation")
|
|
||||||
// }
|
if config.Commit {
|
||||||
// require.NoError(t, err, "simulation setup failed")
|
simapp.PrintStats(db)
|
||||||
//
|
}
|
||||||
// defer func() {
|
}
|
||||||
// db.Close()
|
|
||||||
// require.NoError(t, os.RemoveAll(dir))
|
func TestAppImportExport(t *testing.T) {
|
||||||
// }()
|
config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
||||||
//
|
if skip {
|
||||||
// app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
t.Skip("skipping application import/export simulation")
|
||||||
// require.Equal(t, appName, app.Name())
|
}
|
||||||
//
|
require.NoError(t, err, "simulation setup failed")
|
||||||
// // Run randomized simulation
|
|
||||||
// _, simParams, simErr := simulation.SimulateFromSeed(
|
defer func() {
|
||||||
// t,
|
db.Close()
|
||||||
// os.Stdout,
|
require.NoError(t, os.RemoveAll(dir))
|
||||||
// app.BaseApp,
|
}()
|
||||||
// simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
|
||||||
// simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
||||||
// simapp.SimulationOperations(app, app.AppCodec(), config),
|
require.Equal(t, appName, app.Name())
|
||||||
// app.ModuleAccountAddrs(),
|
|
||||||
// config,
|
// Run randomized simulation
|
||||||
// app.AppCodec(),
|
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||||
// )
|
t,
|
||||||
//
|
os.Stdout,
|
||||||
// // export state and simParams before the simulation error is checked
|
app.BaseApp,
|
||||||
// err = simapp.CheckExportSimulation(app, config, simParams)
|
simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||||
// require.NoError(t, err)
|
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||||
// require.NoError(t, simErr)
|
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||||
//
|
app.ModuleAccountAddrs(),
|
||||||
// if config.Commit {
|
config,
|
||||||
// simapp.PrintStats(db)
|
app.AppCodec(),
|
||||||
// }
|
)
|
||||||
//
|
|
||||||
// fmt.Printf("exporting genesis...\n")
|
// export state and simParams before the simulation error is checked
|
||||||
//
|
err = simapp.CheckExportSimulation(app, config, simParams)
|
||||||
// exported, err := app.ExportAppStateAndValidators(false, []string{})
|
require.NoError(t, err)
|
||||||
// require.NoError(t, err)
|
require.NoError(t, simErr)
|
||||||
//
|
|
||||||
// fmt.Printf("importing genesis...\n")
|
if config.Commit {
|
||||||
//
|
simapp.PrintStats(db)
|
||||||
// // nolint: dogsled
|
}
|
||||||
// _, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
|
||||||
// require.NoError(t, err, "simulation setup failed")
|
fmt.Printf("exporting genesis...\n")
|
||||||
//
|
|
||||||
// defer func() {
|
exported, err := app.ExportAppStateAndValidators(false, []string{})
|
||||||
// newDB.Close()
|
require.NoError(t, err)
|
||||||
// require.NoError(t, os.RemoveAll(newDir))
|
|
||||||
// }()
|
fmt.Printf("importing genesis...\n")
|
||||||
//
|
|
||||||
// newApp := NewEthermintApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
// nolint: dogsled
|
||||||
// require.Equal(t, appName, newApp.Name())
|
_, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
||||||
//
|
require.NoError(t, err, "simulation setup failed")
|
||||||
// var genesisState simapp.GenesisState
|
|
||||||
// err = json.Unmarshal(exported.AppState, &genesisState)
|
defer func() {
|
||||||
// require.NoError(t, err)
|
newDB.Close()
|
||||||
//
|
require.NoError(t, os.RemoveAll(newDir))
|
||||||
// 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)
|
newApp := NewEthermintApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
||||||
// newApp.StoreConsensusParams(ctxB, exported.ConsensusParams)
|
require.Equal(t, appName, newApp.Name())
|
||||||
//
|
|
||||||
// fmt.Printf("comparing stores...\n")
|
var genesisState simapp.GenesisState
|
||||||
//
|
err = json.Unmarshal(exported.AppState, &genesisState)
|
||||||
// storeKeysPrefixes := []storeKeysPrefixes{
|
require.NoError(t, err)
|
||||||
// {app.keys[authtypes.StoreKey], newApp.keys[authtypes.StoreKey], [][]byte{}},
|
|
||||||
// {app.keys[stakingtypes.StoreKey], newApp.keys[stakingtypes.StoreKey],
|
ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
|
||||||
// [][]byte{
|
ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
|
||||||
// stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey,
|
newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState)
|
||||||
// stakingtypes.HistoricalInfoKey,
|
newApp.StoreConsensusParams(ctxB, exported.ConsensusParams)
|
||||||
// }}, // ordering may change but it doesn't matter
|
|
||||||
// {app.keys[slashingtypes.StoreKey], newApp.keys[slashingtypes.StoreKey], [][]byte{}},
|
fmt.Printf("comparing stores...\n")
|
||||||
// {app.keys[minttypes.StoreKey], newApp.keys[minttypes.StoreKey], [][]byte{}},
|
|
||||||
// {app.keys[distrtypes.StoreKey], newApp.keys[distrtypes.StoreKey], [][]byte{}},
|
storeKeysPrefixes := []storeKeysPrefixes{
|
||||||
// {app.keys[banktypes.StoreKey], newApp.keys[banktypes.StoreKey], [][]byte{banktypes.BalancesPrefix}},
|
{app.keys[authtypes.StoreKey], newApp.keys[authtypes.StoreKey], [][]byte{}},
|
||||||
// {app.keys[paramtypes.StoreKey], newApp.keys[paramtypes.StoreKey], [][]byte{}},
|
{
|
||||||
// {app.keys[govtypes.StoreKey], newApp.keys[govtypes.StoreKey], [][]byte{}},
|
app.keys[stakingtypes.StoreKey], newApp.keys[stakingtypes.StoreKey],
|
||||||
// {app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}},
|
[][]byte{
|
||||||
// {app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}},
|
stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey,
|
||||||
// {app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}},
|
stakingtypes.HistoricalInfoKey,
|
||||||
// {app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}},
|
},
|
||||||
// }
|
}, // ordering may change but it doesn't matter
|
||||||
//
|
{app.keys[slashingtypes.StoreKey], newApp.keys[slashingtypes.StoreKey], [][]byte{}},
|
||||||
// for _, skp := range storeKeysPrefixes {
|
{app.keys[minttypes.StoreKey], newApp.keys[minttypes.StoreKey], [][]byte{}},
|
||||||
// storeA := ctxA.KVStore(skp.A)
|
{app.keys[distrtypes.StoreKey], newApp.keys[distrtypes.StoreKey], [][]byte{}},
|
||||||
// storeB := ctxB.KVStore(skp.B)
|
{app.keys[banktypes.StoreKey], newApp.keys[banktypes.StoreKey], [][]byte{banktypes.BalancesPrefix}},
|
||||||
//
|
{app.keys[paramtypes.StoreKey], newApp.keys[paramtypes.StoreKey], [][]byte{}},
|
||||||
// failedKVAs, failedKVBs := sdk.DiffKVStores(storeA, storeB, skp.Prefixes)
|
{app.keys[govtypes.StoreKey], newApp.keys[govtypes.StoreKey], [][]byte{}},
|
||||||
// require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare")
|
{app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}},
|
||||||
//
|
{app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}},
|
||||||
// fmt.Printf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B)
|
{app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}},
|
||||||
// require.Equal(t, len(failedKVAs), 0, simapp.GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs))
|
{app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}},
|
||||||
// }
|
}
|
||||||
//}
|
|
||||||
//
|
for _, skp := range storeKeysPrefixes {
|
||||||
//func TestAppSimulationAfterImport(t *testing.T) {
|
storeA := ctxA.KVStore(skp.A)
|
||||||
// config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
storeB := ctxB.KVStore(skp.B)
|
||||||
// if skip {
|
|
||||||
// t.Skip("skipping application simulation after import")
|
failedKVAs, failedKVBs := sdk.DiffKVStores(storeA, storeB, skp.Prefixes)
|
||||||
// }
|
require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare")
|
||||||
// require.NoError(t, err, "simulation setup failed")
|
|
||||||
//
|
fmt.Printf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B)
|
||||||
// defer func() {
|
require.Equal(t, len(failedKVAs), 0, simapp.GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs))
|
||||||
// db.Close()
|
}
|
||||||
// require.NoError(t, os.RemoveAll(dir))
|
}
|
||||||
// }()
|
|
||||||
//
|
func TestAppSimulationAfterImport(t *testing.T) {
|
||||||
// app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
||||||
// require.Equal(t, appName, app.Name())
|
if skip {
|
||||||
//
|
t.Skip("skipping application simulation after import")
|
||||||
// // Run randomized simulation
|
}
|
||||||
// stopEarly, simParams, simErr := simulation.SimulateFromSeed(
|
require.NoError(t, err, "simulation setup failed")
|
||||||
// t,
|
|
||||||
// os.Stdout,
|
defer func() {
|
||||||
// app.BaseApp,
|
db.Close()
|
||||||
// simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
require.NoError(t, os.RemoveAll(dir))
|
||||||
// simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
}()
|
||||||
// simapp.SimulationOperations(app, app.AppCodec(), config),
|
|
||||||
// app.ModuleAccountAddrs(),
|
app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
||||||
// config,
|
require.Equal(t, appName, app.Name())
|
||||||
// app.AppCodec(),
|
|
||||||
// )
|
// Run randomized simulation
|
||||||
//
|
stopEarly, simParams, simErr := simulation.SimulateFromSeed(
|
||||||
// // export state and simParams before the simulation error is checked
|
t,
|
||||||
// err = simapp.CheckExportSimulation(app, config, simParams)
|
os.Stdout,
|
||||||
// require.NoError(t, err)
|
app.BaseApp,
|
||||||
// require.NoError(t, simErr)
|
simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||||
//
|
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||||
// if config.Commit {
|
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||||
// simapp.PrintStats(db)
|
app.ModuleAccountAddrs(),
|
||||||
// }
|
config,
|
||||||
//
|
app.AppCodec(),
|
||||||
// if stopEarly {
|
)
|
||||||
// fmt.Println("can't export or import a zero-validator genesis, exiting test...")
|
|
||||||
// return
|
// export state and simParams before the simulation error is checked
|
||||||
// }
|
err = simapp.CheckExportSimulation(app, config, simParams)
|
||||||
//
|
require.NoError(t, err)
|
||||||
// fmt.Printf("exporting genesis...\n")
|
require.NoError(t, simErr)
|
||||||
//
|
|
||||||
// exported, err := app.ExportAppStateAndValidators(true, []string{})
|
if config.Commit {
|
||||||
// require.NoError(t, err)
|
simapp.PrintStats(db)
|
||||||
//
|
}
|
||||||
// fmt.Printf("importing genesis...\n")
|
|
||||||
//
|
if stopEarly {
|
||||||
// _, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
fmt.Println("can't export or import a zero-validator genesis, exiting test...")
|
||||||
// require.NoError(t, err, "simulation setup failed")
|
return
|
||||||
//
|
}
|
||||||
// defer func() {
|
|
||||||
// newDB.Close()
|
fmt.Printf("exporting genesis...\n")
|
||||||
// require.NoError(t, os.RemoveAll(newDir))
|
|
||||||
// }()
|
exported, err := app.ExportAppStateAndValidators(true, []string{})
|
||||||
//
|
require.NoError(t, err)
|
||||||
// newApp := NewEthermintApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
|
||||||
// require.Equal(t, appName, newApp.Name())
|
fmt.Printf("importing genesis...\n")
|
||||||
//
|
|
||||||
// newApp.InitChain(abci.RequestInitChain{
|
_, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
||||||
// AppStateBytes: exported.AppState,
|
require.NoError(t, err, "simulation setup failed")
|
||||||
// })
|
|
||||||
//
|
defer func() {
|
||||||
// _, _, err = simulation.SimulateFromSeed(
|
newDB.Close()
|
||||||
// t,
|
require.NoError(t, os.RemoveAll(newDir))
|
||||||
// os.Stdout,
|
}()
|
||||||
// newApp.BaseApp,
|
|
||||||
// simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
newApp := NewEthermintApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
||||||
// simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
require.Equal(t, appName, newApp.Name())
|
||||||
// simapp.SimulationOperations(newApp, newApp.AppCodec(), config),
|
|
||||||
// app.ModuleAccountAddrs(),
|
newApp.InitChain(abci.RequestInitChain{
|
||||||
// config,
|
AppStateBytes: exported.AppState,
|
||||||
// app.AppCodec(),
|
})
|
||||||
// )
|
|
||||||
// require.NoError(t, err)
|
_, _, err = simulation.SimulateFromSeed(
|
||||||
//}
|
t,
|
||||||
//
|
os.Stdout,
|
||||||
//// TODO: Make another test for the fuzzer itself, which just has noOp txs
|
newApp.BaseApp,
|
||||||
//// and doesn't depend on the application.
|
simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||||
//func TestAppStateDeterminism(t *testing.T) {
|
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||||
// if !simapp.FlagEnabledValue {
|
simapp.SimulationOperations(newApp, newApp.AppCodec(), config),
|
||||||
// t.Skip("skipping application simulation")
|
app.ModuleAccountAddrs(),
|
||||||
// }
|
config,
|
||||||
//
|
app.AppCodec(),
|
||||||
// config := simapp.NewConfigFromFlags()
|
)
|
||||||
// config.InitialBlockHeight = 1
|
require.NoError(t, err)
|
||||||
// config.ExportParamsPath = ""
|
}
|
||||||
// config.OnOperation = false
|
|
||||||
// config.AllInvariants = false
|
// TODO: Make another test for the fuzzer itself, which just has noOp txs
|
||||||
// config.ChainID = helpers.SimAppChainID
|
// and doesn't depend on the application.
|
||||||
//
|
func TestAppStateDeterminism(t *testing.T) {
|
||||||
// numSeeds := 3
|
if !simapp.FlagEnabledValue {
|
||||||
// numTimesToRunPerSeed := 5
|
t.Skip("skipping application simulation")
|
||||||
// appHashList := make([]json.RawMessage, numTimesToRunPerSeed)
|
}
|
||||||
//
|
|
||||||
// for i := 0; i < numSeeds; i++ {
|
config := simapp.NewConfigFromFlags()
|
||||||
// config.Seed = rand.Int63()
|
config.InitialBlockHeight = 1
|
||||||
//
|
config.ExportParamsPath = ""
|
||||||
// for j := 0; j < numTimesToRunPerSeed; j++ {
|
config.OnOperation = false
|
||||||
// var logger log.Logger
|
config.AllInvariants = false
|
||||||
// if simapp.FlagVerboseValue {
|
config.ChainID = SimAppChainID
|
||||||
// logger = log.TestingLogger()
|
|
||||||
// } else {
|
numSeeds := 3
|
||||||
// logger = log.NewNopLogger()
|
numTimesToRunPerSeed := 5
|
||||||
// }
|
appHashList := make([]json.RawMessage, numTimesToRunPerSeed)
|
||||||
//
|
|
||||||
// db := dbm.NewMemDB()
|
for i := 0; i < numSeeds; i++ {
|
||||||
// app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, interBlockCacheOpt())
|
config.Seed = rand.Int63()
|
||||||
//
|
|
||||||
// fmt.Printf(
|
for j := 0; j < numTimesToRunPerSeed; j++ {
|
||||||
// "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n",
|
var logger log.Logger
|
||||||
// config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
|
if simapp.FlagVerboseValue {
|
||||||
// )
|
logger = log.TestingLogger()
|
||||||
//
|
} else {
|
||||||
// _, _, err := simulation.SimulateFromSeed(
|
logger = log.NewNopLogger()
|
||||||
// t,
|
}
|
||||||
// os.Stdout,
|
|
||||||
// app.BaseApp,
|
db := memdb.NewDB()
|
||||||
// simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, interBlockCacheOpt())
|
||||||
// simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
|
||||||
// simapp.SimulationOperations(app, app.AppCodec(), config),
|
fmt.Printf(
|
||||||
// app.ModuleAccountAddrs(),
|
"running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n",
|
||||||
// config,
|
config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
|
||||||
// app.AppCodec(),
|
)
|
||||||
// )
|
|
||||||
// require.NoError(t, err)
|
_, _, err := simulation.SimulateFromSeed(
|
||||||
//
|
t,
|
||||||
// if config.Commit {
|
os.Stdout,
|
||||||
// simapp.PrintStats(db)
|
app.BaseApp,
|
||||||
// }
|
simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||||
//
|
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||||
// appHash := app.LastCommitID().Hash
|
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||||
// appHashList[j] = appHash
|
app.ModuleAccountAddrs(),
|
||||||
//
|
config,
|
||||||
// if j != 0 {
|
app.AppCodec(),
|
||||||
// require.Equal(
|
)
|
||||||
// t, string(appHashList[0]), string(appHashList[j]),
|
require.NoError(t, err)
|
||||||
// "non-determinism in seed %d: %d/%d, attempt: %d/%d\n", config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
|
|
||||||
// )
|
if config.Commit {
|
||||||
// }
|
simapp.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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+236
-13
@@ -1,23 +1,50 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
|
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||||
|
"github.com/cosmos/cosmos-sdk/server/types"
|
||||||
"github.com/cosmos/cosmos-sdk/simapp"
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
"github.com/tharsis/ethermint/encoding"
|
"github.com/cosmos/cosmos-sdk/testutil/mock"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/simapp/params"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||||
|
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
|
||||||
|
"github.com/tharsis/ethermint/encoding"
|
||||||
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/db/memdb"
|
||||||
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
|
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
dbm "github.com/tendermint/tm-db"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GenesisState 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.
|
||||||
|
|
||||||
// DefaultConsensusParams defines the default Tendermint consensus params used in
|
// DefaultConsensusParams defines the default Tendermint consensus params used in
|
||||||
// EthermintApp testing.
|
// EthermintApp testing.
|
||||||
var DefaultConsensusParams = &abci.ConsensusParams{
|
var DefaultConsensusParams = &tmproto.ConsensusParams{
|
||||||
Block: &abci.BlockParams{
|
Block: &tmproto.BlockParams{
|
||||||
MaxBytes: 200000,
|
MaxBytes: 200000,
|
||||||
MaxGas: -1, // no limit
|
MaxGas: -1, // no limit
|
||||||
},
|
},
|
||||||
@@ -33,17 +60,50 @@ var DefaultConsensusParams = &abci.ConsensusParams{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp.
|
// SetupOptions defines arguments that are passed into `Simapp` constructor.
|
||||||
func Setup(isCheckTx bool) *EthermintApp {
|
type SetupOptions struct {
|
||||||
db := dbm.NewMemDB()
|
Logger log.Logger
|
||||||
app := NewEthermintApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{})
|
DB *memdb.MemDB
|
||||||
|
InvCheckPeriod uint
|
||||||
|
HomePath string
|
||||||
|
SkipUpgradeHeights map[int64]bool
|
||||||
|
EncConfig params.EncodingConfig
|
||||||
|
AppOpts types.AppOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTestAppWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptions) *EthermintApp {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
privVal := mock.NewPV()
|
||||||
|
pubKey, err := privVal.GetPubKey(context.TODO())
|
||||||
|
require.NoError(t, err)
|
||||||
|
// create validator set with single validator
|
||||||
|
validator := tmtypes.NewValidator(pubKey, 1)
|
||||||
|
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
|
||||||
|
|
||||||
|
// generate genesis account
|
||||||
|
priv, err := ethsecp256k1.GenerateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
address := common.BytesToAddress(priv.PubKey().Address().Bytes())
|
||||||
|
|
||||||
|
acc := ðermint.EthAccount{
|
||||||
|
BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(address.Bytes()), nil, 0, 0),
|
||||||
|
CodeHash: common.BytesToHash(crypto.Keccak256(nil)).String(),
|
||||||
|
}
|
||||||
|
|
||||||
|
balance := banktypes.Balance{
|
||||||
|
Address: acc.GetAddress().String(),
|
||||||
|
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
|
||||||
|
}
|
||||||
|
|
||||||
|
app := NewEthermintApp(options.Logger, options.DB, nil, true, options.SkipUpgradeHeights, options.HomePath, options.InvCheckPeriod, options.EncConfig, options.AppOpts)
|
||||||
|
genesisState := NewDefaultGenesisState(app.appCodec)
|
||||||
|
genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance)
|
||||||
|
|
||||||
if !isCheckTx {
|
if !isCheckTx {
|
||||||
// init chain must be called to stop deliverState from being nil
|
// init chain must be called to stop deliverState from being nil
|
||||||
genesisState := NewDefaultGenesisState()
|
stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ")
|
||||||
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
|
require.NoError(t, err)
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the chain
|
// Initialize the chain
|
||||||
app.InitChain(
|
app.InitChain(
|
||||||
@@ -58,3 +118,166 @@ func Setup(isCheckTx bool) *EthermintApp {
|
|||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp.
|
||||||
|
func Setup(t *testing.T, isCheckTx bool, patchGenesis func(*EthermintApp, simapp.GenesisState) simapp.GenesisState) *EthermintApp {
|
||||||
|
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
privVal := mock.NewPV()
|
||||||
|
pubKey, err := privVal.GetPubKey(context.TODO())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// create validator set with single validator
|
||||||
|
validator := tmtypes.NewValidator(pubKey, 1)
|
||||||
|
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
|
||||||
|
|
||||||
|
priv, err := ethsecp256k1.GenerateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
address := common.BytesToAddress(priv.PubKey().Address().Bytes())
|
||||||
|
|
||||||
|
acc := ðermint.EthAccount{
|
||||||
|
BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(address.Bytes()), nil, 0, 0),
|
||||||
|
CodeHash: common.BytesToHash(crypto.Keccak256(nil)).String(),
|
||||||
|
}
|
||||||
|
|
||||||
|
balance := banktypes.Balance{
|
||||||
|
Address: acc.GetAddress().String(),
|
||||||
|
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
|
||||||
|
}
|
||||||
|
|
||||||
|
app := SetupWithGenesisValSet(t, valSet, patchGenesis, []authtypes.GenesisAccount{acc}, balance)
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
func setup(withGenesis bool, invCheckPeriod uint, patchGenesis func(*EthermintApp, simapp.GenesisState) simapp.GenesisState) (*EthermintApp, simapp.GenesisState) {
|
||||||
|
encCdc := encoding.MakeConfig(ModuleBasics)
|
||||||
|
app := NewEthermintApp(log.NewNopLogger(), memdb.NewDB(), nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, encCdc, EmptyAppOptions{})
|
||||||
|
if withGenesis {
|
||||||
|
genesisState := NewDefaultGenesisState(encCdc.Codec)
|
||||||
|
if patchGenesis != nil {
|
||||||
|
genesisState = patchGenesis(app, genesisState)
|
||||||
|
}
|
||||||
|
return app, genesisState
|
||||||
|
}
|
||||||
|
|
||||||
|
return app, simapp.GenesisState{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts
|
||||||
|
// that also act as delegators. For simplicity, each validator is bonded with a delegation
|
||||||
|
// of one consensus engine unit in the default token of the simapp from first genesis
|
||||||
|
// account. A Nop logger is set in SimApp.
|
||||||
|
func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, patchGenesis func(*EthermintApp, simapp.GenesisState) simapp.GenesisState, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *EthermintApp {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
app, genesisState := setup(true, 5, patchGenesis)
|
||||||
|
genesisState = genesisStateWithValSet(t, app, genesisState, valSet, genAccs, balances...)
|
||||||
|
|
||||||
|
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// init chain will set the validator set and initialize the genesis accounts
|
||||||
|
app.InitChain(
|
||||||
|
abci.RequestInitChain{
|
||||||
|
ChainId: "ethermint_9000-1",
|
||||||
|
Validators: []abci.ValidatorUpdate{},
|
||||||
|
ConsensusParams: DefaultConsensusParams,
|
||||||
|
AppStateBytes: stateBytes,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// commit genesis changes
|
||||||
|
// app.Commit()
|
||||||
|
// app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{
|
||||||
|
// ChainID: "ethermint_9000-1",
|
||||||
|
// Height: app.LastBlockHeight() + 1,
|
||||||
|
// AppHash: app.LastCommitID().Hash,
|
||||||
|
// ValidatorsHash: valSet.Hash(),
|
||||||
|
// NextValidatorsHash: valSet.Hash(),
|
||||||
|
// }})
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
func genesisStateWithValSet(t *testing.T, app *EthermintApp, genesisState simapp.GenesisState,
|
||||||
|
valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) simapp.GenesisState {
|
||||||
|
// set genesis accounts
|
||||||
|
authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs)
|
||||||
|
genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis)
|
||||||
|
|
||||||
|
validators := make([]stakingtypes.Validator, 0, len(valSet.Validators))
|
||||||
|
delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators))
|
||||||
|
|
||||||
|
bondAmt := sdk.DefaultPowerReduction
|
||||||
|
|
||||||
|
for _, val := range valSet.Validators {
|
||||||
|
pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
pkAny, err := codectypes.NewAnyWithValue(pk)
|
||||||
|
require.NoError(t, err)
|
||||||
|
validator := stakingtypes.Validator{
|
||||||
|
OperatorAddress: sdk.ValAddress(val.Address).String(),
|
||||||
|
ConsensusPubkey: pkAny,
|
||||||
|
Jailed: false,
|
||||||
|
Status: stakingtypes.Bonded,
|
||||||
|
Tokens: bondAmt,
|
||||||
|
DelegatorShares: sdk.OneDec(),
|
||||||
|
Description: stakingtypes.Description{},
|
||||||
|
UnbondingHeight: int64(0),
|
||||||
|
UnbondingTime: time.Unix(0, 0).UTC(),
|
||||||
|
Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
|
||||||
|
MinSelfDelegation: sdk.ZeroInt(),
|
||||||
|
}
|
||||||
|
validators = append(validators, validator)
|
||||||
|
delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), sdk.OneDec()))
|
||||||
|
|
||||||
|
}
|
||||||
|
// set validators and delegations
|
||||||
|
stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations)
|
||||||
|
genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenesis)
|
||||||
|
|
||||||
|
totalSupply := sdk.NewCoins()
|
||||||
|
for _, b := range balances {
|
||||||
|
// add genesis acc tokens to total supply
|
||||||
|
totalSupply = totalSupply.Add(b.Coins...)
|
||||||
|
}
|
||||||
|
|
||||||
|
for range delegations {
|
||||||
|
// add delegated tokens to total supply
|
||||||
|
totalSupply = totalSupply.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt))
|
||||||
|
}
|
||||||
|
|
||||||
|
// add bonded amount to bonded pool module account
|
||||||
|
balances = append(balances, banktypes.Balance{
|
||||||
|
Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(),
|
||||||
|
Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)},
|
||||||
|
})
|
||||||
|
|
||||||
|
// update total supply
|
||||||
|
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{})
|
||||||
|
genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis)
|
||||||
|
|
||||||
|
return genesisState
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRandomAccounts will generate random accounts
|
||||||
|
func CreateRandomAccounts(accNum int) []sdk.AccAddress {
|
||||||
|
// createRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order.
|
||||||
|
testAddrs := make([]sdk.AccAddress, accNum)
|
||||||
|
for i := 0; i < accNum; i++ {
|
||||||
|
pk := ed25519.GenPrivKey().PubKey()
|
||||||
|
testAddrs[i] = sdk.AccAddress(pk.Address())
|
||||||
|
}
|
||||||
|
|
||||||
|
return testAddrs
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmptyAppOptions is a stub implementing AppOptions
|
||||||
|
type EmptyAppOptions struct{}
|
||||||
|
|
||||||
|
// Get implements AppOptions
|
||||||
|
func (ao EmptyAppOptions) Get(o string) interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
func TestInitConfigNonNotExistError(t *testing.T) {
|
func TestInitConfigNonNotExistError(t *testing.T) {
|
||||||
tempDir := t.TempDir()
|
tempDir := t.TempDir()
|
||||||
subDir := filepath.Join(tempDir, "nonPerms")
|
subDir := filepath.Join(tempDir, "nonPerms")
|
||||||
if err := os.Mkdir(subDir, 0600); err != nil {
|
if err := os.Mkdir(subDir, 0o600); err != nil {
|
||||||
t.Fatalf("Failed to create sub directory: %v", err)
|
t.Fatalf("Failed to create sub directory: %v", err)
|
||||||
}
|
}
|
||||||
cmd := &cobra.Command{}
|
cmd := &cobra.Command{}
|
||||||
|
|||||||
Vendored
+3
-5
File diff suppressed because one or more lines are too long
Vendored
+488
-221
@@ -1495,11 +1495,6 @@ paths:
|
|||||||
title: >-
|
title: >-
|
||||||
Berlin switch block (nil = no fork, 0 = already on
|
Berlin switch block (nil = no fork, 0 = already on
|
||||||
berlin)
|
berlin)
|
||||||
catalyst_block:
|
|
||||||
type: string
|
|
||||||
title: >-
|
|
||||||
Catalyst switch block (nil = no fork, 0 = already on
|
|
||||||
catalyst)
|
|
||||||
london_block:
|
london_block:
|
||||||
type: string
|
type: string
|
||||||
title: >-
|
title: >-
|
||||||
@@ -1929,6 +1924,360 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
tags:
|
tags:
|
||||||
- Query
|
- Query
|
||||||
|
/ethermint/evm/v1/trace_block:
|
||||||
|
get:
|
||||||
|
summary: >-
|
||||||
|
TraceBlock implements the `debug_traceBlockByNumber` and
|
||||||
|
`debug_traceBlockByHash` rpc api
|
||||||
|
operationId: TraceBlock
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: A successful response.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: string
|
||||||
|
format: byte
|
||||||
|
title: QueryTraceBlockResponse defines TraceBlock response
|
||||||
|
default:
|
||||||
|
description: An unexpected error response.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
code:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
details:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
type_url:
|
||||||
|
type: string
|
||||||
|
description: >-
|
||||||
|
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.
|
||||||
|
value:
|
||||||
|
type: string
|
||||||
|
format: byte
|
||||||
|
description: >-
|
||||||
|
Must be a valid serialized protocol buffer of the above
|
||||||
|
specified type.
|
||||||
|
description: >-
|
||||||
|
`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 := ptypes.MarshalAny(foo)
|
||||||
|
...
|
||||||
|
foo := &pb.Foo{}
|
||||||
|
if err := ptypes.UnmarshalAny(any, 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": <string>,
|
||||||
|
"lastName": <string>
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
parameters:
|
||||||
|
- name: trace_config.tracer
|
||||||
|
description: custom javascript tracer.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.timeout
|
||||||
|
description: >-
|
||||||
|
overrides the default timeout of 5 seconds for JavaScript-based
|
||||||
|
tracing
|
||||||
|
|
||||||
|
calls.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.reexec
|
||||||
|
description: number of blocks the tracer is willing to go back.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
format: uint64
|
||||||
|
- name: trace_config.disable_stack
|
||||||
|
description: disable stack capture.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
- name: trace_config.disable_storage
|
||||||
|
description: disable storage capture.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
- name: trace_config.debug
|
||||||
|
description: print output during capture end.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
- name: trace_config.limit
|
||||||
|
description: 'maximum length of output, but zero means unlimited.'
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
- name: trace_config.overrides.homestead_block
|
||||||
|
description: 'Homestead switch block (nil no fork, 0 = already homestead).'
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.dao_fork_block
|
||||||
|
description: TheDAO hard-fork switch block (nil no fork).
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.dao_fork_support
|
||||||
|
description: Whether the nodes supports or opposes the DAO hard-fork.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
- name: trace_config.overrides.eip150_block
|
||||||
|
description: >-
|
||||||
|
EIP150 implements the Gas price changes
|
||||||
|
|
||||||
|
(https://github.com/ethereum/EIPs/issues/150) EIP150 HF block (nil
|
||||||
|
no fork).
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.eip150_hash
|
||||||
|
description: >-
|
||||||
|
EIP150 HF hash (needed for header only clients as only gas pricing
|
||||||
|
changed).
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.eip155_block
|
||||||
|
description: EIP155Block HF block.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.eip158_block
|
||||||
|
description: EIP158 HF block.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.byzantium_block
|
||||||
|
description: 'Byzantium switch block (nil no fork, 0 = already on byzantium).'
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.constantinople_block
|
||||||
|
description: 'Constantinople switch block (nil no fork, 0 = already activated).'
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.petersburg_block
|
||||||
|
description: Petersburg switch block (nil same as Constantinople).
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.istanbul_block
|
||||||
|
description: 'Istanbul switch block (nil no fork, 0 = already on istanbul).'
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.muir_glacier_block
|
||||||
|
description: >-
|
||||||
|
Eip-2384 (bomb delay) switch block (nil no fork, 0 = already
|
||||||
|
activated).
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.berlin_block
|
||||||
|
description: 'Berlin switch block (nil = no fork, 0 = already on berlin).'
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.overrides.london_block
|
||||||
|
description: 'London switch block (nil = no fork, 0 = already on london).'
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: trace_config.enable_memory
|
||||||
|
description: enable memory capture.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
- name: trace_config.enable_return_data
|
||||||
|
description: enable return data capture.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
- name: block_number
|
||||||
|
description: block number.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
format: int64
|
||||||
|
- name: block_hash
|
||||||
|
description: block hex hash.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: block_time
|
||||||
|
description: block time.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
tags:
|
||||||
|
- Query
|
||||||
/ethermint/evm/v1/trace_tx:
|
/ethermint/evm/v1/trace_tx:
|
||||||
get:
|
get:
|
||||||
summary: TraceTx implements the `debug_traceTransaction` rpc api
|
summary: TraceTx implements the `debug_traceTransaction` rpc api
|
||||||
@@ -2217,8 +2566,8 @@ paths:
|
|||||||
description: transaction index.
|
description: transaction index.
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: integer
|
type: string
|
||||||
format: int64
|
format: uint64
|
||||||
- name: trace_config.tracer
|
- name: trace_config.tracer
|
||||||
description: custom javascript tracer.
|
description: custom javascript tracer.
|
||||||
in: query
|
in: query
|
||||||
@@ -2227,7 +2576,9 @@ paths:
|
|||||||
- name: trace_config.timeout
|
- name: trace_config.timeout
|
||||||
description: >-
|
description: >-
|
||||||
overrides the default timeout of 5 seconds for JavaScript-based
|
overrides the default timeout of 5 seconds for JavaScript-based
|
||||||
tracing calls.
|
tracing
|
||||||
|
|
||||||
|
calls.
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
@@ -2237,53 +2588,43 @@ paths:
|
|||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
format: uint64
|
format: uint64
|
||||||
- name: trace_config.log_config.disable_memory
|
- name: trace_config.disable_stack
|
||||||
description: disable memory capture.
|
|
||||||
in: query
|
|
||||||
required: false
|
|
||||||
type: boolean
|
|
||||||
- name: trace_config.log_config.disable_stack
|
|
||||||
description: disable stack capture.
|
description: disable stack capture.
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
- name: trace_config.log_config.disable_storage
|
- name: trace_config.disable_storage
|
||||||
description: disable storage capture.
|
description: disable storage capture.
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
- name: trace_config.log_config.disable_return_data
|
- name: trace_config.debug
|
||||||
description: disable return data capture.
|
|
||||||
in: query
|
|
||||||
required: false
|
|
||||||
type: boolean
|
|
||||||
- name: trace_config.log_config.debug
|
|
||||||
description: print output during capture end.
|
description: print output during capture end.
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
- name: trace_config.log_config.limit
|
- name: trace_config.limit
|
||||||
description: 'maximum length of output, but zero means unlimited.'
|
description: 'maximum length of output, but zero means unlimited.'
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
- name: trace_config.log_config.overrides.homestead_block
|
- name: trace_config.overrides.homestead_block
|
||||||
description: 'Homestead switch block (nil no fork, 0 = already homestead).'
|
description: 'Homestead switch block (nil no fork, 0 = already homestead).'
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.dao_fork_block
|
- name: trace_config.overrides.dao_fork_block
|
||||||
description: TheDAO hard-fork switch block (nil no fork).
|
description: TheDAO hard-fork switch block (nil no fork).
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.dao_fork_support
|
- name: trace_config.overrides.dao_fork_support
|
||||||
description: Whether the nodes supports or opposes the DAO hard-fork.
|
description: Whether the nodes supports or opposes the DAO hard-fork.
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
- name: trace_config.log_config.overrides.eip150_block
|
- name: trace_config.overrides.eip150_block
|
||||||
description: >-
|
description: >-
|
||||||
EIP150 implements the Gas price changes
|
EIP150 implements the Gas price changes
|
||||||
|
|
||||||
@@ -2292,65 +2633,87 @@ paths:
|
|||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.eip150_hash
|
- name: trace_config.overrides.eip150_hash
|
||||||
description: >-
|
description: >-
|
||||||
EIP150 HF hash (needed for header only clients as only gas pricing
|
EIP150 HF hash (needed for header only clients as only gas pricing
|
||||||
changed).
|
changed).
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.eip155_block
|
- name: trace_config.overrides.eip155_block
|
||||||
description: EIP155Block HF block.
|
description: EIP155Block HF block.
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.eip158_block
|
- name: trace_config.overrides.eip158_block
|
||||||
description: EIP158 HF block.
|
description: EIP158 HF block.
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.byzantium_block
|
- name: trace_config.overrides.byzantium_block
|
||||||
description: 'Byzantium switch block (nil no fork, 0 = already on byzantium).'
|
description: 'Byzantium switch block (nil no fork, 0 = already on byzantium).'
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.constantinople_block
|
- name: trace_config.overrides.constantinople_block
|
||||||
description: 'Constantinople switch block (nil no fork, 0 = already activated).'
|
description: 'Constantinople switch block (nil no fork, 0 = already activated).'
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.petersburg_block
|
- name: trace_config.overrides.petersburg_block
|
||||||
description: Petersburg switch block (nil same as Constantinople).
|
description: Petersburg switch block (nil same as Constantinople).
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.istanbul_block
|
- name: trace_config.overrides.istanbul_block
|
||||||
description: 'Istanbul switch block (nil no fork, 0 = already on istanbul).'
|
description: 'Istanbul switch block (nil no fork, 0 = already on istanbul).'
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.muir_glacier_block
|
- name: trace_config.overrides.muir_glacier_block
|
||||||
description: >-
|
description: >-
|
||||||
Eip-2384 (bomb delay) switch block (nil no fork, 0 = already
|
Eip-2384 (bomb delay) switch block (nil no fork, 0 = already
|
||||||
activated).
|
activated).
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.berlin_block
|
- name: trace_config.overrides.berlin_block
|
||||||
description: 'Berlin switch block (nil = no fork, 0 = already on berlin).'
|
description: 'Berlin switch block (nil = no fork, 0 = already on berlin).'
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
- name: trace_config.log_config.overrides.catalyst_block
|
- name: trace_config.overrides.london_block
|
||||||
description: 'Catalyst switch block (nil = no fork, 0 = already on catalyst).'
|
|
||||||
in: query
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
- name: trace_config.log_config.overrides.london_block
|
|
||||||
description: 'London switch block (nil = no fork, 0 = already on london).'
|
description: 'London switch block (nil = no fork, 0 = already on london).'
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
- name: trace_config.enable_memory
|
||||||
|
description: enable memory capture.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
- name: trace_config.enable_return_data
|
||||||
|
description: enable return data capture.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
- name: block_number
|
||||||
|
description: block number of requested transaction.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
format: int64
|
||||||
|
- name: block_hash
|
||||||
|
description: block hex hash of requested transaction.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: block_time
|
||||||
|
description: block time of requested transaction.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
tags:
|
tags:
|
||||||
- Query
|
- Query
|
||||||
'/ethermint/evm/v1/validator_account/{cons_address}':
|
'/ethermint/evm/v1/validator_account/{cons_address}':
|
||||||
@@ -13493,9 +13856,6 @@ definitions:
|
|||||||
berlin_block:
|
berlin_block:
|
||||||
type: string
|
type: string
|
||||||
title: 'Berlin switch block (nil = no fork, 0 = already on berlin)'
|
title: 'Berlin switch block (nil = no fork, 0 = already on berlin)'
|
||||||
catalyst_block:
|
|
||||||
type: string
|
|
||||||
title: 'Catalyst switch block (nil = no fork, 0 = already on catalyst)'
|
|
||||||
london_block:
|
london_block:
|
||||||
type: string
|
type: string
|
||||||
title: 'London switch block (nil = no fork, 0 = already on london)'
|
title: 'London switch block (nil = no fork, 0 = already on london)'
|
||||||
@@ -13561,93 +13921,6 @@ definitions:
|
|||||||
by
|
by
|
||||||
|
|
||||||
the node.
|
the node.
|
||||||
ethermint.evm.v1.LogConfig:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
disable_memory:
|
|
||||||
type: boolean
|
|
||||||
title: disable memory capture
|
|
||||||
disable_stack:
|
|
||||||
type: boolean
|
|
||||||
title: disable stack capture
|
|
||||||
disable_storage:
|
|
||||||
type: boolean
|
|
||||||
title: disable storage capture
|
|
||||||
disable_return_data:
|
|
||||||
type: boolean
|
|
||||||
title: disable return data capture
|
|
||||||
debug:
|
|
||||||
type: boolean
|
|
||||||
title: print output during capture end
|
|
||||||
limit:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
title: 'maximum length of output, but zero means unlimited'
|
|
||||||
overrides:
|
|
||||||
title: >-
|
|
||||||
Chain overrides, can be used to execute a trace using future fork
|
|
||||||
rules
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
homestead_block:
|
|
||||||
type: string
|
|
||||||
title: 'Homestead switch block (nil no fork, 0 = already homestead)'
|
|
||||||
dao_fork_block:
|
|
||||||
type: string
|
|
||||||
title: TheDAO hard-fork switch block (nil no fork)
|
|
||||||
dao_fork_support:
|
|
||||||
type: boolean
|
|
||||||
title: Whether the nodes supports or opposes the DAO hard-fork
|
|
||||||
eip150_block:
|
|
||||||
type: string
|
|
||||||
title: >-
|
|
||||||
EIP150 implements the Gas price changes
|
|
||||||
|
|
||||||
(https://github.com/ethereum/EIPs/issues/150) EIP150 HF block (nil
|
|
||||||
no fork)
|
|
||||||
eip150_hash:
|
|
||||||
type: string
|
|
||||||
title: >-
|
|
||||||
EIP150 HF hash (needed for header only clients as only gas pricing
|
|
||||||
changed)
|
|
||||||
eip155_block:
|
|
||||||
type: string
|
|
||||||
title: EIP155Block HF block
|
|
||||||
eip158_block:
|
|
||||||
type: string
|
|
||||||
title: EIP158 HF block
|
|
||||||
byzantium_block:
|
|
||||||
type: string
|
|
||||||
title: 'Byzantium switch block (nil no fork, 0 = already on byzantium)'
|
|
||||||
constantinople_block:
|
|
||||||
type: string
|
|
||||||
title: 'Constantinople switch block (nil no fork, 0 = already activated)'
|
|
||||||
petersburg_block:
|
|
||||||
type: string
|
|
||||||
title: Petersburg switch block (nil same as Constantinople)
|
|
||||||
istanbul_block:
|
|
||||||
type: string
|
|
||||||
title: 'Istanbul switch block (nil no fork, 0 = already on istanbul)'
|
|
||||||
muir_glacier_block:
|
|
||||||
type: string
|
|
||||||
title: >-
|
|
||||||
Eip-2384 (bomb delay) switch block (nil no fork, 0 = already
|
|
||||||
activated)
|
|
||||||
berlin_block:
|
|
||||||
type: string
|
|
||||||
title: 'Berlin switch block (nil = no fork, 0 = already on berlin)'
|
|
||||||
catalyst_block:
|
|
||||||
type: string
|
|
||||||
title: 'Catalyst switch block (nil = no fork, 0 = already on catalyst)'
|
|
||||||
london_block:
|
|
||||||
type: string
|
|
||||||
title: 'London switch block (nil = no fork, 0 = already on london)'
|
|
||||||
description: >-
|
|
||||||
ChainConfig defines the Ethereum ChainConfig parameters using *sdk.Int
|
|
||||||
values
|
|
||||||
|
|
||||||
instead of *big.Int.
|
|
||||||
title: LogConfig are the configuration options for structured logger the EVM
|
|
||||||
ethermint.evm.v1.MsgEthereumTx:
|
ethermint.evm.v1.MsgEthereumTx:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -13977,9 +14250,6 @@ definitions:
|
|||||||
berlin_block:
|
berlin_block:
|
||||||
type: string
|
type: string
|
||||||
title: 'Berlin switch block (nil = no fork, 0 = already on berlin)'
|
title: 'Berlin switch block (nil = no fork, 0 = already on berlin)'
|
||||||
catalyst_block:
|
|
||||||
type: string
|
|
||||||
title: 'Catalyst switch block (nil = no fork, 0 = already on catalyst)'
|
|
||||||
london_block:
|
london_block:
|
||||||
type: string
|
type: string
|
||||||
title: 'London switch block (nil = no fork, 0 = already on london)'
|
title: 'London switch block (nil = no fork, 0 = already on london)'
|
||||||
@@ -14126,9 +14396,6 @@ definitions:
|
|||||||
berlin_block:
|
berlin_block:
|
||||||
type: string
|
type: string
|
||||||
title: 'Berlin switch block (nil = no fork, 0 = already on berlin)'
|
title: 'Berlin switch block (nil = no fork, 0 = already on berlin)'
|
||||||
catalyst_block:
|
|
||||||
type: string
|
|
||||||
title: 'Catalyst switch block (nil = no fork, 0 = already on catalyst)'
|
|
||||||
london_block:
|
london_block:
|
||||||
type: string
|
type: string
|
||||||
title: 'London switch block (nil = no fork, 0 = already on london)'
|
title: 'London switch block (nil = no fork, 0 = already on london)'
|
||||||
@@ -14152,6 +14419,13 @@ definitions:
|
|||||||
description: |-
|
description: |-
|
||||||
QueryStorageResponse is the response type for the Query/Storage RPC
|
QueryStorageResponse is the response type for the Query/Storage RPC
|
||||||
method.
|
method.
|
||||||
|
ethermint.evm.v1.QueryTraceBlockResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: string
|
||||||
|
format: byte
|
||||||
|
title: QueryTraceBlockResponse defines TraceBlock response
|
||||||
ethermint.evm.v1.QueryTraceTxResponse:
|
ethermint.evm.v1.QueryTraceTxResponse:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -14187,100 +14461,93 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
title: >-
|
title: >-
|
||||||
overrides the default timeout of 5 seconds for JavaScript-based
|
overrides the default timeout of 5 seconds for JavaScript-based
|
||||||
tracing calls
|
tracing
|
||||||
|
|
||||||
|
calls
|
||||||
reexec:
|
reexec:
|
||||||
type: string
|
type: string
|
||||||
format: uint64
|
format: uint64
|
||||||
title: number of blocks the tracer is willing to go back
|
title: number of blocks the tracer is willing to go back
|
||||||
log_config:
|
disable_stack:
|
||||||
title: configuration options for structured logger the EVM
|
type: boolean
|
||||||
|
title: disable stack capture
|
||||||
|
disable_storage:
|
||||||
|
type: boolean
|
||||||
|
title: disable storage capture
|
||||||
|
debug:
|
||||||
|
type: boolean
|
||||||
|
title: print output during capture end
|
||||||
|
limit:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
title: 'maximum length of output, but zero means unlimited'
|
||||||
|
overrides:
|
||||||
|
title: >-
|
||||||
|
Chain overrides, can be used to execute a trace using future fork
|
||||||
|
rules
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
disable_memory:
|
homestead_block:
|
||||||
|
type: string
|
||||||
|
title: 'Homestead switch block (nil no fork, 0 = already homestead)'
|
||||||
|
dao_fork_block:
|
||||||
|
type: string
|
||||||
|
title: TheDAO hard-fork switch block (nil no fork)
|
||||||
|
dao_fork_support:
|
||||||
type: boolean
|
type: boolean
|
||||||
title: disable memory capture
|
title: Whether the nodes supports or opposes the DAO hard-fork
|
||||||
disable_stack:
|
eip150_block:
|
||||||
type: boolean
|
type: string
|
||||||
title: disable stack capture
|
|
||||||
disable_storage:
|
|
||||||
type: boolean
|
|
||||||
title: disable storage capture
|
|
||||||
disable_return_data:
|
|
||||||
type: boolean
|
|
||||||
title: disable return data capture
|
|
||||||
debug:
|
|
||||||
type: boolean
|
|
||||||
title: print output during capture end
|
|
||||||
limit:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
title: 'maximum length of output, but zero means unlimited'
|
|
||||||
overrides:
|
|
||||||
title: >-
|
title: >-
|
||||||
Chain overrides, can be used to execute a trace using future fork
|
EIP150 implements the Gas price changes
|
||||||
rules
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
homestead_block:
|
|
||||||
type: string
|
|
||||||
title: 'Homestead switch block (nil no fork, 0 = already homestead)'
|
|
||||||
dao_fork_block:
|
|
||||||
type: string
|
|
||||||
title: TheDAO hard-fork switch block (nil no fork)
|
|
||||||
dao_fork_support:
|
|
||||||
type: boolean
|
|
||||||
title: Whether the nodes supports or opposes the DAO hard-fork
|
|
||||||
eip150_block:
|
|
||||||
type: string
|
|
||||||
title: >-
|
|
||||||
EIP150 implements the Gas price changes
|
|
||||||
|
|
||||||
(https://github.com/ethereum/EIPs/issues/150) EIP150 HF block
|
(https://github.com/ethereum/EIPs/issues/150) EIP150 HF block (nil
|
||||||
(nil no fork)
|
no fork)
|
||||||
eip150_hash:
|
eip150_hash:
|
||||||
type: string
|
type: string
|
||||||
title: >-
|
title: >-
|
||||||
EIP150 HF hash (needed for header only clients as only gas
|
EIP150 HF hash (needed for header only clients as only gas pricing
|
||||||
pricing changed)
|
changed)
|
||||||
eip155_block:
|
eip155_block:
|
||||||
type: string
|
type: string
|
||||||
title: EIP155Block HF block
|
title: EIP155Block HF block
|
||||||
eip158_block:
|
eip158_block:
|
||||||
type: string
|
type: string
|
||||||
title: EIP158 HF block
|
title: EIP158 HF block
|
||||||
byzantium_block:
|
byzantium_block:
|
||||||
type: string
|
type: string
|
||||||
title: 'Byzantium switch block (nil no fork, 0 = already on byzantium)'
|
title: 'Byzantium switch block (nil no fork, 0 = already on byzantium)'
|
||||||
constantinople_block:
|
constantinople_block:
|
||||||
type: string
|
type: string
|
||||||
title: >-
|
title: 'Constantinople switch block (nil no fork, 0 = already activated)'
|
||||||
Constantinople switch block (nil no fork, 0 = already
|
petersburg_block:
|
||||||
activated)
|
type: string
|
||||||
petersburg_block:
|
title: Petersburg switch block (nil same as Constantinople)
|
||||||
type: string
|
istanbul_block:
|
||||||
title: Petersburg switch block (nil same as Constantinople)
|
type: string
|
||||||
istanbul_block:
|
title: 'Istanbul switch block (nil no fork, 0 = already on istanbul)'
|
||||||
type: string
|
muir_glacier_block:
|
||||||
title: 'Istanbul switch block (nil no fork, 0 = already on istanbul)'
|
type: string
|
||||||
muir_glacier_block:
|
title: >-
|
||||||
type: string
|
Eip-2384 (bomb delay) switch block (nil no fork, 0 = already
|
||||||
title: >-
|
activated)
|
||||||
Eip-2384 (bomb delay) switch block (nil no fork, 0 = already
|
berlin_block:
|
||||||
activated)
|
type: string
|
||||||
berlin_block:
|
title: 'Berlin switch block (nil = no fork, 0 = already on berlin)'
|
||||||
type: string
|
london_block:
|
||||||
title: 'Berlin switch block (nil = no fork, 0 = already on berlin)'
|
type: string
|
||||||
catalyst_block:
|
title: 'London switch block (nil = no fork, 0 = already on london)'
|
||||||
type: string
|
description: >-
|
||||||
title: 'Catalyst switch block (nil = no fork, 0 = already on catalyst)'
|
ChainConfig defines the Ethereum ChainConfig parameters using *sdk.Int
|
||||||
london_block:
|
values
|
||||||
type: string
|
|
||||||
title: 'London switch block (nil = no fork, 0 = already on london)'
|
|
||||||
description: >-
|
|
||||||
ChainConfig defines the Ethereum ChainConfig parameters using
|
|
||||||
*sdk.Int values
|
|
||||||
|
|
||||||
instead of *big.Int.
|
instead of *big.Int.
|
||||||
|
enable_memory:
|
||||||
|
type: boolean
|
||||||
|
title: enable memory capture
|
||||||
|
enable_return_data:
|
||||||
|
type: boolean
|
||||||
|
title: enable return data capture
|
||||||
description: TraceConfig holds extra parameters to trace functions.
|
description: TraceConfig holds extra parameters to trace functions.
|
||||||
google.protobuf.Any:
|
google.protobuf.Any:
|
||||||
type: object
|
type: object
|
||||||
|
|||||||
+3
-1
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
"github.com/cosmos/cosmos-sdk/client/input"
|
"github.com/cosmos/cosmos-sdk/client/input"
|
||||||
"github.com/cosmos/cosmos-sdk/crypto"
|
"github.com/cosmos/cosmos-sdk/crypto"
|
||||||
@@ -30,12 +31,13 @@ func UnsafeExportEthKeyCommand() *cobra.Command {
|
|||||||
|
|
||||||
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||||
rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
|
rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
|
||||||
|
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||||
kr, err := keyring.New(
|
kr, err := keyring.New(
|
||||||
sdk.KeyringServiceName(),
|
sdk.KeyringServiceName(),
|
||||||
keyringBackend,
|
keyringBackend,
|
||||||
rootDir,
|
rootDir,
|
||||||
inBuf,
|
inBuf,
|
||||||
|
clientCtx.Codec,
|
||||||
hd.EthSecp256k1Option(),
|
hd.EthSecp256k1Option(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
"github.com/cosmos/cosmos-sdk/client/input"
|
"github.com/cosmos/cosmos-sdk/client/input"
|
||||||
"github.com/cosmos/cosmos-sdk/crypto"
|
"github.com/cosmos/cosmos-sdk/crypto"
|
||||||
@@ -31,12 +32,14 @@ func runImportCmd(cmd *cobra.Command, args []string) error {
|
|||||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||||
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||||
rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
|
rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
|
||||||
|
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||||
|
|
||||||
kb, err := keyring.New(
|
kb, err := keyring.New(
|
||||||
sdk.KeyringServiceName(),
|
sdk.KeyringServiceName(),
|
||||||
keyringBackend,
|
keyringBackend,
|
||||||
rootDir,
|
rootDir,
|
||||||
inBuf,
|
inBuf,
|
||||||
|
clientCtx.Codec,
|
||||||
hd.EthSecp256k1Option(),
|
hd.EthSecp256k1Option(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+3
-5
@@ -92,15 +92,13 @@ func runAddCmd(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun)
|
dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun)
|
||||||
if dryRun {
|
if dryRun {
|
||||||
kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, clientCtx.KeyringDir, buf, hd.EthSecp256k1Option())
|
kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, clientCtx.KeyringDir, buf, clientCtx.Codec, hd.EthSecp256k1Option())
|
||||||
} else {
|
clientCtx = clientCtx.WithKeyring(kr)
|
||||||
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
|
||||||
kr, err = keyring.New(sdk.KeyringServiceName(), backend, clientCtx.KeyringDir, buf, hd.EthSecp256k1Option())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientkeys.RunAddCmd(clientCtx.WithKeyring(kr), cmd, args, buf)
|
return clientkeys.RunAddCmd(clientCtx, cmd, args, buf)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -122,7 +122,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
|||||||
|
|
||||||
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); dryRun {
|
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); dryRun {
|
||||||
// use in memory keybase
|
// use in memory keybase
|
||||||
kb = keyring.NewInMemory(etherminthd.EthSecp256k1Option())
|
kb = keyring.NewInMemory(ctx.Codec, etherminthd.EthSecp256k1Option())
|
||||||
} else {
|
} else {
|
||||||
_, err = kb.Key(name)
|
_, err = kb.Key(name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -156,7 +156,9 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pks[i] = k.GetPubKey()
|
if pks[i], err = k.GetPubKey(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if noSort, _ := cmd.Flags().GetBool(flagNoSort); !noSort {
|
if noSort, _ := cmd.Flags().GetBool(flagNoSort); !noSort {
|
||||||
@@ -183,7 +185,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := kb.SavePubKey(name, pk, algo.Name())
|
info, err := kb.SaveOfflineKey(name, pk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -289,7 +291,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
|||||||
return printCreate(cmd, info, showMnemonic, mnemonic, outputFormat)
|
return printCreate(cmd, info, showMnemonic, mnemonic, outputFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func printCreate(cmd *cobra.Command, info keyring.Info, showMnemonic bool, mnemonic, outputFormat string) error {
|
func printCreate(cmd *cobra.Command, info *keyring.Record, showMnemonic bool, mnemonic, outputFormat string) error {
|
||||||
switch outputFormat {
|
switch outputFormat {
|
||||||
case OutputFormatText:
|
case OutputFormatText:
|
||||||
cmd.PrintErrln()
|
cmd.PrintErrln()
|
||||||
|
|||||||
+2
-13
@@ -3,7 +3,6 @@ package keys
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
@@ -20,19 +19,9 @@ const (
|
|||||||
defaultKeyDBName = "keys"
|
defaultKeyDBName = "keys"
|
||||||
)
|
)
|
||||||
|
|
||||||
type bechKeyOutFn func(keyInfo cryptokeyring.Info) (cryptokeyring.KeyOutput, error)
|
type bechKeyOutFn func(keyInfo *cryptokeyring.Record) (cryptokeyring.KeyOutput, error)
|
||||||
|
|
||||||
// NewLegacyKeyBaseFromDir initializes a legacy keybase at the rootDir directory. Keybase
|
func printKeyInfo(w io.Writer, keyInfo *cryptokeyring.Record, bechKeyOut bechKeyOutFn, output string) {
|
||||||
// options can be applied when generating this new Keybase.
|
|
||||||
func NewLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) {
|
|
||||||
return getLegacyKeyBaseFromDir(rootDir, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getLegacyKeyBaseFromDir(rootDir string, opts ...cryptokeyring.KeybaseOption) (cryptokeyring.LegacyKeybase, error) {
|
|
||||||
return cryptokeyring.NewLegacy(defaultKeyDBName, filepath.Join(rootDir, "keys"), opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func printKeyInfo(w io.Writer, keyInfo cryptokeyring.Info, bechKeyOut bechKeyOutFn, output string) {
|
|
||||||
ko, err := bechKeyOut(keyInfo)
|
ko, err := bechKeyOut(keyInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
+227
-135
@@ -5,29 +5,28 @@ package client
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
tmcfg "github.com/tendermint/tendermint/config"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
tmconfig "github.com/tendermint/tendermint/config"
|
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"
|
"github.com/tendermint/tendermint/types"
|
||||||
tmtime "github.com/tendermint/tendermint/types/time"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||||
|
sdkserver "github.com/cosmos/cosmos-sdk/server"
|
||||||
srvconfig "github.com/cosmos/cosmos-sdk/server/config"
|
srvconfig "github.com/cosmos/cosmos-sdk/server/config"
|
||||||
|
"github.com/cosmos/cosmos-sdk/testutil"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/module"
|
"github.com/cosmos/cosmos-sdk/types/module"
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
@@ -36,124 +35,196 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||||
|
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
|
||||||
|
|
||||||
mintypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
mintypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/crypto/hd"
|
"github.com/tharsis/ethermint/crypto/hd"
|
||||||
"github.com/tharsis/ethermint/server/config"
|
"github.com/tharsis/ethermint/server/config"
|
||||||
|
srvflags "github.com/tharsis/ethermint/server/flags"
|
||||||
ethermint "github.com/tharsis/ethermint/types"
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
|
||||||
|
"github.com/tharsis/ethermint/testutil/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
flagNodeDirPrefix = "node-dir-prefix"
|
flagNodeDirPrefix = "node-dir-prefix"
|
||||||
flagNumValidators = "v"
|
flagNumValidators = "v"
|
||||||
flagOutputDir = "output-dir"
|
flagOutputDir = "output-dir"
|
||||||
flagNodeDaemonHome = "node-daemon-home"
|
flagNodeDaemonHome = "node-daemon-home"
|
||||||
flagCoinDenom = "coin-denom"
|
flagStartingIPAddress = "starting-ip-address"
|
||||||
flagIPAddrs = "ip-addresses"
|
flagEnableLogging = "enable-logging"
|
||||||
|
flagRPCAddress = "rpc.address"
|
||||||
|
flagAPIAddress = "api.address"
|
||||||
|
flagPrintMnemonic = "print-mnemonic"
|
||||||
)
|
)
|
||||||
|
|
||||||
const nodeDirPerm = 0o755
|
type initArgs struct {
|
||||||
|
algo string
|
||||||
|
chainID string
|
||||||
|
keyringBackend string
|
||||||
|
minGasPrices string
|
||||||
|
nodeDaemonHome string
|
||||||
|
nodeDirPrefix string
|
||||||
|
numValidators int
|
||||||
|
outputDir string
|
||||||
|
startingIPAddress string
|
||||||
|
}
|
||||||
|
|
||||||
// TestnetCmd initializes all files for tendermint testnet and application
|
type startArgs struct {
|
||||||
func TestnetCmd(
|
algo string
|
||||||
mbm module.BasicManager, genBalancesIterator banktypes.GenesisBalancesIterator,
|
apiAddress string
|
||||||
) *cobra.Command {
|
chainID string
|
||||||
|
grpcAddress string
|
||||||
|
minGasPrices string
|
||||||
|
outputDir string
|
||||||
|
rpcAddress string
|
||||||
|
jsonrpcAddress string
|
||||||
|
numValidators int
|
||||||
|
enableLogging bool
|
||||||
|
printMnemonic bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func addTestnetFlagsToCmd(cmd *cobra.Command) {
|
||||||
|
cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with")
|
||||||
|
cmd.Flags().StringP(flagOutputDir, "o", "./localnet-setup", "Directory to store initialization data for the testnet")
|
||||||
|
cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
|
||||||
|
cmd.Flags().String(sdkserver.FlagMinGasPrices, fmt.Sprintf("0.000006%s", ethermint.AttoPhoton), "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.FlagKeyAlgorithm, string(hd.EthSecp256k1Type), "Key signing algorithm to generate keys for")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTestnetCmd creates a root testnet command with subcommands to run an in-process testnet or initialize
|
||||||
|
// validator configuration files for running a multi-validator testnet in a separate process
|
||||||
|
func NewTestnetCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command {
|
||||||
|
testnetCmd := &cobra.Command{
|
||||||
|
Use: "testnet",
|
||||||
|
Short: "subcommands for starting or configuring local testnets",
|
||||||
|
DisableFlagParsing: true,
|
||||||
|
SuggestionsMinimumDistance: 2,
|
||||||
|
RunE: client.ValidateCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
testnetCmd.AddCommand(testnetStartCmd())
|
||||||
|
testnetCmd.AddCommand(testnetInitFilesCmd(mbm, genBalIterator))
|
||||||
|
|
||||||
|
return testnetCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// get cmd to initialize all files for tendermint testnet and application
|
||||||
|
func testnetInitFilesCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "testnet",
|
Use: "init-files",
|
||||||
Short: "Initialize files for a Ethermint testnet",
|
Short: "Initialize config directories & files for a multi-validator testnet running locally via separate processes (e.g. Docker Compose or similar)",
|
||||||
Long: `testnet will create "v" number of directories and populate each with
|
Long: `init-files will setup "v" number of directories and populate each with
|
||||||
necessary files (private validator, genesis, config, etc.).
|
necessary files (private validator, genesis, config, etc.) for running "v" validator nodes.
|
||||||
|
|
||||||
Note, strict routability for addresses is turned off in the config file.`,
|
Booting up a network with these validator folders is intended to be used with Docker Compose,
|
||||||
|
or a similar setup where each node has a manually configurable IP address.
|
||||||
|
|
||||||
Example: "ethermintd testnet --v 4 --keyring-backend test --output-dir ./output --ip-addresses 192.168.10.2",
|
Note, strict routability for addresses is turned off in the config file.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
chibaclonkd testnet init-files --v 4 --output-dir ./.testnets --starting-ip-address 192.168.10.2
|
||||||
|
`,
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||||
|
if err != nil {
|
||||||
serverCtx := server.GetServerContextFromCmd(cmd)
|
return err
|
||||||
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)
|
|
||||||
ipAddresses, _ := cmd.Flags().GetStringSlice(flagIPAddrs)
|
|
||||||
numValidators, _ := cmd.Flags().GetInt(flagNumValidators)
|
|
||||||
algo, _ := cmd.Flags().GetString(flags.FlagKeyAlgorithm)
|
|
||||||
coinDenom, _ := cmd.Flags().GetString(flagCoinDenom)
|
|
||||||
|
|
||||||
if len(ipAddresses) == 0 {
|
|
||||||
return errors.New("IP address list cannot be empty")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return InitTestnet(
|
serverCtx := sdkserver.GetServerContextFromCmd(cmd)
|
||||||
clientCtx, cmd, config, mbm, genBalancesIterator, outputDir, chainID, coinDenom, minGasPrices,
|
|
||||||
nodeDirPrefix, nodeDaemonHome, keyringBackend, algo, ipAddresses, numValidators,
|
args := initArgs{}
|
||||||
)
|
args.outputDir, _ = cmd.Flags().GetString(flagOutputDir)
|
||||||
|
args.keyringBackend, _ = cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||||
|
args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID)
|
||||||
|
args.minGasPrices, _ = cmd.Flags().GetString(sdkserver.FlagMinGasPrices)
|
||||||
|
args.nodeDirPrefix, _ = cmd.Flags().GetString(flagNodeDirPrefix)
|
||||||
|
args.nodeDaemonHome, _ = cmd.Flags().GetString(flagNodeDaemonHome)
|
||||||
|
args.startingIPAddress, _ = cmd.Flags().GetString(flagStartingIPAddress)
|
||||||
|
args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators)
|
||||||
|
args.algo, _ = cmd.Flags().GetString(flags.FlagKeyAlgorithm)
|
||||||
|
|
||||||
|
return initTestnetFiles(clientCtx, cmd, serverCtx.Config, mbm, genBalIterator, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with")
|
addTestnetFlagsToCmd(cmd)
|
||||||
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(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)")
|
||||||
cmd.Flags().String(flagNodeDaemonHome, "ethermintd", "Home directory of the node's daemon configuration")
|
cmd.Flags().String(flagNodeDaemonHome, "chibaclonkd", "Home directory of the node's daemon configuration")
|
||||||
cmd.Flags().StringSlice(flagIPAddrs, []string{"192.168.0.1"}, "List of IP addresses to use (i.e. `192.168.0.1,172.168.0.1` results in persistent peers list ID0@192.168.0.1:46656, ID1@172.168.0.1)")
|
cmd.Flags().String(flagStartingIPAddress, "192.168.10.1", "Starting IP address (192.168.10.1 results in persistent peers list ID0@192.168.10.1:46656, ID1@192.168.10.2:46656, ...)")
|
||||||
cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
|
|
||||||
cmd.Flags().String(server.FlagMinGasPrices, "", "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01inj,0.001stake)")
|
|
||||||
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
|
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
|
||||||
cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.EthSecp256k1Type), "Key signing algorithm to generate keys for")
|
|
||||||
cmd.Flags().String(flagCoinDenom, ethermint.AttoPhoton, "Coin denomination used for staking, governance, mint, crisis and evm parameters")
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitTestnet initializes the testnet configuration
|
// get cmd to start multi validator in-process testnet
|
||||||
func InitTestnet(
|
func testnetStartCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "start",
|
||||||
|
Short: "Launch an in-process multi-validator testnet",
|
||||||
|
Long: `testnet will launch an in-process multi-validator testnet,
|
||||||
|
and generate "v" directories, populated with necessary validator configuration files
|
||||||
|
(private validator, genesis, config, etc.).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
chibaclonkd testnet --v 4 --output-dir ./.testnets
|
||||||
|
`,
|
||||||
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
|
args := startArgs{}
|
||||||
|
args.outputDir, _ = cmd.Flags().GetString(flagOutputDir)
|
||||||
|
args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID)
|
||||||
|
args.minGasPrices, _ = cmd.Flags().GetString(sdkserver.FlagMinGasPrices)
|
||||||
|
args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators)
|
||||||
|
args.algo, _ = cmd.Flags().GetString(flags.FlagKeyAlgorithm)
|
||||||
|
args.enableLogging, _ = cmd.Flags().GetBool(flagEnableLogging)
|
||||||
|
args.rpcAddress, _ = cmd.Flags().GetString(flagRPCAddress)
|
||||||
|
args.apiAddress, _ = cmd.Flags().GetString(flagAPIAddress)
|
||||||
|
args.grpcAddress, _ = cmd.Flags().GetString(srvflags.GRPCAddress)
|
||||||
|
args.jsonrpcAddress, _ = cmd.Flags().GetString(srvflags.JSONRPCAddress)
|
||||||
|
args.printMnemonic, _ = cmd.Flags().GetBool(flagPrintMnemonic)
|
||||||
|
|
||||||
|
return startTestnet(cmd, args)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
addTestnetFlagsToCmd(cmd)
|
||||||
|
cmd.Flags().Bool(flagEnableLogging, false, "Enable INFO logging of tendermint validator nodes")
|
||||||
|
cmd.Flags().String(flagRPCAddress, "tcp://0.0.0.0:26657", "the RPC address to listen on")
|
||||||
|
cmd.Flags().String(flagAPIAddress, "tcp://0.0.0.0:1317", "the address to listen on for REST API")
|
||||||
|
cmd.Flags().String(srvflags.GRPCAddress, config.DefaultGRPCAddress, "the gRPC server address to listen on")
|
||||||
|
cmd.Flags().String(srvflags.JSONRPCAddress, config.DefaultJSONRPCAddress, "the JSON-RPC server address to listen on")
|
||||||
|
cmd.Flags().Bool(flagPrintMnemonic, true, "print mnemonic of first validator to stdout for manual testing")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodeDirPerm = 0o755
|
||||||
|
|
||||||
|
// initTestnetFiles initializes testnet files for a testnet to be run in a separate process
|
||||||
|
func initTestnetFiles(
|
||||||
clientCtx client.Context,
|
clientCtx client.Context,
|
||||||
cmd *cobra.Command,
|
cmd *cobra.Command,
|
||||||
nodeConfig *tmconfig.Config,
|
nodeConfig *tmconfig.Config,
|
||||||
mbm module.BasicManager,
|
mbm module.BasicManager,
|
||||||
genBalIterator banktypes.GenesisBalancesIterator,
|
genBalIterator banktypes.GenesisBalancesIterator,
|
||||||
outputDir,
|
args initArgs,
|
||||||
chainID,
|
|
||||||
coinDenom,
|
|
||||||
minGasPrices,
|
|
||||||
nodeDirPrefix,
|
|
||||||
nodeDaemonHome,
|
|
||||||
keyringBackend,
|
|
||||||
algoStr string,
|
|
||||||
ipAddresses []string,
|
|
||||||
numValidators int,
|
|
||||||
) error {
|
) error {
|
||||||
if chainID == "" {
|
if args.chainID == "" {
|
||||||
chainID = fmt.Sprintf("ethermint_%d-1", tmrand.Int63n(9999999999999)+1)
|
args.chainID = fmt.Sprintf("ethermint_%d-1", rand.Int63n(9999999999999)+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ethermint.IsValidChainID(chainID) {
|
nodeIDs := make([]string, args.numValidators)
|
||||||
return fmt.Errorf("invalid chain-id: %s", chainID)
|
valPubKeys := make([]cryptotypes.PubKey, args.numValidators)
|
||||||
}
|
|
||||||
|
|
||||||
if err := sdk.ValidateDenom(coinDenom); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ipAddresses) != 0 {
|
|
||||||
numValidators = len(ipAddresses)
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeIDs := make([]string, numValidators)
|
|
||||||
valPubKeys := make([]cryptotypes.PubKey, numValidators)
|
|
||||||
|
|
||||||
appConfig := config.DefaultConfig()
|
appConfig := config.DefaultConfig()
|
||||||
appConfig.MinGasPrices = minGasPrices
|
appConfig.MinGasPrices = args.minGasPrices
|
||||||
appConfig.API.Enable = true
|
appConfig.API.Enable = true
|
||||||
appConfig.Telemetry.Enabled = true
|
appConfig.Telemetry.Enabled = true
|
||||||
appConfig.Telemetry.PrometheusRetentionTime = 60
|
appConfig.Telemetry.PrometheusRetentionTime = 60
|
||||||
appConfig.Telemetry.EnableHostnameLabel = false
|
appConfig.Telemetry.EnableHostnameLabel = false
|
||||||
appConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", chainID}}
|
appConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", args.chainID}}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
genAccounts []authtypes.GenesisAccount
|
genAccounts []authtypes.GenesisAccount
|
||||||
@@ -163,65 +234,50 @@ func InitTestnet(
|
|||||||
|
|
||||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||||
// generate private keys, node IDs, and initial transactions
|
// generate private keys, node IDs, and initial transactions
|
||||||
for i := 0; i < numValidators; i++ {
|
for i := 0; i < args.numValidators; i++ {
|
||||||
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
|
nodeDirName := fmt.Sprintf("%s%d", args.nodeDirPrefix, i)
|
||||||
nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)
|
nodeDir := filepath.Join(args.outputDir, nodeDirName, args.nodeDaemonHome)
|
||||||
gentxsDir := filepath.Join(outputDir, "gentxs")
|
gentxsDir := filepath.Join(args.outputDir, "gentxs")
|
||||||
|
|
||||||
nodeConfig.SetRoot(nodeDir)
|
nodeConfig.SetRoot(nodeDir)
|
||||||
nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657"
|
nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657"
|
||||||
|
|
||||||
if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil {
|
if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil {
|
||||||
_ = os.RemoveAll(outputDir)
|
_ = os.RemoveAll(args.outputDir)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeConfig.Moniker = nodeDirName
|
nodeConfig.Moniker = nodeDirName
|
||||||
|
|
||||||
var (
|
ip, err := getIP(i, args.startingIPAddress)
|
||||||
ip string
|
if err != nil {
|
||||||
err error
|
_ = os.RemoveAll(args.outputDir)
|
||||||
)
|
return err
|
||||||
|
|
||||||
if len(ipAddresses) == 1 {
|
|
||||||
ip, err = getIP(i, ipAddresses[0])
|
|
||||||
if err != nil {
|
|
||||||
_ = os.RemoveAll(outputDir)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ip = ipAddresses[i]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig)
|
nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = os.RemoveAll(outputDir)
|
_ = os.RemoveAll(args.outputDir)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
|
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
|
||||||
genFiles = append(genFiles, nodeConfig.GenesisFile())
|
genFiles = append(genFiles, nodeConfig.GenesisFile())
|
||||||
|
|
||||||
kb, err := keyring.New(
|
kb, err := keyring.New(sdk.KeyringServiceName(), args.keyringBackend, nodeDir, inBuf, clientCtx.Codec, hd.EthSecp256k1Option())
|
||||||
sdk.KeyringServiceName(),
|
|
||||||
keyringBackend,
|
|
||||||
nodeDir,
|
|
||||||
inBuf,
|
|
||||||
hd.EthSecp256k1Option(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
keyringAlgos, _ := kb.SupportedAlgorithms()
|
keyringAlgos, _ := kb.SupportedAlgorithms()
|
||||||
algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos)
|
algo, err := keyring.NewSigningAlgoFromString(args.algo, keyringAlgos)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, secret, err := server.GenerateSaveCoinKey(kb, nodeDirName, true, algo)
|
addr, secret, err := testutil.GenerateSaveCoinKey(kb, nodeDirName, "", true, algo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = os.RemoveAll(outputDir)
|
_ = os.RemoveAll(args.outputDir)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,16 +289,16 @@ func InitTestnet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// save private key seed words
|
// save private key seed words
|
||||||
if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil {
|
if err := network.WriteFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
accStakingTokens := sdk.TokensFromConsensusPower(5000, ethermint.PowerReduction)
|
accStakingTokens := sdk.TokensFromConsensusPower(5000, ethermint.PowerReduction)
|
||||||
coins := sdk.NewCoins(
|
coins := sdk.Coins{
|
||||||
sdk.NewCoin(coinDenom, accStakingTokens),
|
sdk.NewCoin(ethermint.AttoPhoton, accStakingTokens),
|
||||||
)
|
}
|
||||||
|
|
||||||
genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins})
|
genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()})
|
||||||
genAccounts = append(genAccounts, ðermint.EthAccount{
|
genAccounts = append(genAccounts, ðermint.EthAccount{
|
||||||
BaseAccount: authtypes.NewBaseAccount(addr, nil, 0, 0),
|
BaseAccount: authtypes.NewBaseAccount(addr, nil, 0, 0),
|
||||||
CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(),
|
CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(),
|
||||||
@@ -252,7 +308,7 @@ func InitTestnet(
|
|||||||
createValMsg, err := stakingtypes.NewMsgCreateValidator(
|
createValMsg, err := stakingtypes.NewMsgCreateValidator(
|
||||||
sdk.ValAddress(addr),
|
sdk.ValAddress(addr),
|
||||||
valPubKeys[i],
|
valPubKeys[i],
|
||||||
sdk.NewCoin(coinDenom, valTokens),
|
sdk.NewCoin(ethermint.AttoPhoton, valTokens),
|
||||||
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
|
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
|
||||||
stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()),
|
stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()),
|
||||||
sdk.OneInt(),
|
sdk.OneInt(),
|
||||||
@@ -270,12 +326,12 @@ func InitTestnet(
|
|||||||
|
|
||||||
txFactory := tx.Factory{}
|
txFactory := tx.Factory{}
|
||||||
txFactory = txFactory.
|
txFactory = txFactory.
|
||||||
WithChainID(chainID).
|
WithChainID(args.chainID).
|
||||||
WithMemo(memo).
|
WithMemo(memo).
|
||||||
WithKeybase(kb).
|
WithKeybase(kb).
|
||||||
WithTxConfig(clientCtx.TxConfig)
|
WithTxConfig(clientCtx.TxConfig)
|
||||||
|
|
||||||
if err := tx.Sign(txFactory, nodeDirName, txBuilder, false); err != nil {
|
if err := tx.Sign(txFactory, nodeDirName, txBuilder, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,26 +340,33 @@ func InitTestnet(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil {
|
if err := network.WriteFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
customAppTemplate, customAppConfig := config.AppConfig(ethermint.AttoPhoton)
|
||||||
|
srvconfig.SetConfigTemplate(customAppTemplate)
|
||||||
|
customTmConfig := tmcfg.DefaultConfig()
|
||||||
|
if err := sdkserver.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTmConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), appConfig)
|
srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), appConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := initGenFiles(clientCtx, mbm, chainID, coinDenom, genAccounts, genBalances, genFiles, numValidators); err != nil {
|
if err := initGenFiles(clientCtx, mbm, args.chainID, ethermint.AttoPhoton, genAccounts, genBalances, genFiles, args.numValidators); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := collectGenFiles(
|
err := collectGenFiles(
|
||||||
clientCtx, nodeConfig, chainID, nodeIDs, valPubKeys, numValidators,
|
clientCtx, nodeConfig, args.chainID, nodeIDs, valPubKeys, args.numValidators,
|
||||||
outputDir, nodeDirPrefix, nodeDaemonHome, genBalIterator,
|
args.outputDir, args.nodeDirPrefix, args.nodeDaemonHome, genBalIterator,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.PrintErrf("Successfully initialized %d node directories\n", numValidators)
|
cmd.PrintErrf("Successfully initialized %d node directories\n", args.numValidators)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +381,6 @@ func initGenFiles(
|
|||||||
numValidators int,
|
numValidators int,
|
||||||
) error {
|
) error {
|
||||||
appGenState := mbm.DefaultGenesis(clientCtx.Codec)
|
appGenState := mbm.DefaultGenesis(clientCtx.Codec)
|
||||||
|
|
||||||
// set the accounts in the genesis state
|
// set the accounts in the genesis state
|
||||||
var authGenState authtypes.GenesisState
|
var authGenState authtypes.GenesisState
|
||||||
clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState)
|
clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState)
|
||||||
@@ -344,7 +406,7 @@ func initGenFiles(
|
|||||||
stakingGenState.Params.BondDenom = coinDenom
|
stakingGenState.Params.BondDenom = coinDenom
|
||||||
appGenState[stakingtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&stakingGenState)
|
appGenState[stakingtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&stakingGenState)
|
||||||
|
|
||||||
var govGenState govtypes.GenesisState
|
var govGenState v1.GenesisState
|
||||||
clientCtx.Codec.MustUnmarshalJSON(appGenState[govtypes.ModuleName], &govGenState)
|
clientCtx.Codec.MustUnmarshalJSON(appGenState[govtypes.ModuleName], &govGenState)
|
||||||
|
|
||||||
govGenState.DepositParams.MinDeposit[0].Denom = coinDenom
|
govGenState.DepositParams.MinDeposit[0].Denom = coinDenom
|
||||||
@@ -394,7 +456,7 @@ func collectGenFiles(
|
|||||||
outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator,
|
outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator,
|
||||||
) error {
|
) error {
|
||||||
var appState json.RawMessage
|
var appState json.RawMessage
|
||||||
genTime := tmtime.Now()
|
genTime := time.Now()
|
||||||
|
|
||||||
for i := 0; i < numValidators; i++ {
|
for i := 0; i < numValidators; i++ {
|
||||||
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
|
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
|
||||||
@@ -435,7 +497,7 @@ func collectGenFiles(
|
|||||||
|
|
||||||
func getIP(i int, startingIPAddr string) (ip string, err error) {
|
func getIP(i int, startingIPAddr string) (ip string, err error) {
|
||||||
if len(startingIPAddr) == 0 {
|
if len(startingIPAddr) == 0 {
|
||||||
ip, err = server.ExternalIP()
|
ip, err = sdkserver.ExternalIP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -457,19 +519,49 @@ func calculateIP(ip string, i int) (string, error) {
|
|||||||
return ipv4.String(), nil
|
return ipv4.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeFile(name, dir string, contents []byte) error {
|
// startTestnet starts an in-process testnet
|
||||||
writePath := filepath.Join(dir)
|
func startTestnet(cmd *cobra.Command, args startArgs) error {
|
||||||
file := filepath.Join(writePath, name)
|
networkConfig := network.DefaultConfig()
|
||||||
|
|
||||||
err := tmos.EnsureDir(writePath, 0o755)
|
// Default networkConfig.ChainID is random, and we should only override it if chainID provided
|
||||||
|
// is non-empty
|
||||||
|
if args.chainID != "" {
|
||||||
|
networkConfig.ChainID = args.chainID
|
||||||
|
}
|
||||||
|
networkConfig.SigningAlgo = args.algo
|
||||||
|
networkConfig.MinGasPrices = args.minGasPrices
|
||||||
|
networkConfig.NumValidators = args.numValidators
|
||||||
|
networkConfig.EnableTMLogging = args.enableLogging
|
||||||
|
networkConfig.RPCAddress = args.rpcAddress
|
||||||
|
networkConfig.APIAddress = args.apiAddress
|
||||||
|
networkConfig.GRPCAddress = args.grpcAddress
|
||||||
|
networkConfig.JSONRPCAddress = args.jsonrpcAddress
|
||||||
|
networkConfig.PrintMnemonic = args.printMnemonic
|
||||||
|
networkLogger := network.NewCLILogger(cmd)
|
||||||
|
|
||||||
|
baseDir := fmt.Sprintf("%s/%s", args.outputDir, networkConfig.ChainID)
|
||||||
|
if _, err := os.Stat(baseDir); !os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"testnests directory already exists for chain-id '%s': %s, please remove or select a new --chain-id",
|
||||||
|
networkConfig.ChainID, baseDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
testnet, err := network.New(networkLogger, baseDir, networkConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tmos.WriteFile(file, contents, 0o644)
|
_, err = testnet.WaitForHeight(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd.Println("press the Enter Key to terminate")
|
||||||
|
_, err = fmt.Scanln() // wait for Enter Key
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
testnet.Cleanup()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
"github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/app"
|
"github.com/tharsis/ethermint/app"
|
||||||
ethermintd "github.com/tharsis/ethermint/cmd/ethermintd"
|
chibaclonkd "github.com/tharsis/ethermint/cmd/chibaclonkd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInitCmd(t *testing.T) {
|
func TestInitCmd(t *testing.T) {
|
||||||
rootCmd, _ := ethermintd.NewRootCmd()
|
rootCmd, _ := chibaclonkd.NewRootCmd()
|
||||||
rootCmd.SetArgs([]string{
|
rootCmd.SetArgs([]string{
|
||||||
"init", // Test the init cmd
|
"init", // Test the init cmd
|
||||||
"etherminttest", // Moniker
|
"etherminttest", // Moniker
|
||||||
@@ -23,6 +23,6 @@ func TestInitCmd(t *testing.T) {
|
|||||||
fmt.Sprintf("--%s=%s", flags.FlagChainID, "ethermint_9000-1"),
|
fmt.Sprintf("--%s=%s", flags.FlagChainID, "ethermint_9000-1"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := svrcmd.Execute(rootCmd, app.DefaultNodeHome)
|
err := svrcmd.Execute(rootCmd, chibaclonkd.EnvPrefix, app.DefaultNodeHome)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
|
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
@@ -19,7 +20,6 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
|
||||||
"github.com/tharsis/ethermint/crypto/hd"
|
"github.com/tharsis/ethermint/crypto/hd"
|
||||||
ethermint "github.com/tharsis/ethermint/types"
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
@@ -44,38 +44,44 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
|||||||
Args: cobra.ExactArgs(2),
|
Args: cobra.ExactArgs(2),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||||
cdc := clientCtx.Codec
|
|
||||||
|
|
||||||
serverCtx := server.GetServerContextFromCmd(cmd)
|
serverCtx := server.GetServerContextFromCmd(cmd)
|
||||||
config := serverCtx.Config
|
config := serverCtx.Config
|
||||||
|
|
||||||
config.SetRoot(clientCtx.HomeDir)
|
config.SetRoot(clientCtx.HomeDir)
|
||||||
|
|
||||||
|
var kr keyring.Keyring
|
||||||
addr, err := sdk.AccAddressFromBech32(args[0])
|
addr, err := sdk.AccAddressFromBech32(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||||
keyringBackend, err := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||||
if err != nil {
|
|
||||||
return err
|
if keyringBackend != "" && clientCtx.Keyring == nil {
|
||||||
}
|
var err error
|
||||||
// attempt to lookup address from Keybase if no address was provided
|
kr, err = keyring.New(
|
||||||
kb, err := keyring.New(
|
sdk.KeyringServiceName(),
|
||||||
sdk.KeyringServiceName(),
|
keyringBackend,
|
||||||
keyringBackend,
|
clientCtx.HomeDir,
|
||||||
clientCtx.HomeDir,
|
inBuf,
|
||||||
inBuf,
|
clientCtx.Codec,
|
||||||
hd.EthSecp256k1Option(),
|
hd.EthSecp256k1Option(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
kr = clientCtx.Keyring
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := kb.Key(args[0])
|
info, err := kr.Key(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get address from Keybase: %w", err)
|
return fmt.Errorf("failed to get address from Keyring: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = info.GetAddress()
|
addr, err = info.GetAddress()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get address from Keyring: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
coins, err := sdk.ParseCoinsNormalized(args[1])
|
coins, err := sdk.ParseCoinsNormalized(args[1])
|
||||||
@@ -142,7 +148,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
|||||||
return fmt.Errorf("failed to unmarshal genesis state: %w", err)
|
return fmt.Errorf("failed to unmarshal genesis state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
authGenState := authtypes.GetGenesisStateFromAppState(cdc, appState)
|
authGenState := authtypes.GetGenesisStateFromAppState(clientCtx.Codec, appState)
|
||||||
|
|
||||||
accs, err := authtypes.UnpackAccounts(authGenState.Accounts)
|
accs, err := authtypes.UnpackAccounts(authGenState.Accounts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -164,19 +170,19 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
|||||||
}
|
}
|
||||||
authGenState.Accounts = genAccs
|
authGenState.Accounts = genAccs
|
||||||
|
|
||||||
authGenStateBz, err := cdc.MarshalJSON(&authGenState)
|
authGenStateBz, err := clientCtx.Codec.MarshalJSON(&authGenState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal auth genesis state: %w", err)
|
return fmt.Errorf("failed to marshal auth genesis state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
appState[authtypes.ModuleName] = authGenStateBz
|
appState[authtypes.ModuleName] = authGenStateBz
|
||||||
|
|
||||||
bankGenState := banktypes.GetGenesisStateFromAppState(cdc, appState)
|
bankGenState := banktypes.GetGenesisStateFromAppState(clientCtx.Codec, appState)
|
||||||
bankGenState.Balances = append(bankGenState.Balances, balances)
|
bankGenState.Balances = append(bankGenState.Balances, balances)
|
||||||
bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances)
|
bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances)
|
||||||
bankGenState.Supply = bankGenState.Supply.Add(balances.Coins...)
|
bankGenState.Supply = bankGenState.Supply.Add(balances.Coins...)
|
||||||
|
|
||||||
bankGenStateBz, err := cdc.MarshalJSON(bankGenState)
|
bankGenStateBz, err := clientCtx.Codec.MarshalJSON(bankGenState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal bank genesis state: %w", err)
|
return fmt.Errorf("failed to marshal bank genesis state: %w", err)
|
||||||
}
|
}
|
||||||
@@ -194,7 +200,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
|
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
|
||||||
cmd.Flags().String(flags.FlagKeyringBackend, keyring.BackendFile, "Select keyring's backend (os|file|kwallet|pass|test)")
|
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().String(flagVestingAmt, "", "amount of coins for vesting accounts")
|
||||||
cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) 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")
|
cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
|
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
|
||||||
|
|
||||||
|
"github.com/tharsis/ethermint/app"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rootCmd, _ := NewRootCmd()
|
||||||
|
|
||||||
|
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
|
||||||
|
switch e := err.(type) {
|
||||||
|
case server.ErrorCode:
|
||||||
|
os.Exit(e.Code)
|
||||||
|
|
||||||
|
default:
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,22 +6,18 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/spf13/cast"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
|
||||||
tmlog "github.com/tendermint/tendermint/libs/log"
|
|
||||||
dbm "github.com/tendermint/tm-db"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/config"
|
"github.com/cosmos/cosmos-sdk/client/config"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||||
|
dbm "github.com/cosmos/cosmos-sdk/db"
|
||||||
|
"github.com/cosmos/cosmos-sdk/db/badgerdb"
|
||||||
sdkserver "github.com/cosmos/cosmos-sdk/server"
|
sdkserver "github.com/cosmos/cosmos-sdk/server"
|
||||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||||
"github.com/cosmos/cosmos-sdk/simapp/params"
|
"github.com/cosmos/cosmos-sdk/simapp/params"
|
||||||
"github.com/cosmos/cosmos-sdk/snapshots"
|
"github.com/cosmos/cosmos-sdk/snapshots"
|
||||||
|
snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
|
||||||
"github.com/cosmos/cosmos-sdk/store"
|
"github.com/cosmos/cosmos-sdk/store"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||||
@@ -29,6 +25,11 @@ import (
|
|||||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||||
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
tmcfg "github.com/tendermint/tendermint/config"
|
||||||
|
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||||
|
tmlog "github.com/tendermint/tendermint/libs/log"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/app"
|
"github.com/tharsis/ethermint/app"
|
||||||
ethermintclient "github.com/tharsis/ethermint/client"
|
ethermintclient "github.com/tharsis/ethermint/client"
|
||||||
@@ -41,14 +42,14 @@ import (
|
|||||||
ethermint "github.com/tharsis/ethermint/types"
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const EnvPrefix = "ETHERMINT"
|
const EnvPrefix = "CHIBACLONK"
|
||||||
|
|
||||||
// NewRootCmd creates a new root command for simd. It is called once in the
|
// NewRootCmd creates a new root command for simd. It is called once in the
|
||||||
// main function.
|
// main function.
|
||||||
func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
||||||
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
|
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
|
||||||
initClientCtx := client.Context{}.
|
initClientCtx := client.Context{}.
|
||||||
WithCodec(encodingConfig.Marshaler).
|
WithCodec(encodingConfig.Codec).
|
||||||
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
|
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
|
||||||
WithTxConfig(encodingConfig.TxConfig).
|
WithTxConfig(encodingConfig.TxConfig).
|
||||||
WithLegacyAmino(encodingConfig.Amino).
|
WithLegacyAmino(encodingConfig.Amino).
|
||||||
@@ -60,16 +61,19 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
|||||||
WithViper(EnvPrefix)
|
WithViper(EnvPrefix)
|
||||||
|
|
||||||
rootCmd := &cobra.Command{
|
rootCmd := &cobra.Command{
|
||||||
Use: "ethermintd",
|
Use: "chibaclonkd",
|
||||||
Short: "Ethermint Daemon",
|
Short: "Chiba-Clonk Daemon",
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
|
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
// set the default command outputs
|
// set the default command outputs
|
||||||
cmd.SetOut(cmd.OutOrStdout())
|
cmd.SetOut(cmd.OutOrStdout())
|
||||||
cmd.SetErr(cmd.ErrOrStderr())
|
cmd.SetErr(cmd.ErrOrStderr())
|
||||||
|
|
||||||
initClientCtx = client.ReadHomeFlag(initClientCtx, cmd)
|
initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
initClientCtx, err := config.ReadFromClientConfig(initClientCtx)
|
initClientCtx, err = config.ReadFromClientConfig(initClientCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -78,9 +82,11 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: replace AttoPhoton with bond denom
|
||||||
customAppTemplate, customAppConfig := servercfg.AppConfig(ethermint.AttoPhoton)
|
customAppTemplate, customAppConfig := servercfg.AppConfig(ethermint.AttoPhoton)
|
||||||
|
customTMConfig := initTendermintConfig()
|
||||||
|
|
||||||
return sdkserver.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig)
|
return sdkserver.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,12 +101,12 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
|||||||
genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
|
genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
|
||||||
),
|
),
|
||||||
genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
|
genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
|
||||||
genutilcli.MigrateGenesisCmd(),
|
genutilcli.MigrateGenesisCmd(), // TODO: shouldn't this include the local app version instead of the SDK?
|
||||||
genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
|
genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
|
||||||
genutilcli.ValidateGenesisCmd(app.ModuleBasics),
|
genutilcli.ValidateGenesisCmd(app.ModuleBasics),
|
||||||
AddGenesisAccountCmd(app.DefaultNodeHome),
|
AddGenesisAccountCmd(app.DefaultNodeHome),
|
||||||
tmcli.NewCompletionCmd(rootCmd, true),
|
tmcli.NewCompletionCmd(rootCmd, true),
|
||||||
ethermintclient.TestnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}),
|
ethermintclient.NewTestnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}),
|
||||||
debug.Cmd(),
|
debug.Cmd(),
|
||||||
config.Cmd(),
|
config.Cmd(),
|
||||||
)
|
)
|
||||||
@@ -115,10 +121,17 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
|||||||
txCommand(),
|
txCommand(),
|
||||||
ethermintclient.KeyCommands(app.DefaultNodeHome),
|
ethermintclient.KeyCommands(app.DefaultNodeHome),
|
||||||
)
|
)
|
||||||
rootCmd = srvflags.AddTxFlags(rootCmd)
|
|
||||||
|
rootCmd, err := srvflags.AddTxFlags(rootCmd)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
// add rosetta
|
// add rosetta
|
||||||
rootCmd.AddCommand(sdkserver.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Marshaler))
|
rootCmd.AddCommand(sdkserver.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec))
|
||||||
|
|
||||||
|
// Add flags for GQL server.
|
||||||
|
rootCmd = srvflags.AddGQLFlags(rootCmd)
|
||||||
|
|
||||||
return rootCmd, encodingConfig
|
return rootCmd, encodingConfig
|
||||||
}
|
}
|
||||||
@@ -127,6 +140,18 @@ func addModuleInitFlags(startCmd *cobra.Command) {
|
|||||||
crisis.AddModuleInitFlags(startCmd)
|
crisis.AddModuleInitFlags(startCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initTendermintConfig helps to override default Tendermint Config values.
|
||||||
|
// return tmcfg.DefaultConfig if no custom configuration is required for the application.
|
||||||
|
func initTendermintConfig() *tmcfg.Config {
|
||||||
|
cfg := tmcfg.DefaultConfig()
|
||||||
|
|
||||||
|
// these values put a higher strain on node memory
|
||||||
|
// cfg.P2P.MaxNumInboundPeers = 100
|
||||||
|
// cfg.P2P.MaxNumOutboundPeers = 40
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
func queryCommand() *cobra.Command {
|
func queryCommand() *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "query",
|
Use: "query",
|
||||||
@@ -182,7 +207,7 @@ type appCreator struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newApp is an appCreator
|
// newApp is an appCreator
|
||||||
func (a appCreator) newApp(logger tmlog.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
|
func (a appCreator) newApp(logger tmlog.Logger, db dbm.DBConnection, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
|
||||||
var cache sdk.MultiStorePersistentCache
|
var cache sdk.MultiStorePersistentCache
|
||||||
|
|
||||||
if cast.ToBool(appOpts.Get(sdkserver.FlagInterBlockCache)) {
|
if cast.ToBool(appOpts.Get(sdkserver.FlagInterBlockCache)) {
|
||||||
@@ -200,7 +225,7 @@ func (a appCreator) newApp(logger tmlog.Logger, db dbm.DB, traceStore io.Writer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots")
|
snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots")
|
||||||
snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir)
|
snapshotDB, err := badgerdb.NewDB(filepath.Join(snapshotDir, "metadata"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -208,6 +233,10 @@ func (a appCreator) newApp(logger tmlog.Logger, db dbm.DB, traceStore io.Writer,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
snapshotOptions := snapshottypes.NewSnapshotOptions(
|
||||||
|
cast.ToUint64(appOpts.Get(sdkserver.FlagStateSyncSnapshotInterval)),
|
||||||
|
cast.ToUint32(appOpts.Get(sdkserver.FlagStateSyncSnapshotKeepRecent)),
|
||||||
|
)
|
||||||
|
|
||||||
ethermintApp := app.NewEthermintApp(
|
ethermintApp := app.NewEthermintApp(
|
||||||
logger, db, traceStore, true, skipUpgradeHeights,
|
logger, db, traceStore, true, skipUpgradeHeights,
|
||||||
@@ -223,9 +252,7 @@ func (a appCreator) newApp(logger tmlog.Logger, db dbm.DB, traceStore io.Writer,
|
|||||||
baseapp.SetInterBlockCache(cache),
|
baseapp.SetInterBlockCache(cache),
|
||||||
baseapp.SetTrace(cast.ToBool(appOpts.Get(sdkserver.FlagTrace))),
|
baseapp.SetTrace(cast.ToBool(appOpts.Get(sdkserver.FlagTrace))),
|
||||||
baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(sdkserver.FlagIndexEvents))),
|
baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(sdkserver.FlagIndexEvents))),
|
||||||
baseapp.SetSnapshotStore(snapshotStore),
|
baseapp.SetSnapshot(snapshotStore, snapshotOptions),
|
||||||
baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(sdkserver.FlagStateSyncSnapshotInterval))),
|
|
||||||
baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(sdkserver.FlagStateSyncSnapshotKeepRecent))),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return ethermintApp
|
return ethermintApp
|
||||||
@@ -234,7 +261,7 @@ func (a appCreator) newApp(logger tmlog.Logger, db dbm.DB, traceStore io.Writer,
|
|||||||
// appExport creates a new simapp (optionally at a given height)
|
// appExport creates a new simapp (optionally at a given height)
|
||||||
// and exports state.
|
// and exports state.
|
||||||
func (a appCreator) appExport(
|
func (a appCreator) appExport(
|
||||||
logger tmlog.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string,
|
logger tmlog.Logger, db dbm.DBConnection, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string,
|
||||||
appOpts servertypes.AppOptions,
|
appOpts servertypes.AppOptions,
|
||||||
) (servertypes.ExportedApp, error) {
|
) (servertypes.ExportedApp, error) {
|
||||||
var ethermintApp *app.EthermintApp
|
var ethermintApp *app.EthermintApp
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Bech32Prefix defines the Bech32 prefix used for EthAccounts
|
// Bech32Prefix defines the Bech32 prefix used for EthAccounts
|
||||||
Bech32Prefix = "ethm"
|
Bech32Prefix = ethermint.Bech32MainPrefix
|
||||||
|
|
||||||
// Bech32PrefixAccAddr defines the Bech32 prefix of an account's address
|
// Bech32PrefixAccAddr defines the Bech32 prefix of an account's address
|
||||||
Bech32PrefixAccAddr = Bech32Prefix
|
Bech32PrefixAccAddr = Bech32Prefix
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/app"
|
|
||||||
cmdcfg "github.com/tharsis/ethermint/cmd/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
setupConfig()
|
|
||||||
cmdcfg.RegisterDenoms()
|
|
||||||
|
|
||||||
rootCmd, _ := NewRootCmd()
|
|
||||||
|
|
||||||
if err := svrcmd.Execute(rootCmd, app.DefaultNodeHome); err != nil {
|
|
||||||
switch e := err.(type) {
|
|
||||||
case server.ErrorCode:
|
|
||||||
os.Exit(e.Code)
|
|
||||||
|
|
||||||
default:
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupConfig() {
|
|
||||||
// set the address prefixes
|
|
||||||
config := sdk.GetConfig()
|
|
||||||
cmdcfg.SetBech32Prefixes(config)
|
|
||||||
cmdcfg.SetBip44CoinType(config)
|
|
||||||
config.Seal()
|
|
||||||
}
|
|
||||||
@@ -10,4 +10,5 @@ import (
|
|||||||
// RegisterInterfaces register the Ethermint key concrete types.
|
// RegisterInterfaces register the Ethermint key concrete types.
|
||||||
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
||||||
registry.RegisterImplementations((*cryptotypes.PubKey)(nil), ðsecp256k1.PubKey{})
|
registry.RegisterImplementations((*cryptotypes.PubKey)(nil), ðsecp256k1.PubKey{})
|
||||||
|
registry.RegisterImplementations((*cryptotypes.PrivKey)(nil), ðsecp256k1.PrivKey{})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@@ -12,12 +13,14 @@ import (
|
|||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||||
|
|
||||||
cryptocodec "github.com/tharsis/ethermint/crypto/codec"
|
cryptocodec "github.com/tharsis/ethermint/crypto/codec"
|
||||||
ethermint "github.com/tharsis/ethermint/types"
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var protoCodec codec.Codec
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
protoCodec = codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
|
||||||
amino := codec.NewLegacyAmino()
|
amino := codec.NewLegacyAmino()
|
||||||
cryptocodec.RegisterCrypto(amino)
|
cryptocodec.RegisterCrypto(amino)
|
||||||
}
|
}
|
||||||
@@ -28,7 +31,7 @@ func TestKeyring(t *testing.T) {
|
|||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
mockIn := strings.NewReader("")
|
mockIn := strings.NewReader("")
|
||||||
|
|
||||||
kr, err := keyring.New("ethermint", keyring.BackendTest, dir, mockIn, EthSecp256k1Option())
|
kr, err := keyring.New("ethermint", keyring.BackendTest, dir, mockIn, protoCodec, EthSecp256k1Option())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// fail in retrieving key
|
// fail in retrieving key
|
||||||
@@ -40,9 +43,8 @@ func TestKeyring(t *testing.T) {
|
|||||||
info, mnemonic, err := kr.NewMnemonic("foo", keyring.English, ethermint.BIP44HDPath, keyring.DefaultBIP39Passphrase, EthSecp256k1)
|
info, mnemonic, err := kr.NewMnemonic("foo", keyring.English, ethermint.BIP44HDPath, keyring.DefaultBIP39Passphrase, EthSecp256k1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, mnemonic)
|
require.NotEmpty(t, mnemonic)
|
||||||
require.Equal(t, "foo", info.GetName())
|
require.Equal(t, "foo", info.Name)
|
||||||
require.Equal(t, "local", info.GetType().String())
|
require.Equal(t, "local", info.GetType().String())
|
||||||
require.Equal(t, EthSecp256k1Type, info.GetAlgo())
|
|
||||||
|
|
||||||
hdPath := ethermint.BIP44HDPath
|
hdPath := ethermint.BIP44HDPath
|
||||||
|
|
||||||
|
|||||||
+46
-32
@@ -1,73 +1,87 @@
|
|||||||
version: "3"
|
version: "3"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
ethermintdnode0:
|
chibaclonkdnode0:
|
||||||
container_name: ethermintdnode0
|
container_name: chibaclonkdnode0
|
||||||
image: "ethermintd/node"
|
image: "chibaclonkd/node"
|
||||||
ports:
|
ports:
|
||||||
- "26657:26657"
|
- "26656-26657:26656-26657"
|
||||||
|
- "1317:1317"
|
||||||
|
- "9090:9090"
|
||||||
- "8545:8545"
|
- "8545:8545"
|
||||||
- "8546:8546"
|
- "8546:8546"
|
||||||
- "8125:8125"
|
- "8125:8125"
|
||||||
environment:
|
environment:
|
||||||
- ID=0
|
- ID=0
|
||||||
- LOG=${LOG:-ethermintd.log}
|
- LOG=${LOG:-chibaclonkd.log}
|
||||||
volumes:
|
volumes:
|
||||||
- ./localnet-setup/node0/ethermintd:/ethermint:Z
|
- ./localnet-setup/node0/chibaclonkd:/chibaclonk:Z
|
||||||
networks:
|
networks:
|
||||||
- localnet
|
localnet:
|
||||||
entrypoint: "bash start-docker.sh"
|
ipv4_address: 192.168.10.1
|
||||||
|
|
||||||
ethermintdnode1:
|
chibaclonkdnode1:
|
||||||
container_name: ethermintdnode1
|
container_name: chibaclonkdnode1
|
||||||
image: "ethermintd/node"
|
image: "chibaclonkd/node"
|
||||||
ports:
|
ports:
|
||||||
- "26658:26657"
|
- "26666-26667:26656-26657"
|
||||||
|
- "1318:1317"
|
||||||
|
- "9091:9090"
|
||||||
- "8555:8545"
|
- "8555:8545"
|
||||||
- "8556:8546"
|
- "8556:8546"
|
||||||
- "8126:8125"
|
- "8126:8125"
|
||||||
environment:
|
environment:
|
||||||
- ID=1
|
- ID=1
|
||||||
- LOG=${LOG:-ethermintd.log}
|
- LOG=${LOG:-chibaclonkd.log}
|
||||||
volumes:
|
volumes:
|
||||||
- ./localnet-setup/node1/ethermintd:/ethermint:Z
|
- ./localnet-setup/node1/chibaclonkd:/chibaclonk:Z
|
||||||
networks:
|
networks:
|
||||||
- localnet
|
localnet:
|
||||||
entrypoint: "bash start-docker.sh"
|
ipv4_address: 192.168.10.2
|
||||||
|
|
||||||
ethermintdnode2:
|
chibaclonkdnode2:
|
||||||
container_name: ethermintdnode2
|
container_name: chibaclonkdnode2
|
||||||
image: "ethermintd/node"
|
image: "chibaclonkd/node"
|
||||||
environment:
|
environment:
|
||||||
- ID=2
|
- ID=2
|
||||||
- LOG=${LOG:-ethermintd.log}
|
- LOG=${LOG:-chibaclonkd.log}
|
||||||
ports:
|
ports:
|
||||||
- "26659:26657"
|
- "26676-26677:26656-26657"
|
||||||
|
- "1319:1317"
|
||||||
|
- "9092:9090"
|
||||||
- "8565:8545"
|
- "8565:8545"
|
||||||
- "8566:8546"
|
- "8566:8546"
|
||||||
- "8127:8125"
|
- "8127:8125"
|
||||||
volumes:
|
volumes:
|
||||||
- ./localnet-setup/node2/ethermintd:/ethermint:Z
|
- ./localnet-setup/node2/chibaclonkd:/chibaclonk:Z
|
||||||
networks:
|
networks:
|
||||||
- localnet
|
localnet:
|
||||||
entrypoint: "bash start-docker.sh"
|
ipv4_address: 192.168.10.3
|
||||||
|
|
||||||
ethermintdnode3:
|
chibaclonkdnode3:
|
||||||
container_name: ethermintdnode3
|
container_name: chibaclonkdnode3
|
||||||
image: "ethermintd/node"
|
image: "chibaclonkd/node"
|
||||||
environment:
|
environment:
|
||||||
- ID=3
|
- ID=3
|
||||||
- LOG=${LOG:-ethermintd.log}
|
- LOG=${LOG:-chibaclonkd.log}
|
||||||
ports:
|
ports:
|
||||||
- "26660:26657"
|
- "26686-26687:26656-26657"
|
||||||
|
- "1320:1317"
|
||||||
|
- "9093:9090"
|
||||||
- "8575:8545"
|
- "8575:8545"
|
||||||
- "8576:8546"
|
- "8576:8546"
|
||||||
- "8128:8125"
|
- "8128:8125"
|
||||||
volumes:
|
volumes:
|
||||||
- ./localnet-setup/node3/ethermintd:/ethermint:Z
|
- ./localnet-setup/node3/chibaclonkd:/chibaclonk:Z
|
||||||
networks:
|
networks:
|
||||||
- localnet
|
localnet:
|
||||||
entrypoint: "bash start-docker.sh"
|
ipv4_address: 192.168.10.4
|
||||||
|
# entrypoint: "sh scripts/start-docker.sh"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
localnet:
|
localnet:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
driver: default
|
||||||
|
config:
|
||||||
|
- subnet: 192.168.10.0/16
|
||||||
@@ -1,512 +0,0 @@
|
|||||||
<template lang="pug">
|
|
||||||
div
|
|
||||||
.search__container
|
|
||||||
.search(@click="$emit('search', true)")
|
|
||||||
.search__icon
|
|
||||||
icon-search
|
|
||||||
.search__text Search
|
|
||||||
.h1 {{$frontmatter.title}}
|
|
||||||
.intro
|
|
||||||
.p {{$frontmatter.description}}
|
|
||||||
.h2 Getting Started
|
|
||||||
.p__alt Read all about Ethermint or dive straight into the code with guides.
|
|
||||||
.features
|
|
||||||
router-link(to="/quickstart").features__item.features__item__light
|
|
||||||
.features__item__image
|
|
||||||
icon-rocket.features__item__image__img
|
|
||||||
.features__item__text
|
|
||||||
.features__item__text__h2 read
|
|
||||||
.features__item__text__h1 Quick start
|
|
||||||
.features__item__text__p Deploy your own node, setup your testnet and more.
|
|
||||||
router-link(to="/guides").features__item.features__item__dark
|
|
||||||
.features__item__image
|
|
||||||
icon-code.features__item__image__img
|
|
||||||
.features__item__text
|
|
||||||
.features__item__text__h2 use
|
|
||||||
.features__item__text__h1 Guides
|
|
||||||
.features__item__text__p Follow guides to using polular Ethereum tools with Ethermint.
|
|
||||||
.sections__wrapper
|
|
||||||
.h2 Explore Ethermint
|
|
||||||
.p__alt Get familiar with Ethermint and explore its main concepts.
|
|
||||||
.sections
|
|
||||||
router-link.sections__item(tag="a" :to="section.url" v-for="section in $frontmatter.sections")
|
|
||||||
component(:is="`tm-icon-${section.icon}`").sections__item__icon
|
|
||||||
.sections__item__wrapper
|
|
||||||
.sections__item__title {{section.title}}
|
|
||||||
.sections__item__desc {{section.desc}}
|
|
||||||
.h2 Explore the stack
|
|
||||||
.p__alt Check out the docs for the various parts of the Ethermint stack.
|
|
||||||
.stack
|
|
||||||
a.stack__item(:href="item.url" v-for="item in $frontmatter.stack" :style="{'--accent': item.color, '--opacity': '5%'}")
|
|
||||||
.stack__item__wrapper
|
|
||||||
component(:is="`tm-logo-${item.label}`" :color="item.color" height="100px").stack__item__logo
|
|
||||||
svg(width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg").stack__item__icon
|
|
||||||
path(d="M1.07239 14.4697C0.779499 14.7626 0.779499 15.2374 1.07239 15.5303C1.36529 15.8232 1.84016 15.8232 2.13305 15.5303L1.07239 14.4697ZM15.7088 1.95457C16.0017 1.66168 16.0017 1.18681 15.7088 0.893912C15.4159 0.601019 14.941 0.601019 14.6482 0.893912L15.7088 1.95457ZM15.6027 1H16.3527C16.3527 0.585786 16.0169 0.25 15.6027 0.25V1ZM5.4209 0.25C5.00669 0.25 4.6709 0.585786 4.6709 1C4.6709 1.41421 5.00669 1.75 5.4209 1.75V0.25ZM14.8527 11.1818C14.8527 11.596 15.1885 11.9318 15.6027 11.9318C16.0169 11.9318 16.3527 11.596 16.3527 11.1818H14.8527ZM2.13305 15.5303L15.7088 1.95457L14.6482 0.893912L1.07239 14.4697L2.13305 15.5303ZM15.6027 0.25H5.4209V1.75H15.6027V0.25ZM16.3527 11.1818V1H14.8527V11.1818H16.3527Z" fill="#DADCE6")
|
|
||||||
div
|
|
||||||
.stack__item__h1 {{item.title}}
|
|
||||||
.stack__item__p {{item.desc}}
|
|
||||||
tm-help-support
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
/deep/ {
|
|
||||||
.container h1 {
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: rgba(22, 25, 49, 0.65);
|
|
||||||
padding-top: 1rem;
|
|
||||||
width: calc(var(--aside-width) - 6rem);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.15s ease-out;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: var(--color-text, black);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-top: 1rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon {
|
|
||||||
width: 1.5rem;
|
|
||||||
height: 1.5rem;
|
|
||||||
fill: #aaa;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
transition: fill 0.15s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover &__icon {
|
|
||||||
fill: var(--color-text, black);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h1 {
|
|
||||||
font-size: 3rem;
|
|
||||||
font-weight: 700;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
line-height: 3.25rem;
|
|
||||||
letter-spacing: -0.02em;
|
|
||||||
padding-top: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h2 {
|
|
||||||
font-size: 2rem;
|
|
||||||
font-weight: 700;
|
|
||||||
margin-top: 4.5rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
line-height: 2.25rem;
|
|
||||||
letter-spacing: -0.01em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
line-height: 2.25rem;
|
|
||||||
|
|
||||||
&__alt {
|
|
||||||
margin-top: 0.75rem;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
line-height: 1.75rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.features {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
||||||
gap: 1.5rem;
|
|
||||||
margin-bottom: 5rem;
|
|
||||||
margin-top: 2.25rem;
|
|
||||||
|
|
||||||
&__item {
|
|
||||||
cursor: pointer;
|
|
||||||
display: grid;
|
|
||||||
grid-auto-flow: column;
|
|
||||||
grid-template-columns: minmax(6rem, 1fr) 2fr;
|
|
||||||
box-shadow: 0px 2px 4px rgba(22, 25, 49, 0.05), 0px 0px 1px rgba(22, 25, 49, 0.2), 0px 0.5px 0px rgba(22, 25, 49, 0.05);
|
|
||||||
position: relative;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
background: linear-gradient(281.08deg, #FFFFFF 48.96%, #E8F3FF 100%);
|
|
||||||
outline: none;
|
|
||||||
transition: box-shadow 0.25s ease-out, transform 0.25s ease-out, opacity 0.4s ease-out;
|
|
||||||
|
|
||||||
&:hover:not(:active), &:focus {
|
|
||||||
box-shadow: 0px 12px 24px rgba(22, 25, 49, 0.07), 0px 4px 8px rgba(22, 25, 49, 0.05), 0px 1px 0px rgba(22, 25, 49, 0.05);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
transition-duration: 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
opacity: 0.7;
|
|
||||||
transition-duration: 0s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__dark {
|
|
||||||
background: linear-gradient(112.22deg, #161831 0%, #2E3148 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__dark &__text__h2 {
|
|
||||||
color: white;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__dark &__text__h1 {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__dark &__text__p {
|
|
||||||
color: white;
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 0.75rem;
|
|
||||||
width: 1rem;
|
|
||||||
height: 1rem;
|
|
||||||
fill: white;
|
|
||||||
opacity: 0.35;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover &__icon {
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__image {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
align-self: center;
|
|
||||||
max-height: 10rem;
|
|
||||||
transition: transform 0.2s ease-out;
|
|
||||||
|
|
||||||
&__img {
|
|
||||||
max-height: 14rem;
|
|
||||||
max-width: 10rem;
|
|
||||||
min-width: 8rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover:not(:active) &__image {
|
|
||||||
transform: translateY(-0.25rem) scale(1.02);
|
|
||||||
transition-duration: 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__text {
|
|
||||||
padding: 1.75rem 2rem 2rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
&__h2 {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
letter-spacing: 0.2em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: var(--color-text-dim, inherit);
|
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__h1 {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
color: var(--color-text, black);
|
|
||||||
line-height: 1.75rem;
|
|
||||||
letter-spacing: 0.01em;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-top: 0.25rem;
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__p {
|
|
||||||
color: var(--color-text-dim, inherit);
|
|
||||||
font-size: 0.875rem;
|
|
||||||
letter-spacing: 0.03em;
|
|
||||||
line-height: 1.25rem;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sections {
|
|
||||||
display: grid;
|
|
||||||
margin-top: 3rem;
|
|
||||||
margin-bottom: 5rem;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
||||||
gap: 1.5rem;
|
|
||||||
|
|
||||||
&__item {
|
|
||||||
position: relative;
|
|
||||||
color: initial;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
padding: 1.5rem 1.5rem 1.5rem 5.5rem;
|
|
||||||
box-shadow: 0px 2px 4px rgba(22, 25, 49, 0.05), 0px 0px 1px rgba(22, 25, 49, 0.2), 0px 0.5px 0px rgba(22, 25, 49, 0.05);
|
|
||||||
transition: box-shadow 0.25s ease-out, transform 0.25s ease-out, opacity 0.4s ease-out;
|
|
||||||
|
|
||||||
&:hover:not(:active) {
|
|
||||||
box-shadow: 0px 12px 24px rgba(22, 25, 49, 0.07), 0px 4px 8px rgba(22, 25, 49, 0.05), 0px 1px 0px rgba(22, 25, 49, 0.05);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
transition-duration: 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transition-duration: 0s;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon {
|
|
||||||
position: absolute;
|
|
||||||
left: 1.25rem;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 3rem;
|
|
||||||
height: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__title {
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__desc {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
line-height: 1.25rem;
|
|
||||||
color: var(--color-text-dim, inherit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stack {
|
|
||||||
display: grid;
|
|
||||||
gap: 1.5rem;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
||||||
margin-bottom: 4rem;
|
|
||||||
|
|
||||||
&__item {
|
|
||||||
position: relative;
|
|
||||||
min-height: 120px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 2rem 1.25rem;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
box-shadow: 0px 2px 4px rgba(22, 25, 49, 0.05), 0px 0px 1px rgba(22, 25, 49, 0.2), 0px 0.5px 0px rgba(22, 25, 49, 0.05);
|
|
||||||
color: var(--color-text, black);
|
|
||||||
background: white;
|
|
||||||
transition: box-shadow 0.25s ease-out, transform 0.25s ease-out, opacity 0.4s ease-out;
|
|
||||||
|
|
||||||
&:hover:not(:active) {
|
|
||||||
box-shadow: 0px 12px 24px rgba(22, 25, 49, 0.07), 0px 4px 8px rgba(22, 25, 49, 0.05), 0px 1px 0px rgba(22, 25, 49, 0.05);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
transition-duration: 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
opacity: 0.7;
|
|
||||||
transition-duration: 0s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 1rem;
|
|
||||||
opacity: 0.35;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover &__icon {
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__h1 {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
line-height: 1.5rem;
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__p {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
color: rgba(22, 25, 49, 0.65);
|
|
||||||
line-height: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
display: grid;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
gap: 1.25rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
content: '';
|
|
||||||
width: 50%;
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(to right, var(--accent), rgba(255, 255, 255, 0));
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
opacity: 0.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__logo {
|
|
||||||
height: 72px;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1136px) {
|
|
||||||
.p {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
line-height: 1.75rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 832px) {
|
|
||||||
.h1 {
|
|
||||||
padding-top: 3.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search__container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 752px) {
|
|
||||||
.search {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 500px) {
|
|
||||||
.h1 {
|
|
||||||
font-size: 2rem;
|
|
||||||
line-height: 2.25rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h2 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
line-height: 2rem;
|
|
||||||
margin-top: 3rem;
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p__alt {
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.features {
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
|
||||||
|
|
||||||
&__item {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
&:not(:active) {
|
|
||||||
box-shadow: 0px 24px 40px rgba(0, 0, 0, 0.1), 0px 10px 16px rgba(0, 0, 0, 0.08), 0px 1px 0px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__image {
|
|
||||||
max-height: 9rem;
|
|
||||||
padding-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__text {
|
|
||||||
padding: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sections {
|
|
||||||
gap: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 2rem;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
|
||||||
margin-left: -1rem;
|
|
||||||
margin-right: -1rem;
|
|
||||||
|
|
||||||
&__item {
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding: 1.25rem 1rem 0 5.5rem;
|
|
||||||
|
|
||||||
&, &:hover:not(:active) {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon {
|
|
||||||
top: 1rem;
|
|
||||||
left: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
padding-bottom: 1.25rem;
|
|
||||||
border-bottom: 1px solid rgba(140, 145, 177, 0.32);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child .sections__item__wrapper {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
position: relative;
|
|
||||||
padding: 0.1px 1rem 1rem;
|
|
||||||
background: white;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
position: absolute;
|
|
||||||
content: '';
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
box-shadow: 0px 24px 40px rgba(0, 0, 0, 0.1), 0px 10px 16px rgba(0, 0, 0, 0.08), 0px 1px 0px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stack {
|
|
||||||
gap: 0.75rem;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
|
|
||||||
&__item {
|
|
||||||
padding: 1.25rem;
|
|
||||||
|
|
||||||
&:not(:active) {
|
|
||||||
box-shadow: 0px 24px 40px rgba(22, 25, 49, 0.1), 0px 10px 16px rgba(22, 25, 49, 0.08), 0px 1px 0px rgba(22, 25, 49, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
grid-template-columns: 3rem 1fr;
|
|
||||||
text-align: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__h1 {
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg width="100%" height="100%" viewBox="0 0 165 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<rect x="15.2" y="0.399879" width="135.6" height="115.2" rx="4.8" stroke="url(#paint0_linear)" stroke-width="0.6"/>
|
|
||||||
<rect x="0.199982" y="46.5999" width="145.2" height="94.8" transform="rotate(-15 0.199982 46.5999)" fill="url(#paint1_linear)"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M87.4269 40.4409C88.0849 40.5195 88.5547 41.1167 88.4761 41.7747L81.1977 102.735C81.1192 103.393 80.522 103.863 79.8639 103.784C79.2059 103.706 78.7361 103.109 78.8147 102.451L86.0931 41.4902C86.1716 40.8321 86.7688 40.3624 87.4269 40.4409ZM60.8853 56.9452C61.4443 57.3012 61.6089 58.0429 61.253 58.6019L46.1657 82.2944L71.0008 95.0057C71.5907 95.3076 71.8242 96.0307 71.5223 96.6206C71.2203 97.2106 70.4973 97.4441 69.9073 97.1421L43.8986 83.8301L42.7249 83.2294L43.4331 82.1173L59.2286 57.3128C59.5846 56.7538 60.3263 56.5892 60.8853 56.9452ZM94.2871 47.9121C93.6966 47.6112 92.9739 47.8459 92.673 48.4364C92.3721 49.0269 92.6068 49.7495 93.1973 50.0504L118.014 62.6977L102.942 86.455C102.587 87.0146 102.753 87.7561 103.313 88.1111C103.872 88.4661 104.614 88.3003 104.969 87.7406L120.747 62.8701L121.453 61.7568L120.278 61.1581L94.2871 47.9121Z" fill="#8CA9C6"/>
|
|
||||||
<path d="M34.1 14.7999C34.1 17.2852 32.0853 19.2999 29.6 19.2999V19.8999C32.4167 19.8999 34.7 17.6165 34.7 14.7999H34.1ZM29.6 10.2999C32.0853 10.2999 34.1 12.3146 34.1 14.7999H34.7C34.7 11.9832 32.4167 9.69988 29.6 9.69988V10.2999ZM25.1 14.7999C25.1 12.3146 27.1147 10.2999 29.6 10.2999V9.69988C26.7834 9.69988 24.5 11.9832 24.5 14.7999H25.1ZM29.6 19.2999C27.1147 19.2999 25.1 17.2852 25.1 14.7999H24.5C24.5 17.6165 26.7834 19.8999 29.6 19.8999V19.2999ZM48.4999 14.7999C48.4999 17.2852 46.4852 19.2999 43.9999 19.2999V19.8999C46.8166 19.8999 49.0999 17.6165 49.0999 14.7999H48.4999ZM43.9999 10.2999C46.4852 10.2999 48.4999 12.3146 48.4999 14.7999H49.0999C49.0999 11.9832 46.8166 9.69988 43.9999 9.69988V10.2999ZM39.4999 14.7999C39.4999 12.3146 41.5147 10.2999 43.9999 10.2999V9.69988C41.1833 9.69988 38.8999 11.9832 38.8999 14.7999H39.4999ZM43.9999 19.2999C41.5147 19.2999 39.4999 17.2852 39.4999 14.7999H38.8999C38.8999 17.6165 41.1833 19.8999 43.9999 19.8999V19.2999ZM58.4 19.8999C61.2167 19.8999 63.5 17.6165 63.5 14.7999H62.9C62.9 17.2852 60.8853 19.2999 58.4 19.2999V19.8999ZM53.3 14.7999C53.3 17.6165 55.5834 19.8999 58.4 19.8999V19.2999C55.9147 19.2999 53.9 17.2852 53.9 14.7999H53.3ZM58.4 9.69988C55.5834 9.69988 53.3 11.9832 53.3 14.7999H53.9C53.9 12.3146 55.9147 10.2999 58.4 10.2999V9.69988ZM63.5 14.7999C63.5 11.9832 61.2167 9.69988 58.4 9.69988V10.2999C60.8853 10.2999 62.9 12.3146 62.9 14.7999H63.5Z" fill="url(#paint3_linear)"/>
|
|
||||||
<path d="M15.2 29.1999H150.8" stroke="url(#paint4_linear)" stroke-width="0.6"/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear" x1="120.998" y1="62.4" x2="120.998" y2="177.6" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#8CA9C6"/>
|
|
||||||
<stop offset="1" stop-color="#336699"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint1_linear" x1="127.715" y1="148.887" x2="147.74" y2="281.816" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#336699"/>
|
|
||||||
<stop offset="1" stop-color="#8CA9C6"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint2_linear" x1="125.577" y1="107.749" x2="125.258" y2="229.399" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#8CA9C6"/>
|
|
||||||
<stop offset="1" stop-color="#336699"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint3_linear" x1="81.9981" y1="72" x2="81.9981" y2="97.2" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#8CA9C6"/>
|
|
||||||
<stop offset="1" stop-color="#336699"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint4_linear" x1="120.998" y1="67.2" x2="120.998" y2="163.2" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#8CA9C6"/>
|
|
||||||
<stop offset="1" stop-color="#336699"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg width="100%" height="100%" viewBox="0 0 150 230" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M129.04 81.9366L135.681 58.78L125.153 20.3152L95.8426 47.3566L89.2025 70.5132L105.801 87.8034L129.04 81.9366Z" fill="url(#paint0_linear)"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M122.412 105.051L129.028 81.9786L112.418 64.7302L89.1905 70.5552L82.5745 93.6277L99.1854 110.876L122.412 105.051Z" fill="url(#paint1_linear)"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M96.9404 193.882L115.64 128.671L98.9611 111.437L75.6844 117.214L56.5251 182.294L76.9628 188.154L96.9404 193.882Z" fill="url(#paint2_linear)"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M42.0642 201.869L93.0233 133.456L51.5928 127.542L12.0095 178.467L42.0642 201.869Z" fill="url(#paint3_linear)"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M98.6275 218.088L92.8579 134.032L131.018 150.902L135.385 214.524L98.6275 218.088Z" fill="url(#paint4_linear)"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.4626 196.23L99.4743 110.96L58.1472 105.081L5.50019 172.841L35.4626 196.23Z" stroke="url(#paint5_linear)" stroke-width="0.7"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M106.575 217.245L99.4741 110.959L137.392 127.801L143.167 213.533L106.575 217.245Z" stroke="url(#paint6_linear)" stroke-width="0.7"/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear" x1="171.808" y1="70.3402" x2="210.702" y2="119.532" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
|
||||||
<stop offset="1" stop-color="#8CAAC6"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint1_linear" x1="161.105" y1="107.665" x2="185.783" y2="154.845" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
|
||||||
<stop offset="1" stop-color="#8CAAC6"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint2_linear" x1="144.638" y1="164.499" x2="188.211" y2="213.994" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
|
||||||
<stop offset="1" stop-color="#8CAAC6"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint3_linear" x1="112.6" y1="179.034" x2="154.555" y2="254.491" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
|
||||||
<stop offset="1" stop-color="#8CAAC6"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint4_linear" x1="173.74" y1="196.982" x2="215.848" y2="270.124" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#336699" stop-opacity="0.91"/>
|
|
||||||
<stop offset="1" stop-color="#8CAAC6"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint5_linear" x1="108.253" y1="125.86" x2="80.7963" y2="221.613" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#8CA9C6"/>
|
|
||||||
<stop offset="1" stop-color="#336699"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint6_linear" x1="177.248" y1="145.644" x2="149.626" y2="241.973" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#8CA9C6"/>
|
|
||||||
<stop offset="1" stop-color="#336699"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<rect width="48" height="48" fill="white"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.2612 1.52098L45.3579 24.8028L24.2611 47.4575L2.62622 24.8029L24.2612 1.52098ZM5.63765 24.5003L23.2519 33.396V5.54515L5.63765 24.5003ZM25.2519 5.59283V33.3772L42.3871 24.5028L25.2519 5.59283ZM39.3349 28.3358L25.2519 35.6295V43.4588L39.3349 28.3358ZM23.2519 43.5049V35.6365L8.73749 28.3064L23.2519 43.5049Z" fill="#7499BF"/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<svg width="100%" height="100%" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path opacity="0.6" d="M39.9917 30.4542L17.5 40.6792L39.9917 53.975L62.4875 40.6792L39.9917 30.4542Z" fill="black"/>
|
|
||||||
<path opacity="0.45" d="M17.5083 40.6791L40 53.975V30.4541V3.35828L17.5083 40.6791Z" fill="black"/>
|
|
||||||
<path opacity="0.8" d="M40 3.35828V30.4541V53.975L62.4917 40.6791L40 3.35828Z" fill="black"/>
|
|
||||||
<path opacity="0.45" d="M17.5 44.9458L39.9917 76.6416V58.2333L17.5 44.9458Z" fill="black"/>
|
|
||||||
<path opacity="0.8" d="M39.9917 58.2333V76.6416L62.5 44.9458L39.9917 58.2333Z" fill="black"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<svg width="100%" height="100%" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M63.3188 38.6786L40.0002 52.4512L16.6724 38.6786L40.0002 0L63.3188 38.6786ZM40.0001 75.9369L16.6724 43.0953L40.0001 56.8679L63.3371 43.0953L40.0001 75.9369ZM40.0106 22.5689C41.8663 22.5689 43.7036 22.9206 45.4097 23.5941C45.495 24.2572 45.5265 24.9236 45.5046 25.5884C43.8027 24.7855 41.9183 24.3629 40.0106 24.3629C33.1513 24.3629 27.5045 29.8641 27.1843 36.7318C30.4764 38.4276 34.3665 38.5945 37.7989 37.2405C38.3645 37.6723 38.9596 38.064 39.5805 38.4118C37.6113 39.3875 35.4391 39.9162 33.2435 39.9478C33.1741 39.9489 33.1043 39.9494 33.035 39.9494C30.5163 39.9494 28.0306 39.2905 25.8327 38.0383L25.3766 37.7786L25.3799 37.253C25.4044 33.3394 26.9318 29.6577 29.6808 26.886C32.4418 24.1021 36.1104 22.5689 40.0106 22.5689ZM54.6886 37.139C54.6364 32.2612 52.2708 27.8109 48.3276 25.1C48.3305 25.8137 48.283 26.5271 48.1854 27.2362C50.9873 29.5334 52.6955 32.916 52.8824 36.622C46.8383 39.7491 39.3006 37.5591 35.8671 31.5834C34.9397 29.9693 34.3711 28.1645 34.204 26.3205C33.6206 26.6399 33.0635 27.0074 32.5375 27.4194C32.8149 29.194 33.4176 30.9174 34.317 32.4827C36.2701 35.8819 39.4102 38.319 43.1585 39.3447C44.4302 39.6928 45.7232 39.865 47.0091 39.865C49.5145 39.865 51.9931 39.2113 54.2359 37.9305L54.6941 37.6687L54.6886 37.139ZM40.0878 12.1068L40.5393 12.3722C47.4822 16.4532 49.8515 25.4683 45.8206 32.4686C44.9135 34.0439 43.7216 35.4371 42.3214 36.5745C41.7042 36.3236 41.1102 36.0235 40.5445 35.6779C42.0591 34.6 43.3375 33.1961 44.2724 31.5723C47.7249 25.5767 45.8347 17.8993 40.0869 14.1965C36.9575 16.2106 34.8408 19.5066 34.274 23.1534C33.6161 23.4268 32.9798 23.7466 32.369 24.1104C32.5218 21.8982 33.1735 19.7309 34.2753 17.7961C35.5512 15.5558 37.4049 13.6801 39.6361 12.3718L40.0878 12.1068Z" fill="white"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,278 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
theme: 'cosmos',
|
|
||||||
title: 'Ethermint Documentation',
|
|
||||||
locales: {
|
|
||||||
'/': {
|
|
||||||
lang: 'en-US'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
markdown: {
|
|
||||||
extendMarkdown: (md) => {
|
|
||||||
md.use(require("markdown-it-katex"));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
head: [
|
|
||||||
[
|
|
||||||
"link",
|
|
||||||
{
|
|
||||||
rel: "stylesheet",
|
|
||||||
href:
|
|
||||||
"https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"link",
|
|
||||||
{
|
|
||||||
rel: "stylesheet",
|
|
||||||
href:
|
|
||||||
"https://cdn.jsdelivr.net/github-markdown-css/2.2.1/github-markdown.css",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
base: process.env.VUEPRESS_BASE || '/',
|
|
||||||
plugins: [
|
|
||||||
'vuepress-plugin-element-tabs'
|
|
||||||
],
|
|
||||||
themeConfig: {
|
|
||||||
repo: 'tharsis/ethermint',
|
|
||||||
docsRepo: 'tharsis/ethermint',
|
|
||||||
docsBranch: 'main',
|
|
||||||
docsDir: 'docs',
|
|
||||||
editLinks: true,
|
|
||||||
custom: true,
|
|
||||||
project: {
|
|
||||||
name: 'Ethermint',
|
|
||||||
denom: 'PHOTON',
|
|
||||||
ticker: 'ETHM',
|
|
||||||
rpc_url: '',
|
|
||||||
rpc_url_local: 'http://localhost:8545/',
|
|
||||||
chain_id: '9000',
|
|
||||||
block_explorer_url: '',
|
|
||||||
},
|
|
||||||
logo: {
|
|
||||||
src: '/ethermint-logo-horizontal-alpha.svg',
|
|
||||||
},
|
|
||||||
algolia: {
|
|
||||||
id: 'BH4D9OD16A',
|
|
||||||
key: 'c5da4dd3636828292e3c908a0db39688',
|
|
||||||
index: 'ethermint'
|
|
||||||
},
|
|
||||||
topbar: {
|
|
||||||
banner: false
|
|
||||||
},
|
|
||||||
sidebar: {
|
|
||||||
auto: false,
|
|
||||||
nav: [
|
|
||||||
{
|
|
||||||
title: 'Reference',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: 'Introduction',
|
|
||||||
directory: true,
|
|
||||||
path: '/intro'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Quick Start',
|
|
||||||
directory: true,
|
|
||||||
path: '/quickstart'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Basics',
|
|
||||||
directory: true,
|
|
||||||
path: '/basics'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Core Concepts',
|
|
||||||
directory: true,
|
|
||||||
path: '/core'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Guides',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: 'Localnet',
|
|
||||||
directory: true,
|
|
||||||
path: '/guides/localnet'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Keys and Wallets',
|
|
||||||
directory: true,
|
|
||||||
path: '/guides/keys-wallets'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Ethereum Tooling',
|
|
||||||
directory: true,
|
|
||||||
path: '/guides/tools'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Validators',
|
|
||||||
directory: true,
|
|
||||||
path: '/guides/validators'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Key Management System',
|
|
||||||
directory: true,
|
|
||||||
path: '/guides/kms'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'APIs',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: 'JSON-RPC',
|
|
||||||
directory: true,
|
|
||||||
path: '/api/json-rpc'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Protobuf Reference',
|
|
||||||
directory: false,
|
|
||||||
path: '/api/proto-docs'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Testnet',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: 'Join Testnet',
|
|
||||||
directory: false,
|
|
||||||
path: '/testnet/join'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Token Faucet',
|
|
||||||
directory: false,
|
|
||||||
path: '/testnet/faucet'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Deploy Node on Cloud',
|
|
||||||
directory: false,
|
|
||||||
path: '/testnet/cloud_providers'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Specifications',
|
|
||||||
children: [{
|
|
||||||
title: 'Modules',
|
|
||||||
directory: true,
|
|
||||||
path: '/modules'
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
title: 'Resources',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: 'Ethermint API Reference',
|
|
||||||
path: 'https://pkg.go.dev/github.com/tharsis/ethermint'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Cosmos REST API Spec',
|
|
||||||
path: 'https://cosmos.network/rpc/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'JSON-RPC API Reference',
|
|
||||||
path: '/api/json-rpc/endpoints'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
gutter: {
|
|
||||||
title: 'Help & Support',
|
|
||||||
chat: {
|
|
||||||
title: 'Developer Chat',
|
|
||||||
text: 'Chat with Ethermint developers on Discord.',
|
|
||||||
url: 'https://discord.gg/trje9XuAmy',
|
|
||||||
bg: 'linear-gradient(103.75deg, #1B1E36 0%, #22253F 100%)'
|
|
||||||
},
|
|
||||||
forum: {
|
|
||||||
title: 'Ethermint Developer Forum',
|
|
||||||
text: 'Join the Ethermint Developer Forum to learn more.',
|
|
||||||
url: 'https://forum.cosmos.network/c/ethermint',
|
|
||||||
bg: 'linear-gradient(221.79deg, #3D6B99 -1.08%, #336699 95.88%)',
|
|
||||||
logo: 'ethereum-white'
|
|
||||||
},
|
|
||||||
github: {
|
|
||||||
title: 'Found an Issue?',
|
|
||||||
text: 'Help us improve this page by suggesting edits on GitHub.',
|
|
||||||
bg: '#F8F9FC'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
footer: {
|
|
||||||
logo: '/logo-bw.svg',
|
|
||||||
textLink: {
|
|
||||||
text: 'ethermint.dev',
|
|
||||||
url: 'https://ethermint.dev'
|
|
||||||
},
|
|
||||||
services: [
|
|
||||||
{
|
|
||||||
service: 'github',
|
|
||||||
url: 'https://github.com/tharsis/ethermint'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
service: "twitter",
|
|
||||||
url: "https://twitter.com/ethermint",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
service: "linkedin",
|
|
||||||
url: "https://www.linkedin.com/company/tharsis-finance/",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
service: "medium",
|
|
||||||
url: "https://medium.com/@tharsis_labs",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
smallprint: 'This website is maintained by Tharsis Labs Ltd.',
|
|
||||||
links: [{
|
|
||||||
title: 'Documentation',
|
|
||||||
children: [{
|
|
||||||
title: 'Cosmos SDK Docs',
|
|
||||||
url: 'https://docs.cosmos.network/master/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Ethereum Docs',
|
|
||||||
url: 'https://ethereum.org/developers'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Tendermint Core Docs',
|
|
||||||
url: 'https://docs.tendermint.com'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Community',
|
|
||||||
children: [{
|
|
||||||
title: 'Ethermint Community',
|
|
||||||
url: 'https://discord.gg/trje9XuAmy'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Ethermint Forum',
|
|
||||||
url: 'https://forum.cosmos.network/c/ethermint'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Tharsis',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: 'Jobs at Tharsis',
|
|
||||||
url: 'https://tharsis.notion.site/Jobs-at-Tharsis-5a1642eb89b34747ae6f2db2d356fc0d'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
versions: [
|
|
||||||
{
|
|
||||||
"label": "main",
|
|
||||||
"key": "main"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v0.5",
|
|
||||||
"key": "v0.5"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 526 192" style="enable-background:new 0 0 526 192;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:url(#SVGID_1_);}
|
|
||||||
.st1{fill:url(#SVGID_2_);}
|
|
||||||
.st2{fill:url(#SVGID_3_);}
|
|
||||||
.st3{fill:url(#SVGID_4_);}
|
|
||||||
.st4{fill:#B3C9F4;}
|
|
||||||
.st5{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
|
||||||
.st6{fill:#717BBF;}
|
|
||||||
.st7{opacity:0.5;fill:url(#SVGID_5_);enable-background:new ;}
|
|
||||||
.st8{opacity:0.5;fill:url(#SVGID_6_);enable-background:new ;}
|
|
||||||
.st9{fill:#131516;}
|
|
||||||
</style>
|
|
||||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="96.4904" y1="115.7662" x2="80.8316" y2="187.581" gradientTransform="matrix(1 0 0 -1 0 194)">
|
|
||||||
<stop offset="0" style="stop-color:#8D8DE4"/>
|
|
||||||
<stop offset="1" style="stop-color:#89A2E5;stop-opacity:0"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBD9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st0" d="M76.9,7v123.2l54.8-32.3L76.9,7z"/>
|
|
||||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="85.6408" y1="131.291" x2="28.6749" y2="93.2238" gradientTransform="matrix(1 0 0 -1 0 194)">
|
|
||||||
<stop offset="0" style="stop-color:#8D8DE4"/>
|
|
||||||
<stop offset="1" style="stop-color:#89A2E5;stop-opacity:0"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBD9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st1" d="M22.1,97.8l54.8,32.3V7L22.1,97.8z"/>
|
|
||||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="22.1" y1="47.25" x2="76.9" y2="47.25" gradientTransform="matrix(1 0 0 -1 0 194)">
|
|
||||||
<stop offset="0" style="stop-color:#E3FFFF"/>
|
|
||||||
<stop offset="1" style="stop-color:#89A2E5"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st2" d="M22.1,108.2l54.8,77.1v-44.8L22.1,108.2z"/>
|
|
||||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-52.6532" y1="253.8875" x2="422.5458" y2="-79.853">
|
|
||||||
<stop offset="6.489749e-03" style="stop-color:#DC614D"/>
|
|
||||||
<stop offset="0.3603" style="stop-color:#8D8DE4"/>
|
|
||||||
<stop offset="1" style="stop-color:#89A2E5"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st3" d="M76.9,140.5v44.8l54.8-77.1L76.9,140.5z"/>
|
|
||||||
<g>
|
|
||||||
<path class="st4" d="M76.9,72.9L22.1,97.8l54.8,32.3l54.8-32.3L76.9,72.9z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st5" d="M89.6,62.4c-4-1.6-8.3-2.4-12.7-2.4c-9.2,0-17.8,3.6-24.3,10.1s-10,15.2-10.1,24.3v1.2l1.1,0.6
|
|
||||||
c5.2,2.9,11,4.5,16.9,4.5c0.2,0,0.3,0,0.5,0c5.2-0.1,10.3-1.3,14.9-3.6c-1.5-0.8-2.9-1.7-4.2-2.8c-8.1,3.2-17.2,2.8-24.9-1.2
|
|
||||||
c0.8-16.1,14-29,30.1-29c4.5,0,8.9,1,12.9,2.9C89.8,65.5,89.8,64,89.6,62.4"/>
|
|
||||||
<path class="st5" d="M111.3,94.2c-0.1-11.5-5.7-21.9-14.9-28.3c0,1.7-0.1,3.4-0.3,5c6.6,5.4,10.6,13.3,11,22
|
|
||||||
c-14.2,7.3-31.9,2.2-40-11.8c-2.2-3.8-3.5-8-3.9-12.4c-1.4,0.8-2.7,1.6-3.9,2.6c0.7,4.2,2.1,8.2,4.2,11.9c4.6,8,12,13.7,20.8,16.1
|
|
||||||
c3,0.8,6,1.2,9,1.2c5.9,0,11.7-1.5,17-4.5l1.1-0.6L111.3,94.2z"/>
|
|
||||||
<path class="st5" d="M78.1,36L77,35.4L76,36c-5.2,3.1-9.6,7.5-12.6,12.7c-2.6,4.5-4.1,9.6-4.5,14.8c1.4-0.9,2.9-1.6,4.5-2.2
|
|
||||||
c1.3-8.6,6.3-16.3,13.7-21C90.6,49,95,67.1,86.9,81.1c-2.2,3.8-5.2,7.1-8.8,9.6c1.3,0.8,2.7,1.5,4.2,2.1c3.3-2.7,6.1-5.9,8.2-9.6
|
|
||||||
C100,66.8,94.4,45.6,78.1,36"/>
|
|
||||||
<polygon class="st6" points="76.9,146.5 131.7,108.2 131.7,108.2 76.9,140.5 22.1,108.2 22.1,108.2 "/>
|
|
||||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="75.5332" y1="186.2992" x2="42.3256" y2="50.7691" gradientTransform="matrix(1 0 0 -1 0 194)">
|
|
||||||
<stop offset="0" style="stop-color:#E3FFFF"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st7" d="M22.1,97.8l54.8,32.3V7L22.1,97.8z"/>
|
|
||||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="117.958" y1="89.2972" x2="55.3226" y2="144.3732" gradientTransform="matrix(1 0 0 -1 0 194)">
|
|
||||||
<stop offset="1.975860e-02" style="stop-color:#DD5C47"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st8" d="M76.9,7v123.2l54.8-32.3L76.9,7z"/>
|
|
||||||
<g>
|
|
||||||
<path class="st9" d="M182.2,76.1h34.4v8.4h-24.7V97h19.8v8.4h-19.8v13.8h25.5v8.5h-35.2L182.2,76.1L182.2,76.1z"/>
|
|
||||||
<path class="st9" d="M235.6,79.3v11.2h10.3v7.6h-10.3v16.2c0,3.8,2,5.7,5.4,5.7h4.9v7.7h-6c-8.1,0-13.4-4.7-13.4-13V98.2h-7.3v-7.6
|
|
||||||
h7.3V79.3H235.6z"/>
|
|
||||||
<path class="st9" d="M252.8,74.6h9v21.7c2.1-4.1,6.4-6.4,11.7-6.4c8.3,0,13.8,6.1,13.8,14.8v23h-9v-21.1c0-5.1-3.2-8.6-7.8-8.6
|
|
||||||
c-5,0-8.6,4-8.6,9.5v20.3h-9L252.8,74.6L252.8,74.6z"/>
|
|
||||||
<path class="st9" d="M328.9,115.4c-1.4,7.9-8.3,13-17.5,13c-12.2,0-19-9.6-19-19.4s6.1-19.1,18.2-19.1c12.5,0,18.1,9.1,18.1,17.9
|
|
||||||
c0,1.3-0.1,2.4-0.1,3.1h-27.5c0.7,6,4.5,9.8,10.3,9.8c4.7,0,7.7-1.9,8.6-5.5h8.9V115.4z M301.4,105h18.3c-0.4-4.7-3.6-8.3-9-8.3
|
|
||||||
C305.6,96.7,302.3,99.4,301.4,105z"/>
|
|
||||||
<path class="st9" d="M351.2,98.2c-5.8,0-8.1,4.9-8.1,12v17.6H334V90.5h9.1v6.6c1.8-4.7,4.7-6.6,9.5-6.6h4.4v7.6L351.2,98.2
|
|
||||||
L351.2,98.2z"/>
|
|
||||||
<path class="st9" d="M361.2,90.5h9.1v5.8c1.8-3.8,5.5-6.4,10.8-6.4c5.9,0,10,2.5,11.6,7.1c1.7-3.8,6.4-7.1,12.3-7.1
|
|
||||||
c8.1,0,13.2,5.8,13.2,13.7v24.1h-9v-21.3c0-5.2-2.7-8.7-7.1-8.7c-4.9,0-7.9,3.5-7.9,8.7v21.3h-9v-21.3c0-5.2-2.7-8.7-7.1-8.7
|
|
||||||
c-4.8,0-7.8,3.5-7.8,8.7v21.3h-9.1V90.5z"/>
|
|
||||||
<path class="st9" d="M434.7,74.6v10.1h-9.8V74.6H434.7z M425.3,90.5h9.1v37.2h-9.1V90.5z"/>
|
|
||||||
<path class="st9" d="M441.5,90.5h9.1v5.8c2.1-4.1,6.3-6.4,11.6-6.4c8.4,0,13.9,6.1,13.9,14.8v23H467v-21.1c0-5.1-3.1-8.6-7.8-8.6
|
|
||||||
c-5.1,0-8.6,4-8.6,9.5v20.3h-9.1V90.5z"/>
|
|
||||||
<path class="st9" d="M495.6,79.3v11.2h10.3v7.6h-10.3v16.2c0,3.8,2,5.7,5.4,5.7h4.9v7.7h-6c-8.1,0-13.4-4.7-13.4-13V98.2h-7.3v-7.6
|
|
||||||
h7.3V79.3H495.6z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 5.5 KiB |
@@ -1,94 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg width="240" height="96" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 526 192" style="enable-background:new 0 0 526 192;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#131516;}
|
|
||||||
.st1{fill:url(#SVGID_1_);}
|
|
||||||
.st2{fill:url(#SVGID_2_);}
|
|
||||||
.st3{fill:url(#SVGID_3_);}
|
|
||||||
.st4{fill:url(#SVGID_4_);}
|
|
||||||
.st5{fill:#B3C9F4;}
|
|
||||||
.st6{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
|
||||||
.st7{fill:#717BBF;}
|
|
||||||
.st8{opacity:0.5;fill:url(#SVGID_5_);enable-background:new ;}
|
|
||||||
.st9{opacity:0.5;fill:url(#SVGID_6_);enable-background:new ;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M180.9,75.3l35,0v8.6l-25.1,0v12.8l20.1,0v8.6l-20.1,0v14l25.9,0l0,8.6l-35.8,0L180.9,75.3z"/>
|
|
||||||
<path class="st0" d="M247.7,73.8l9.2,0v22.1c2.1-4.1,6.5-6.5,11.9-6.5c8.5,0,14,6.2,14,15v23.4l-9.2,0l0-21.5c0-5.2-3.2-8.8-8-8.8
|
|
||||||
c-5.1,0-8.8,4.1-8.8,9.6l0,20.6l-9.2,0L247.7,73.8z"/>
|
|
||||||
<path class="st0" d="M324.3,115.2c-1.4,8-8.5,13.2-17.8,13.2c-12.4,0-19.3-9.8-19.3-19.7c0-10,6.2-19.4,18.5-19.4
|
|
||||||
c12.7,0,18.4,9.2,18.4,18.2c0,1.3-0.1,2.4-0.1,3.2l-27.9,0c0.7,6.1,4.6,10,10.4,10c4.7,0,7.8-2,8.8-5.6L324.3,115.2z M296.3,104.7
|
|
||||||
l18.6,0c-0.4-4.8-3.7-8.4-9.2-8.4C300.6,96.3,297.2,99,296.3,104.7z"/>
|
|
||||||
<path class="st0" d="M345.3,97.7c-5.9,0-8.2,5-8.2,12.2v17.9l-9.2,0l0-37.8l9.2,0v6.7c1.9-4.8,4.8-6.7,9.7-6.7h4.4v7.7L345.3,97.7z
|
|
||||||
"/>
|
|
||||||
<path class="st0" d="M355.9,90l9.2,0v5.9c1.9-3.8,5.6-6.5,11-6.5c6,0,10.1,2.6,11.8,7.2c1.7-3.9,6.5-7.2,12.5-7.2
|
|
||||||
c8.2,0,13.4,5.9,13.4,14l0,24.5l-9.2,0l0-21.7c0-5.3-2.8-8.9-7.2-8.9c-5,0-8,3.5-8,8.9v21.7l-9.2,0v-21.7c0-5.3-2.8-8.9-7.2-8.9
|
|
||||||
c-4.9,0-8,3.5-8,8.9l0,21.7l-9.2,0L355.9,90z"/>
|
|
||||||
<path class="st0" d="M429.1,73.8v10.3l-9.9,0l0-10.3L429.1,73.8z M419.5,90l9.2,0l0,37.8l-9.2,0L419.5,90z"/>
|
|
||||||
<path class="st0" d="M435,90l9.2,0v5.9c2.1-4.1,6.4-6.5,11.8-6.5c8.6,0,14.1,6.2,14.1,15v23.4l-9.2,0v-21.5c0-5.2-3.2-8.8-7.9-8.8
|
|
||||||
c-5.2,0-8.8,4.1-8.8,9.6l0,20.6l-9.2,0L435,90z"/>
|
|
||||||
<path class="st0" d="M489.4,78.4v11.5h10.6v7.8h-10.6v16.6c0,3.8,2,5.8,5.5,5.8h5.1v7.8h-6.1c-8.3,0-13.7-4.8-13.7-13.3v-17h-7.5
|
|
||||||
v-7.8h7.5V78.4H489.4z"/>
|
|
||||||
<path class="st0" d="M233.4,78.4v11.5h10.6v7.8h-10.6v16.6c0,3.8,2,5.8,5.5,5.8h5.1v7.8h-6.1c-8.3,0-13.7-4.8-13.7-13.3v-17h-7.5
|
|
||||||
v-7.8h7.5V78.4H233.4z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
|
|
||||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-624.5055" y1="-406.1891" x2="-639.7977" y2="-476.3224" gradientTransform="matrix(1 0 0 1 720.2893 484.6111)">
|
|
||||||
<stop offset="0" style="stop-color:#8D8DE4"/>
|
|
||||||
<stop offset="1" style="stop-color:#89A2E5;stop-opacity:0"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBD9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st1" d="M76.7,8.8v120.3l53.5-31.6L76.7,8.8z"/>
|
|
||||||
|
|
||||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="-635.0693" y1="-421.3597" x2="-690.7014" y2="-384.1838" gradientTransform="matrix(1 0 0 1 720.2893 484.6111)">
|
|
||||||
<stop offset="0" style="stop-color:#8D8DE4"/>
|
|
||||||
<stop offset="1" style="stop-color:#89A2E5;stop-opacity:0"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBD9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st2" d="M23.1,97.5l53.5,31.6V8.8L23.1,97.5z"/>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="23.0618" y1="-1965.4794" x2="76.6382" y2="-1965.4794" gradientTransform="matrix(1 0 0 -1 0 -1820)">
|
|
||||||
<stop offset="0" style="stop-color:#E3FFFF"/>
|
|
||||||
<stop offset="1" style="stop-color:#89A2E5"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st3" d="M23.1,107.8l53.6,75.4v-43.8L23.1,107.8z"/>
|
|
||||||
|
|
||||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-50.0858" y1="1004.2726" x2="414.7754" y2="677.7925" gradientTransform="matrix(1 0 0 1 0 -754)">
|
|
||||||
<stop offset="6.489749e-03" style="stop-color:#DC614D"/>
|
|
||||||
<stop offset="0.3603" style="stop-color:#8D8DE4"/>
|
|
||||||
<stop offset="1" style="stop-color:#89A2E5"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st4" d="M76.6,139.4v43.8l53.6-75.4L76.6,139.4z"/>
|
|
||||||
<g>
|
|
||||||
<path class="st5" d="M76.6,73.2L23.1,97.6l53.6,31.6l53.6-31.6L76.6,73.2z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st6" d="M89.1,63c-3.9-1.5-8.1-2.4-12.4-2.4c-9,0-17.4,3.5-23.7,9.9c-6.3,6.4-9.8,14.8-9.9,23.7v1.2l1.1,0.6
|
|
||||||
c5.1,2.9,10.8,4.4,16.5,4.4c0.2,0,0.3,0,0.5,0c5.1-0.1,10.1-1.3,14.6-3.5c-1.5-0.8-2.9-1.7-4.1-2.7c-7.9,3.2-16.8,2.7-24.4-1.2
|
|
||||||
C48,77.2,61,64.6,76.6,64.6c4.4,0,8.7,1,12.6,2.9C89.3,66,89.3,64.6,89.1,63"/>
|
|
||||||
<path class="st6" d="M110.3,94.1c-0.1-11.3-5.6-21.4-14.6-27.7c0,1.7-0.1,3.3-0.3,4.9c6.4,5.3,10.4,13,10.8,21.5
|
|
||||||
C92.4,100,75,95,67.1,81.3c-2.2-3.7-3.4-7.8-3.8-12.1c-1.4,0.8-2.7,1.5-3.8,2.5c0.7,4.1,2,8.1,4.1,11.6
|
|
||||||
c4.5,7.8,11.8,13.4,20.4,15.8c2.9,0.8,5.9,1.2,8.8,1.2c5.7,0,11.4-1.5,16.6-4.4l1.1-0.6L110.3,94.1z"/>
|
|
||||||
<path class="st6" d="M77.8,37.2l-1.1-0.6l-1,0.6c-5.1,3-9.4,7.4-12.3,12.4c-2.5,4.4-4,9.4-4.4,14.5c1.4-0.9,2.9-1.5,4.4-2.2
|
|
||||||
c1.3-8.4,6.2-16,13.4-20.5c13.2,8.5,17.5,26.2,9.6,39.9c-2.2,3.7-5.1,6.9-8.6,9.4c1.3,0.8,2.7,1.5,4.1,2c3.2-2.7,6-5.7,8.1-9.4
|
|
||||||
C99.3,67.3,93.8,46.6,77.8,37.2"/>
|
|
||||||
<polygon class="st7" points="76.6,145.2 130.3,107.8 130.3,107.8 76.6,139.4 23.1,107.8 23.1,107.8 "/>
|
|
||||||
|
|
||||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="75.316" y1="-1829.4694" x2="42.8308" y2="-1962.051" gradientTransform="matrix(1 0 0 -1 0 -1820)">
|
|
||||||
<stop offset="0" style="stop-color:#E3FFFF"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st8" d="M23.1,97.6l53.6,31.6V8.8L23.1,97.6z"/>
|
|
||||||
|
|
||||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="116.8103" y1="-1924.3955" x2="55.5375" y2="-1870.5176" gradientTransform="matrix(1 0 0 -1 0 -1820)">
|
|
||||||
<stop offset="1.975860e-02" style="stop-color:#DD5C47"/>
|
|
||||||
<stop offset="1" style="stop-color:#BBF9FF;stop-opacity:0"/>
|
|
||||||
</linearGradient>
|
|
||||||
<path class="st9" d="M76.6,8.8v120.5l53.6-31.6L76.6,8.8z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 5.9 KiB |
@@ -1,3 +0,0 @@
|
|||||||
:root
|
|
||||||
--color-link #3171B0
|
|
||||||
--color-primary #7499BF
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
# Updating the docs
|
|
||||||
|
|
||||||
If you want to open a PR on the Cosmos SDK to update the documentation, please follow the guidelines in the [`CONTRIBUTING.md`](https://github.com/tharsis/ethermint/tree/main/CONTRIBUTING.md#updating-documentation)
|
|
||||||
|
|
||||||
## Translating
|
|
||||||
|
|
||||||
- Docs translations live in a `docs/country-code/` folder, where `country-code` stands for the country code of the language used (`cn` for Chinese, `kr` for Korea, `fr` for France, ...).
|
|
||||||
- Always translate content living on `main`.
|
|
||||||
- Only content under `/docs/intro/`, `/docs/basics/`, `/docs/core/`, `/docs/building-modules/` and `docs/interfaces` needs to be translated, as well as `docs/README.md`. It is also nice (but not mandatory) to translate `/docs/spec/`.
|
|
||||||
- Specify the release/tag of the translation in the README of your translation folder. Update the release/tag each time you update the translation.
|
|
||||||
|
|
||||||
## Docs Build Workflow
|
|
||||||
|
|
||||||
The documentation for Ethermint is hosted at https://ethermint.dev/
|
|
||||||
|
|
||||||
built from the files in this (`/docs`) directory for
|
|
||||||
[master](https://github.com/tharsis/ethermint/tree/main/docs).
|
|
||||||
|
|
||||||
### How It Works
|
|
||||||
|
|
||||||
There is a CircleCI job listening for changes in the `/docs` directory, on
|
|
||||||
the `main` branch. Any updates to files in this directory
|
|
||||||
on that branch will automatically trigger a website deployment. Under the hood,
|
|
||||||
the private website repository has a `make build-docs` target consumed by a CircleCI job in that repo.
|
|
||||||
|
|
||||||
## README
|
|
||||||
|
|
||||||
The [README.md](./README.md) is also the landing page for the documentation
|
|
||||||
on the website. During the Jenkins build, the current commit is added to the bottom
|
|
||||||
of the README.
|
|
||||||
|
|
||||||
## Config.js
|
|
||||||
|
|
||||||
The [config.js](./.vuepress/config.js) generates the sidebar and Table of Contents
|
|
||||||
on the website docs. Note the use of relative links and the omission of
|
|
||||||
file extensions. Additional features are available to improve the look
|
|
||||||
of the sidebar.
|
|
||||||
|
|
||||||
## Links
|
|
||||||
|
|
||||||
**NOTE:** Strongly consider the existing links - both within this directory
|
|
||||||
and to the website docs - when moving or deleting files.
|
|
||||||
|
|
||||||
Relative links should be used nearly everywhere, having discovered and weighed the following:
|
|
||||||
|
|
||||||
### Relative
|
|
||||||
|
|
||||||
Where is the other file, relative to the current one?
|
|
||||||
|
|
||||||
- works both on GitHub and for the VuePress build
|
|
||||||
- confusing / annoying to have things like: `../../../../myfile.md`
|
|
||||||
- requires more updates when files are re-shuffled
|
|
||||||
|
|
||||||
### Absolute
|
|
||||||
|
|
||||||
Where is the other file, given the root of the repo?
|
|
||||||
|
|
||||||
- works on GitHub, doesn't work for the VuePress build
|
|
||||||
- this is much nicer: `/docs/hereitis/myfile.md`
|
|
||||||
- if you move that file around, the links inside it are preserved (but not to it, of course)
|
|
||||||
|
|
||||||
### Full
|
|
||||||
|
|
||||||
The full GitHub URL to a file or directory. Used occasionally when it makes sense
|
|
||||||
to send users to the GitHub.
|
|
||||||
|
|
||||||
## Building Locally
|
|
||||||
|
|
||||||
Make sure you are in the `docs` directory and run the following commands:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rm -rf node_modules
|
|
||||||
```
|
|
||||||
|
|
||||||
This command will remove old version of the visual theme and required packages. This step is optional.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn install
|
|
||||||
```
|
|
||||||
|
|
||||||
Install the theme and all dependencies.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn run serve
|
|
||||||
```
|
|
||||||
|
|
||||||
Run `pre` and `post` hooks and start a hot-reloading web-server. See output of this command for the URL (it is often [https://localhost:8080](https://localhost:8080)).
|
|
||||||
|
|
||||||
To build documentation as a static website run `yarn run build`. You will find the website in `.vuepress/dist` directory.
|
|
||||||
|
|
||||||
## Search
|
|
||||||
|
|
||||||
We are using [Algolia](https://www.algolia.com) to power full-text search. This uses a public API search-only key in the `config.js` as well as a [cosmos_network.json](https://github.com/algolia/docsearch-configs/blob/main/configs/cosmos_network.json) configuration file that we can update with PRs.
|
|
||||||
|
|
||||||
### Update and Build the RPC docs
|
|
||||||
|
|
||||||
1. Execute the following command at the root directory to install the swagger-ui generate tool.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make tools
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Edit API docs
|
|
||||||
1. Directly Edit API docs manually: `client/lcd/swagger-ui/swagger.yaml`.
|
|
||||||
2. Edit API docs within the [Swagger Editor](https://editor.swagger.io/). Please refer to this [document](https://swagger.io/docs/specification/2-0/basic-structure/) for the correct structure in `.yaml`.
|
|
||||||
3. Download `swagger.yaml` and replace the old `swagger.yaml` under fold `client/lcd/swagger-ui`.
|
|
||||||
4. Compile ethermintd
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make install
|
|
||||||
```
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
<!--
|
|
||||||
layout: home
|
|
||||||
title: Ethermint Documentation
|
|
||||||
description: Ethermint is a scalable and interoperable Ethereum, built on Proof-of-Stake with fast-finality.
|
|
||||||
sections:
|
|
||||||
- title: Introduction
|
|
||||||
desc: Read a high-level overview of Ethermint and its architecture.
|
|
||||||
url: /intro
|
|
||||||
icon: ethereum-intro
|
|
||||||
- title: Basics
|
|
||||||
desc: Start with the basic concepts of Ethermint, like accounts and transactions.
|
|
||||||
url: /basics
|
|
||||||
icon: basics
|
|
||||||
- title: Core Concepts
|
|
||||||
desc: Read about the core concepts like encoding and events.
|
|
||||||
url: /core
|
|
||||||
icon: core
|
|
||||||
stack:
|
|
||||||
- title: Cosmos SDK
|
|
||||||
desc: The SDK is the world’s most popular framework for building application-specific blockchains.
|
|
||||||
color: "#5064FB"
|
|
||||||
label: sdk
|
|
||||||
url: http://docs.cosmos.network
|
|
||||||
- title: Ethereum
|
|
||||||
desc: Ethereum is a global, open-source platform for decentralized applications.
|
|
||||||
color: "#1A1F36"
|
|
||||||
label: ethereum-black
|
|
||||||
url: https://eth.wiki
|
|
||||||
- title: Tendermint Core
|
|
||||||
desc: The leading BFT engine for building blockchains, powering Ethermint.
|
|
||||||
color: "#00BB00"
|
|
||||||
label: core
|
|
||||||
url: http://docs.tendermint.com
|
|
||||||
footer:
|
|
||||||
newsletter: false
|
|
||||||
aside: false
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Ethermint Documentation
|
|
||||||
|
|
||||||
## Get Started
|
|
||||||
|
|
||||||
- **[Introduction](./intro/overview.md)**: High-level overview of Ethermint.
|
|
||||||
|
|
||||||
## Reference
|
|
||||||
|
|
||||||
- **[Basics](./basics/)**: Documentation on the basic concepts of Ethermint, like the standard anatomy of an application, the transaction lifecycle and accounts management.
|
|
||||||
- **[Core](./core/)**: Documentation on the core concepts of Ethermint, like `encoding`, and `events`.
|
|
||||||
- **[Building Modules](./building-modules/)**: Important concepts for module developers like `message`s, `keeper`s, `handler`s and `querier`s.
|
|
||||||
- **[Interfaces](./interfaces/)**: Documentation on building interfaces for Ethermint applications.
|
|
||||||
|
|
||||||
## Other Resources
|
|
||||||
|
|
||||||
- **[Module Directory](../x/)**: Module implementations and their respective documentation.
|
|
||||||
- **[Ethermint API Reference](https://godoc.org/github.com/tharsis/ethermint)**: Godocs of Ethermint.
|
|
||||||
- **[REST API spec](https://cosmos.network/rpc/)**: List of REST endpoints to interact with an full-node through REST.
|
|
||||||
|
|
||||||
## Contribute
|
|
||||||
|
|
||||||
See [this file](https://github.com/tharsis/ethermint/blob/main/docs/DOCS_README.md) for details of the build process and considerations when making changes.
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: false
|
|
||||||
parent:
|
|
||||||
order: 1
|
|
||||||
-->
|
|
||||||
|
|
||||||
# API
|
|
||||||
|
|
||||||
This section contains different client and API reference document.
|
|
||||||
|
|
||||||
1. [JSON-RPC](./json-rpc.md)
|
|
||||||
1. [Protobuf Docs](./proto-docs.md)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,130 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 5
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Events
|
|
||||||
|
|
||||||
`Event`s are objects that contain information about the execution of the application. They are
|
|
||||||
mainly used by service providers like block explorers and wallet to track the execution of various
|
|
||||||
messages and index transactions. {synopsis}
|
|
||||||
|
|
||||||
## Pre-requisite Readings
|
|
||||||
|
|
||||||
- [Cosmos SDK Events](https://docs.cosmos.network/master/core/events.html) {prereq}
|
|
||||||
- [Ethereum's PubSub JSON-RPC API](https://geth.ethereum.org/docs/rpc/pubsub) {prereq}
|
|
||||||
|
|
||||||
## Subscribing to Events
|
|
||||||
|
|
||||||
### SDK and Tendermint Events
|
|
||||||
|
|
||||||
It is possible to subscribe to `Events` via Tendermint's [Websocket](https://tendermint.com/docs/app-dev/subscribing-to-events-via-websocket.html#subscribing-to-events-via-websocket).
|
|
||||||
This is done by calling the `subscribe` RPC method via Websocket:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"method": "subscribe",
|
|
||||||
"id": "0",
|
|
||||||
"params": {
|
|
||||||
"query": "tm.event='eventCategory' AND eventType.eventAttribute='attributeValue'"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The main `eventCategory` you can subscribe to are:
|
|
||||||
|
|
||||||
- `NewBlock`: Contains `events` triggered during `BeginBlock` and `EndBlock`.
|
|
||||||
- `Tx`: Contains `events` triggered during `DeliverTx` (i.e. transaction processing).
|
|
||||||
- `ValidatorSetUpdates`: Contains validator set updates for the block.
|
|
||||||
|
|
||||||
These events are triggered from the `state` package after a block is committed. You can get the full
|
|
||||||
list of `event` categories
|
|
||||||
[here](https://godoc.org/github.com/tendermint/tendermint/types#pkg-constants).
|
|
||||||
|
|
||||||
The `type` and `attribute` value of the `query` allow you to filter the specific `event` you are
|
|
||||||
looking for. For example, a `MsgEthereumTx` transaction triggers an `event` of type `ethermint` and
|
|
||||||
has `sender` and `recipient` as `attributes`. Subscribing to this `event` would be done like so:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"method": "subscribe",
|
|
||||||
"id": "0",
|
|
||||||
"params": {
|
|
||||||
"query": "tm.event='Tx' AND ethereum.recipient='hexAddress'"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
where `hexAddress` is an Ethereum hex address (eg: `0x1122334455667788990011223344556677889900`).
|
|
||||||
|
|
||||||
### Ethereum JSON-RPC Events
|
|
||||||
|
|
||||||
Ethermint also supports the Ethereum [JSON-RPC](https://eth.wiki/json-rpc/API) filters calls to
|
|
||||||
subscribe to [state logs](https://eth.wiki/json-rpc/API#eth_newfilter),
|
|
||||||
[blocks](https://eth.wiki/json-rpc/API#eth_newblockfilter) or [pending
|
|
||||||
transactions](https://eth.wiki/json-rpc/API#eth_newpendingtransactionfilter) changes.
|
|
||||||
|
|
||||||
Under the hood, it uses the Tendermint RPC client's event system to process subscriptions that are
|
|
||||||
then formatted to Ethereum-compatible events.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newBlockFilter","params":[],"id":1}' -H "Content-Type: application/json" http://localhost:8545
|
|
||||||
|
|
||||||
{"jsonrpc":"2.0","id":1,"result":"0x3503de5f0c766c68f78a03a3b05036a5"}
|
|
||||||
```
|
|
||||||
|
|
||||||
Then you can check if the state changes with the [`eth_getFilterChanges`](https://eth.wiki/json-rpc/API#eth_getfilterchanges) call:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x3503de5f0c766c68f78a03a3b05036a5"],"id":1}' -H "Content-Type: application/json" http://localhost:8545
|
|
||||||
|
|
||||||
{"jsonrpc":"2.0","id":1,"result":["0x7d44dceff05d5963b5bc81df7e9f79b27e777b0a03a6feca09f3447b99c6fa71","0x3961e4050c27ce0145d375255b3cb829a5b4e795ac475c05a219b3733723d376","0xd7a497f95167d63e6feca70f344d9f6e843d097b62729b8f43bdcd5febf142ab","0x55d80a4ba6ef54f2a8c0b99589d017b810ed13a1fda6a111e1b87725bc8ceb0e","0x9e8b92c17280dd05f2562af6eea3285181c562ebf41fc758527d4c30364bcbc4","0x7353a4b9d6b35c9eafeccaf9722dd293c46ae2ffd4093b2367165c3620a0c7c9","0x026d91bda61c8789c59632c349b38fd7e7557e6b598b94879654a644cfa75f30","0x73e3245d4ddc3bba48fa67633f9993c6e11728a36401fa1206437f8be94ef1d3"]}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Websocket Connection
|
|
||||||
|
|
||||||
### Tendermint Websocket
|
|
||||||
|
|
||||||
To start a connection with the Tendermint websocket you need to define the address with the `--rpc.laddr`
|
|
||||||
flag when starting the node (default `tcp://127.0.0.1:26657`):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ethermintd start --rpc.laddr="tcp://127.0.0.1:26657"
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, start a websocket subscription with [ws](https://github.com/hashrocket/ws)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# connect to tendermint websocket at port 8080 as defined above
|
|
||||||
ws ws://localhost:8080/websocket
|
|
||||||
|
|
||||||
# subscribe to new Tendermint block headers
|
|
||||||
> { "jsonrpc": "2.0", "method": "subscribe", "params": ["tm.event='NewBlockHeader'"], "id": 1 }
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ethereum Websocket
|
|
||||||
|
|
||||||
Since Ethermint runs uses Tendermint Core as it's consensus Engine and it's built with the Cosmos
|
|
||||||
SDK framework, it inherits the event format from them. However, in order to support the native Web3
|
|
||||||
compatibility for websockets of the [Ethereum's
|
|
||||||
PubSubAPI](https://geth.ethereum.org/docs/rpc/pubsub), Ethermint needs to cast the Tendermint
|
|
||||||
responses retrieved into the Ethereum types.
|
|
||||||
|
|
||||||
You can start a connection with the Ethereum websocket using the `--json-rpc.ws-address` flag when starting
|
|
||||||
the node (default `"0.0.0.0:8546"`):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ethermintd start --json-rpc.address"0.0.0.0:8545" --json-rpc.ws-address="0.0.0.0:8546" --evm.rpc.api="eth,web3,net,txpool,debug" --json-rpc.enable
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, start a websocket subscription with [`ws`](https://github.com/hashrocket/ws)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# connect to tendermint websocet at port 8546 as defined above
|
|
||||||
ws ws://localhost:8546/
|
|
||||||
|
|
||||||
# subscribe to new Ethereum-formatted block Headers
|
|
||||||
> {"id": 1, "method": "eth_subscribe", "params": ["newHeads", {}]}
|
|
||||||
< {"jsonrpc":"2.0","result":"0x44e010cb2c3161e9c02207ff172166ef","id":1}
|
|
||||||
```
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 3
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Namespaces
|
|
||||||
|
|
||||||
Check the JSON-RPC namespaces supported on Ethermint. {synopsis}
|
|
||||||
|
|
||||||
## Pre-requisite Readings
|
|
||||||
|
|
||||||
- [Geth JSON-RPC Namespaces](https://geth.ethereum.org/docs/rpc/server) {prereq}
|
|
||||||
|
|
||||||
## Ethereum Namespaces
|
|
||||||
|
|
||||||
| Namespace | Description | Supported | Enabled by Default |
|
|
||||||
|--------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|--------------------|
|
|
||||||
| [`eth`](./endpoints.md#eth-methods) | Ethermint provides several extensions to the standard `eth` JSON-RPC namespace. | ✔ | ✔ |
|
|
||||||
| [`web3`](./endpoints.md#web3-methods) | The `web3` API provides utility functions for the web3 client. | ✔ | ✔ |
|
|
||||||
| [`net`](./endpoints.md#net-methods) | The `net` API provides access to network information of the node | ✔ | ✔ |
|
|
||||||
| `clique` | The `clique` API provides access to the state of the clique consensus engine. You can use this API to manage signer votes and to check the health of a private network. | ❌ | |
|
|
||||||
| `debug` | The `debug` API gives you access to several non-standard RPC methods, which will allow you to inspect, debug and set certain debugging flags during runtime. | ✔ | |
|
|
||||||
| `les` | The `les` API allows you to manage LES server settings, including client parameters and payment settings for prioritized clients. It also provides functions to query checkpoint information in both server and client mode. | ❌ | |
|
|
||||||
| [`miner`](./endpoints.md#miner-methods) | The `miner` API allows you to remote control the node’s mining operation and set various mining specific settings. | ✔ | ❌ |
|
|
||||||
| [`txpool`](./endpoints.md#txpool-methods) | The `txpool` API gives you access to several non-standard RPC methods to inspect the contents of the transaction pool containing all the currently pending transactions as well as the ones queued for future processing. | ✔ | ❌ |
|
|
||||||
| `admin` | The `admin` API gives you access to several non-standard RPC methods, which will allow you to have a fine grained control over your nodeinstance, including but not limited to network peer and RPC endpoint management. | ❌ | |
|
|
||||||
| [`personal`](./endpoints.md#personal-methods) | The `personal` API manages private keys in the key store. | ✔ | ❌ |
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 2
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Running the Server
|
|
||||||
|
|
||||||
Learn how to run and setup the JSON-RPC server on Ethermint. {synopsis}
|
|
||||||
|
|
||||||
## Enable Server
|
|
||||||
|
|
||||||
To enable RPC server use the following flag (set to true by default).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ethermintd start --json-rpc.enable
|
|
||||||
```
|
|
||||||
|
|
||||||
## Defining Namespaces
|
|
||||||
|
|
||||||
`Eth`,`Net` and `Web3` [namespaces](./namespaces) are enabled by default. In order to enable other namespaces use flag `--json-rpc.api`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ethermintd start --json-rpc.api eth,txpool,personal,net,debug,web3,miner
|
|
||||||
```
|
|
||||||
|
|
||||||
## Set a Gas Cap
|
|
||||||
|
|
||||||
`eth_call` and `eth_estimateGas` define a global gas cap over rpc for DoS protection. You can override the default gas cap value of 25,000,000 by passing a custom value when starting the node:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# set gas cap to 85M
|
|
||||||
ethermintd start --json-rpc.gas-cap 85000000000
|
|
||||||
|
|
||||||
# set gas cap to infinite (=0)
|
|
||||||
ethermintd start --json-rpc.gas-cap 0
|
|
||||||
```
|
|
||||||
|
|
||||||
## CORS
|
|
||||||
|
|
||||||
If accessing the RPC from a browser, CORS will need to be enabled with the appropriate domain set. Otherwise, JavaScript calls are limit by the same-origin policy and requests will fail.
|
|
||||||
|
|
||||||
The CORS setting can be updated from the `app.toml`
|
|
||||||
|
|
||||||
```toml
|
|
||||||
###############################################################################
|
|
||||||
### API Configuration ###
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
[api]
|
|
||||||
|
|
||||||
# ...
|
|
||||||
|
|
||||||
# EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk).
|
|
||||||
enabled-unsafe-cors = true # default false
|
|
||||||
```
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 1
|
|
||||||
-->
|
|
||||||
|
|
||||||
# JSON-RPC Server
|
|
||||||
|
|
||||||
Learn about the JSON-RPC server to interact with the EVM. {synopsis}
|
|
||||||
|
|
||||||
## Pre-requisite Readings
|
|
||||||
|
|
||||||
- [EthWiki JSON-RPC API](https://eth.wiki/json-rpc/API) {prereq}
|
|
||||||
- [Geth JSON-RPC Server](https://geth.ethereum.org/docs/rpc/server) {prereq}
|
|
||||||
|
|
||||||
## JSON-RPC API
|
|
||||||
|
|
||||||
[JSON](https://json.org/) is a lightweight data-interchange format. It can represent numbers, strings, ordered sequences of values, and collections of name/value pairs.
|
|
||||||
|
|
||||||
[JSON-RPC](http://www.jsonrpc.org/specification) is a stateless, light-weight remote procedure call (RPC) protocol. Primarily this specification defines several data structures and the rules around their processing. It is transport agnostic in that the concepts can be used within the same process, over sockets, over HTTP, or in many various message passing environments. It uses JSON ([RFC 4627](https://www.ietf.org/rfc/rfc4627.txt)) as data format.
|
|
||||||
|
|
||||||
## JSON-RPC Support
|
|
||||||
|
|
||||||
Ethermint supports all standard web3 JSON-RPC APIs. You can find documentation for these APIs on the [`JSON-RPC Methods`](./endpoints.md) page.
|
|
||||||
|
|
||||||
JSON-RPC is provided on multiple transports. Ethermint supports JSON-RPC over HTTP and WebSocket. Transports must be enabled through command-line flags or through the `app.toml` configuration file. For more details see the []
|
|
||||||
|
|
||||||
Ethereum JSON-RPC APIs use a name-space system. RPC methods are grouped into several categories depending on their purpose. All method names are composed of the namespace, an underscore, and the actual method name within the namespace. For example, the eth_call method resides in the eth namespace.
|
|
||||||
|
|
||||||
Access to RPC methods can be enabled on a per-namespace basis. Find documentation for individual namespaces in the [Namespaces](./namespaces.md) page.
|
|
||||||
|
|
||||||
## HEX value encoding
|
|
||||||
|
|
||||||
At present there are two key datatypes that are passed over JSON: unformatted byte arrays and quantities. Both are passed with a hex encoding, however with different requirements to formatting:
|
|
||||||
|
|
||||||
When encoding **QUANTITIES** (integers, numbers): encode as hex, prefix with `"0x"`, the most compact representation (slight exception: zero should be represented as `"0x0"`). Examples:
|
|
||||||
|
|
||||||
- `0x41` (65 in decimal)
|
|
||||||
- `0x400` (1024 in decimal)
|
|
||||||
- WRONG: `0x` (should always have at least one digit - zero is `"0x0"`)
|
|
||||||
- WRONG: `0x0400` (no leading zeroes allowed)
|
|
||||||
- WRONG: `ff` (must be prefixed `0x`)
|
|
||||||
|
|
||||||
When encoding **UNFORMATTED DATA** (byte arrays, account addresses, hashes, bytecode arrays): encode as hex, prefix with `"0x"`, two hex digits per byte. Examples:
|
|
||||||
|
|
||||||
- `0x41` (size 1, `"A"`)
|
|
||||||
- `0x004200` (size 3, `"\0B\0"`)
|
|
||||||
- `0x` (size 0, `""`)
|
|
||||||
- WRONG: `0xf0f0f` (must be even number of digits)
|
|
||||||
- WRONG: `004200` (must be prefixed `0x`)
|
|
||||||
|
|
||||||
## Default block parameter
|
|
||||||
|
|
||||||
The following methods have an extra default block parameter:
|
|
||||||
|
|
||||||
- [`eth_getBalance`](./endpoints.md#eth-getbalance)
|
|
||||||
- [`eth_getCode`](./endpoints.md#eth-getcode)
|
|
||||||
- [`eth_getTransactionCount`](./endpoints.md#eth-gettransactioncount)
|
|
||||||
- [`eth_getStorageAt`](./endpoints.md#eth-getstorageat)
|
|
||||||
- [`eth_call`](./endpoints.md#eth-call)
|
|
||||||
|
|
||||||
When requests are made that act on the state of Ethermint, the last default block parameter determines the height of the block.
|
|
||||||
|
|
||||||
The following options are possible for the `defaultBlock` parameter:
|
|
||||||
|
|
||||||
- `HEX String` - an integer block number
|
|
||||||
- `String "earliest"` for the earliest/genesis block
|
|
||||||
- `String "latest"` - for the latest mined block
|
|
||||||
- `String "pending"` - for the pending state/transactions
|
|
||||||
|
|
||||||
## Curl Examples Explained
|
|
||||||
|
|
||||||
The curl options below might return a response where the node complains about the content type, this is because the `--data` option sets the content type to `application/x-www-form-urlencoded`. If your node does complain, manually set the header by placing `-H "Content-Type: application/json"` at the start of the call.
|
|
||||||
|
|
||||||
The examples also do not include the URL/IP & port combination which must be the last argument given to curl e.x. `127.0.0.1:8545`
|
|
||||||
+2116
-44
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
|||||||
|
# ADR Creation Process
|
||||||
|
|
||||||
|
1. Copy the `adr-template.md` file. Use the following filename pattern: `adr-next_number-title.md`
|
||||||
|
2. Create a draft Pull Request if you want to get an early feedback.
|
||||||
|
3. Make sure the context and a solution is clear and well documented.
|
||||||
|
4. Add an entry to a list in the [README](./README.md) file.
|
||||||
|
5. Create a Pull Request to propose a new ADR.
|
||||||
|
|
||||||
|
## ADR life cycle
|
||||||
|
|
||||||
|
ADR creation is an **iterative** process. Instead of trying to solve all decisions in a single ADR pull request, we MUST firstly understand the problem and collect feedback through a GitHub Issue.
|
||||||
|
|
||||||
|
1. Every proposal SHOULD start with a new GitHub Issue or be a result of existing Issues. The Issue should contain just a brief proposal summary.
|
||||||
|
|
||||||
|
2. Once the motivation is validated, a GitHub Pull Request (PR) is created with a new document based on the `adr-template.md`.
|
||||||
|
|
||||||
|
3. An ADR doesn't have to arrive to `master` with an _accepted_ status in a single PR. If the motivation is clear and the solution is sound, we SHOULD be able to merge it and keep a _proposed_ status. It's preferable to have an iterative approach rather than long, not merged Pull Requests.
|
||||||
|
|
||||||
|
4. If a _proposed_ ADR is merged, then it should clearly document outstanding issues either in ADR document notes or in a GitHub Issue.
|
||||||
|
|
||||||
|
5. The PR SHOULD always be merged. In the case of a faulty ADR, we still prefer to merge it with a _rejected_ status. The only time the ADR SHOULD NOT be merged is if the author abandons it.
|
||||||
|
|
||||||
|
6. Merged ADRs SHOULD NOT be pruned.
|
||||||
|
|
||||||
|
### ADR status
|
||||||
|
|
||||||
|
Status has two components:
|
||||||
|
|
||||||
|
```
|
||||||
|
{CONSENSUS STATUS} {IMPLEMENTATION STATUS}
|
||||||
|
```
|
||||||
|
|
||||||
|
IMPLEMENTATION STATUS is either `Implemented` or `Not Implemented`.
|
||||||
|
|
||||||
|
#### Consensus Status
|
||||||
|
|
||||||
|
```
|
||||||
|
DRAFT -> PROPOSED -> LAST CALL yyyy-mm-dd -> ACCEPTED | REJECTED -> SUPERSEDED by ADR-xxx
|
||||||
|
\ |
|
||||||
|
\ |
|
||||||
|
v v
|
||||||
|
ABANDONED
|
||||||
|
```
|
||||||
|
|
||||||
|
+ `DRAFT`: [optional] an ADR which is work in progress, not being ready for a general review. This is to present an early work and get an early feedback in a Draft Pull Request form.
|
||||||
|
+ `PROPOSED`: an ADR covering a full solution architecture and still in the review - project stakeholders haven't reached an agreed yet.
|
||||||
|
+ `LAST CALL <date for the last call>`: [optional] clear notify that we are close to accept updates. Changing a status to `LAST CALL` means that social consensus (of Cosmos SDK maintainers) has been reached and we still want to give it a time to let the community react or analyze.
|
||||||
|
+ `ACCEPTED`: ADR which will represent a currently implemented or to be implemented architecture design.
|
||||||
|
+ `REJECTED`: ADR can go from PROPOSED or ACCEPTED to rejected if the consensus among project stakeholders will decide so.
|
||||||
|
+ `SUPERSEEDED by ADR-xxx`: ADR which has been superseded by a new ADR.
|
||||||
|
+ `ABANDONED`: the ADR is no longer pursued by the original authors.
|
||||||
|
|
||||||
|
## Language used in ADR
|
||||||
|
|
||||||
|
+ The context/background should be written in the present tense.
|
||||||
|
+ Avoid using a first, personal form.
|
||||||
@@ -210,4 +210,4 @@ Later, this section can optionally list ideas or improvements the author or revi
|
|||||||
|
|
||||||
<!-- - {reference link} -->
|
<!-- - {reference link} -->
|
||||||
|
|
||||||
- [Hooks in staking module](https://docs.cosmos.network/v0.43/modules/staking/06_hooks.html)
|
- [Hooks in staking module](https://docs.cosmos.network/master/modules/staking/06_hooks.html)
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: false
|
|
||||||
parent:
|
|
||||||
order: 3
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Basics
|
|
||||||
|
|
||||||
This repository contains reference documentation on the basic concepts of Ethermint.
|
|
||||||
|
|
||||||
1. [Chain ID](./chain_id.md)
|
|
||||||
1. [Accounts](./accounts.md)
|
|
||||||
1. [Gas and Fees](./gas.md)
|
|
||||||
1. [Lifecycle of a transaction](./transactions.md)
|
|
||||||
1. [Tokens](./tokens.md)
|
|
||||||
|
|
||||||
After reading the basics, head on to the [Core Reference](../core/README.md) for more advanced material.
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 2
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Accounts
|
|
||||||
|
|
||||||
This document describes the in-built accounts system of Ethermint. {synopsis}
|
|
||||||
|
|
||||||
## Pre-requisite Readings
|
|
||||||
|
|
||||||
- [Cosmos SDK Accounts](https://docs.cosmos.network/master/basics/accounts.html) {prereq}
|
|
||||||
- [Ethereum Accounts](https://ethereum.org/en/whitepaper/#ethereum-accounts) {prereq}
|
|
||||||
|
|
||||||
## Ethermint Accounts
|
|
||||||
|
|
||||||
Ethermint defines its own custom `Account` type that uses Ethereum's ECDSA secp256k1 curve for keys. This
|
|
||||||
satisfies the [EIP84](https://github.com/ethereum/EIPs/issues/84) for full [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) paths.
|
|
||||||
The root HD path for Ethermint-based accounts is `m/44'/60'/0'/0`.
|
|
||||||
|
|
||||||
+++ https://github.com/tharsis/ethermint/blob/main/types/account.pb.go#L28-L33
|
|
||||||
|
|
||||||
## Addresses and Public Keys
|
|
||||||
|
|
||||||
[BIP-0173](https://github.com/satoshilabs/slips/blob/master/slip-0173.md) defines a new format for segregated witness output addresses that contains a human-readable part that identifies the Bech32 usage. Ethermint uses the following HRP (human readable prefix) as the base HRP:
|
|
||||||
|
|
||||||
| Network | Mainnet | Testnet | Regtest |
|
|
||||||
|-----------|---------|---------|---------|
|
|
||||||
| Ethermint | `ethm` | `ethm` | |
|
|
||||||
|
|
||||||
There are 3 main types of HRP for the `Addresses`/`PubKeys` available by default on Ethermint:
|
|
||||||
|
|
||||||
- Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`eth_secp256k1`** curve.
|
|
||||||
- Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`eth_secp256k1`** curve.
|
|
||||||
- Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are derived using the **`ed25519`** curve.
|
|
||||||
|
|
||||||
| | Address bech32 Prefix | Pubkey bech32 Prefix | Curve | Address byte length | Pubkey byte length |
|
|
||||||
|--------------------|-----------------------|----------------------|-----------------|---------------------|--------------------|
|
|
||||||
| Accounts | `ethm` | `ethmpub` | `eth_secp256k1` | `20` | `33` (compressed) |
|
|
||||||
| Validator Operator | `ethmvaloper` | `ethmvaloperpub` | `eth_secp256k1` | `20` | `33` (compressed) |
|
|
||||||
| Consensus Nodes | `ethmvalcons` | `ethmvalconspub` | `ed25519` | `20` | `32` |
|
|
||||||
|
|
||||||
## Address formats for clients
|
|
||||||
|
|
||||||
`EthAccount` can be represented in both [Bech32](https://en.bitcoin.it/wiki/Bech32) (`ethm1...`) and hex (`0x...`) formats for Ethereum's Web3 tooling compatibility.
|
|
||||||
|
|
||||||
The Bech32 format is the default format for Cosmos-SDK queries and transactions through CLI and REST
|
|
||||||
clients. The hex format on the other hand, is the Ethereum `common.Address` representation of a
|
|
||||||
Cosmos `sdk.AccAddress`.
|
|
||||||
|
|
||||||
- **Address (Bech32)**: `ethm1j800cll9vq7l4rxfke2u74mjgkdlzrr0r5mu97`
|
|
||||||
- **Address ([EIP55](https://eips.ethereum.org/EIPS/eip-55) Hex)**: `0x91defC7fE5603DFA8CC9B655cF5772459BF10c6f`
|
|
||||||
- **Compressed Public Key**: `{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"Aq9WtHGKtvX523b2ptvimGVfp3hZ1GDxVdINYWBM9+Gy"}`
|
|
||||||
|
|
||||||
### Address conversion
|
|
||||||
|
|
||||||
The `ethermintd debug addr <address>` can be used to convert an address between hex and bech32 formats. For example:
|
|
||||||
|
|
||||||
:::: tabs
|
|
||||||
::: tab Bech32
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ethermintd debug addr ethm10jmp6sgh4cc6zt3e8gw05wavvejgr5pwtu750w
|
|
||||||
Address bytes: [124 182 29 65 23 174 49 161 46 57 58 28 250 59 172 102 100 129 208 46]
|
|
||||||
Address (hex): 7CB61D4117AE31A12E393A1CFA3BAC666481D02E
|
|
||||||
Address (EIP-55): 0x7cB61D4117AE31a12E393a1Cfa3BaC666481D02E
|
|
||||||
Bech32 Acc: ethm10jmp6sgh4cc6zt3e8gw05wavvejgr5pwtu750w
|
|
||||||
Bech32 Val: ethmvaloper10jmp6sgh4cc6zt3e8gw05wavvejgr5pwyv5chn
|
|
||||||
```
|
|
||||||
|
|
||||||
:::
|
|
||||||
::: tab Hex
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ethermintd debug addr 0x7cB61D4117AE31a12E393a1Cfa3BaC666481D02E
|
|
||||||
Address bytes: [124 182 29 65 23 174 49 161 46 57 58 28 250 59 172 102 100 129 208 46]
|
|
||||||
Address (hex): 7CB61D4117AE31A12E393A1CFA3BAC666481D02E
|
|
||||||
Address (EIP-55): 0x7cB61D4117AE31a12E393a1Cfa3BaC666481D02E
|
|
||||||
Bech32 Acc: ethm10jmp6sgh4cc6zt3e8gw05wavvejgr5pwtu750w
|
|
||||||
Bech32 Val: ethmvaloper10jmp6sgh4cc6zt3e8gw05wavvejgr5pwyv5chn
|
|
||||||
```
|
|
||||||
|
|
||||||
:::
|
|
||||||
::::
|
|
||||||
|
|
||||||
### Key output
|
|
||||||
|
|
||||||
::: tip
|
|
||||||
The Cosmos SDK Keyring output (i.e `ethermintd keys`) only supports addresses and public keys in Bech32 format.
|
|
||||||
:::
|
|
||||||
|
|
||||||
We can use the `keys show` command of `ethermintd` with the flag `--bech <type> (acc|val|cons)` to
|
|
||||||
obtain the addresses and keys as mentioned above,
|
|
||||||
|
|
||||||
:::: tabs
|
|
||||||
::: tab Account
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ethermintd keys show mykey --bech acc
|
|
||||||
- name: mykey
|
|
||||||
type: local
|
|
||||||
address: ethm1qsklxwt77qrxur494uvw07zjynu03dq9alwh37
|
|
||||||
pubkey: '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"A8nbJ3eW9oAb2RNZoS8L71jFMfjk6zVa1UISYgKK9HPm"}'
|
|
||||||
mnemonic: ""
|
|
||||||
```
|
|
||||||
|
|
||||||
:::
|
|
||||||
::: tab Validator
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ethermintd keys show test --bech val
|
|
||||||
- name: mykey
|
|
||||||
type: local
|
|
||||||
address: ethmvaloper1qsklxwt77qrxur494uvw07zjynu03dq9rdsrlq
|
|
||||||
pubkey: '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"A8nbJ3eW9oAb2RNZoS8L71jFMfjk6zVa1UISYgKK9HPm"}'
|
|
||||||
mnemonic: ""
|
|
||||||
```
|
|
||||||
|
|
||||||
:::
|
|
||||||
::: tab Consensus
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ethermintd keys show test --bech cons
|
|
||||||
- name: mykey
|
|
||||||
type: local
|
|
||||||
address: ethmvalcons1qsklxwt77qrxur494uvw07zjynu03dq9h7rlnp
|
|
||||||
pubkey: '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"A8nbJ3eW9oAb2RNZoS8L71jFMfjk6zVa1UISYgKK9HPm"}'
|
|
||||||
mnemonic: ""
|
|
||||||
```
|
|
||||||
|
|
||||||
:::
|
|
||||||
::::
|
|
||||||
|
|
||||||
## Querying an Account
|
|
||||||
|
|
||||||
You can query an account address using the CLI, gRPC or
|
|
||||||
|
|
||||||
### Command Line Interface
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# NOTE: the --output (-o) flag will define the output format in JSON or YAML (text)
|
|
||||||
ethermintd q auth account $(ethermintd keys show <MYKEY> -a) -o text
|
|
||||||
|
|
|
||||||
'@type': /ethermint.types.v1beta1.EthAccount
|
|
||||||
base_account:
|
|
||||||
account_number: "3"
|
|
||||||
address: inj14au322k9munkmx5wrchz9q30juf5wjgz2cfqku
|
|
||||||
pub_key: null
|
|
||||||
sequence: "0"
|
|
||||||
code_hash: xdJGAYb3IzySfn2y3McDwOUAtlPKgic7e/rYBF2FpHA=
|
|
||||||
```
|
|
||||||
|
|
||||||
### Cosmos gRPC and REST
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
# GET /cosmos/auth/v1beta1/accounts/{address}
|
|
||||||
curl -X GET "http://localhost:10337/cosmos/auth/v1beta1/accounts/ethm14au322k9munkmx5wrchz9q30juf5wjgz2cfqku" -H "accept: application/json"
|
|
||||||
```
|
|
||||||
|
|
||||||
### JSON-RPC
|
|
||||||
|
|
||||||
To retrieve the Ethereum hex address using Web3, use the JSON-RPC [`eth_accounts`](./../api/json-rpc/endpoints.md#eth-accounts) or [`personal_listAccounts`](./../api/json-rpc/endpoints#personal-listAccounts.md) endpoints:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# query against a local node
|
|
||||||
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' -H "Content-Type: application/json" http://localhost:8545
|
|
||||||
|
|
||||||
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_listAccounts","params":[],"id":1}' -H "Content-Type: application/json" http://localhost:8545
|
|
||||||
```
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 1
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Chain ID
|
|
||||||
|
|
||||||
Learn about the Ethermint chain-id format {synopsis}
|
|
||||||
|
|
||||||
## The Chain Identifier
|
|
||||||
|
|
||||||
Every chain must have a unique identifier or `chain-id`. Tendermint requires each application to
|
|
||||||
define its own `chain-id` in the [genesis.json fields](https://docs.tendermint.com/master/spec/core/genesis.html#genesis-fields). However, in order to comply with both EIP155 and Cosmos standard for chain upgrades, Ethermint-compatible chains must implement a special structure for their chain identifiers.
|
|
||||||
|
|
||||||
## Structure
|
|
||||||
|
|
||||||
The Ethermint Chain ID contains 3 main components
|
|
||||||
|
|
||||||
- **Identifier**: Unstructured string that defines the name of the application.
|
|
||||||
- **EIP155 Number**: Immutable [EIP155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) `CHAIN_ID` that defines the replay attack protection number.
|
|
||||||
- **Version Number**: Is the version number (always positive) that the chain is currently running.
|
|
||||||
This number **MUST** be incremented every time the chain is upgraded or forked in order to avoid network or consensus errors.
|
|
||||||
|
|
||||||
### Format
|
|
||||||
|
|
||||||
The format for specifying and Ethermint compatible chain-id in genesis is the following:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
{identifier}_{EIP155}-{version}
|
|
||||||
```
|
|
||||||
|
|
||||||
The following table provides an example where the second row corresponds to an upgrade from the first one:
|
|
||||||
|
|
||||||
| ChainID | Identifier | EIP155 Number | Version Number |
|
|
||||||
|--------------------|------------|---------------|----------------|
|
|
||||||
| `ethermint_9000-1` | ethermint | 9000 | 1 |
|
|
||||||
| `ethermint_9000-2` | ethermint | 9000 | 2 |
|
|
||||||
| `...` | ... | ... | ... |
|
|
||||||
| `ethermint_9000-N` | ethermint | 9000 | N |
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 4
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Gas and Fees
|
|
||||||
|
|
||||||
Learn about the differences between `Gas` and `Fees` in Ethereum and Cosmos. {synopsis}
|
|
||||||
|
|
||||||
## Pre-requisite Readings
|
|
||||||
|
|
||||||
- [Cosmos SDK Gas](https://docs.cosmos.network/master/basics/gas-fees.html) {prereq}
|
|
||||||
- [Ethereum Gas](https://ethereum.org/en/developers/docs/gas/) {prereq}
|
|
||||||
|
|
||||||
The concept of Gas represents the amount of computational effort required to execute specific operations on the state machine.
|
|
||||||
|
|
||||||
Gas was created on Ethereum to disallow the EVM (Ethereum Virtual Machine) from running infinite
|
|
||||||
loops by allocating a small amount of monetary value into the system. A unit of gas, usually in a
|
|
||||||
form as a fraction of the native coin, is consumed for every operation on the EVM and requires a
|
|
||||||
user to pay for these operations. These operations consist in state transitions such as sending a
|
|
||||||
transaction or calling a contract.
|
|
||||||
|
|
||||||
Exactly like Ethereum, Cosmos utilizes the concept of gas and this is how Cosmos tracks the resource
|
|
||||||
usage of operations during execution. Operations on Cosmos are represented as read or writes done to the chain's store.
|
|
||||||
|
|
||||||
In Cosmos, a fee is calculated and charged to the user during a message execution. This fee is
|
|
||||||
calculated from the sum of all gas consumed in an message execution:
|
|
||||||
|
|
||||||
$$fee = gas ~ * ~ gasPrice$$
|
|
||||||
|
|
||||||
In both networks, gas is used to make sure that operations do not require an excess amount of
|
|
||||||
computational power to complete and as a way to deter bad-acting users from spamming the network.
|
|
||||||
|
|
||||||
## Cosmos SDK `Gas`
|
|
||||||
|
|
||||||
In the Cosmos SDK, gas is tracked in the main `GasMeter` and the `BlockGasMeter`:
|
|
||||||
|
|
||||||
- `GasMeter`: keeps track of the gas consumed during executions that lead to state transitions. It is reset on every transaction execution.
|
|
||||||
- `BlockGasMeter`: keeps track of the gas consumed in a block and enforces that the gas does not go over a predefined limit. This limit is defined in the Tendermint consensus parameters and can be changed via governance parameter change proposals.
|
|
||||||
|
|
||||||
More information regarding gas in Cosmos SDK can be found [here](https://docs.cosmos.network/master/basics/gas-fees.html).
|
|
||||||
|
|
||||||
## Matching EVM Gas consumption
|
|
||||||
|
|
||||||
Ethermint is an EVM-compatible chain that supports Ethereum Web3 tooling. For this reason, gas
|
|
||||||
consumption must be equitable with other EVMs, most importantly Ethereum.
|
|
||||||
|
|
||||||
The main difference between EVM and Cosmos state transitions, is that the EVM uses a [gas table](https://github.com/ethereum/go-ethereum/blob/master/params/protocol_params.go) for each OPCODE, whereas Cosmos uses a `GasConfig` that charges gas for each CRUD operation by setting a flat and per-byte cost for accessing the database.
|
|
||||||
|
|
||||||
+++ https://github.com/cosmos/cosmos-sdk/blob/3fd376bd5659f076a4dc79b644573299fd1ec1bf/store/types/gas.go#L187-L196
|
|
||||||
|
|
||||||
In order to match the the gas consumed by the EVM, the gas consumption logic from the SDK is ignored, and instead the gas consumed is calculated by subtracting the state transition leftover gas plus refund from the gas limit defined on the message.
|
|
||||||
|
|
||||||
To ignore the SDK gas consumption, we reset the transaction `GasMeter` count to 0 and manually set it to the `gasUsed` value computed by the EVM module at the end of the execution.
|
|
||||||
|
|
||||||
+++ https://github.com/tharsis/ethermint/blob/098da6d0cc0e0c4cefbddf632df1057383973e4a/x/evm/keeper/state_transition.go#L188
|
|
||||||
|
|
||||||
### `AnteHandler`
|
|
||||||
|
|
||||||
The Cosmos SDK [`AnteHandler`](https://docs.cosmos.network/master/basics/gas-fees.html#antehandler)
|
|
||||||
performs basic checks prior to transaction execution. These checks are usually signature
|
|
||||||
verification, transaction field validation, transaction fees, etc.
|
|
||||||
|
|
||||||
Regarding gas consumption and fees, the `AnteHandler` checks that the user has enough balance to
|
|
||||||
cover for the tx cost (amount plus fees) as well as checking that the gas limit defined in the
|
|
||||||
message is greater or equal than the computed intrinsic gas for the message.
|
|
||||||
|
|
||||||
## Gas Refunds
|
|
||||||
|
|
||||||
In the EVM, gas can be specified prior to execution. The totality of the gas specified is consumed at the beginning of the execution (during the `AnteHandler` step) and the remaining gas is refunded back to
|
|
||||||
the user if any gas is left over after the execution. Additionally the EVM can also define gas to be refunded back to the user but those will be capped to a fraction of the used gas depending on the fork/version being used.
|
|
||||||
|
|
||||||
## 0 Fee Transactions
|
|
||||||
|
|
||||||
In Cosmos, a minimum gas price is not enforced by the `AnteHandler` as the `min-gas-prices` is
|
|
||||||
checked against the local node/validator. In other words, the minimum fees accepted are determined
|
|
||||||
by the validators of the network, and each validator can specify a different minimum value for their fees.
|
|
||||||
This potentially allows end users to submit 0 fee transactions if there is at least one single
|
|
||||||
validator that is willing to include transactions with `0` gas price in their blocks proposed.
|
|
||||||
|
|
||||||
For this same reason, in Ethermint it is possible to send transactions with `0` fees for transaction
|
|
||||||
types other than the ones defined by the `evm` module. EVM module transactions cannot have `0` fees
|
|
||||||
as gas is required inherently by the EVM. This check is done by the EVM transactions stateless validation
|
|
||||||
(i.e `ValidateBasic`) function as well as on the custom `AnteHandler` defined by Ethermint.
|
|
||||||
|
|
||||||
## Gas estimation
|
|
||||||
|
|
||||||
Ethereum provides a JSON-RPC endpoint `eth_estimateGas` to help users set up a correct gas limit in their transactions.
|
|
||||||
|
|
||||||
Unfortunately, we cannot make use of the SDK `tx simulation` for gas estimation because the pre-check in the Ante Handlers would require a valid signature, and the sender balance to be enough to pay for the gas. But in Ethereum, this endpoint can be called without specifying any sender address.
|
|
||||||
|
|
||||||
For that reason, a specific query API `EstimateGas` is implemented in Ethermint. It will apply the transaction against the current block/state and perform a binary search in order to find the optimal gas value to return to the user (the same transaction will be applied over and over until we find the minimum gas needed before it fails). The reason we need to use a binary search is that the gas required for the
|
|
||||||
transaction might be higher than the value returned by the EVM after applying the transaction, so we need to try until we find the optimal value.
|
|
||||||
|
|
||||||
A cache context will be used during the whole execution to avoid changes be persisted in the state.
|
|
||||||
|
|
||||||
+++ https://github.com/tharsis/ethermint/blob/098da6d0cc0e0c4cefbddf632df1057383973e4a/x/evm/keeper/grpc_query.go#L100
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
@@ -1,32 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 5
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Tokens
|
|
||||||
|
|
||||||
Learn about the the different types of tokens available in Ethermint. {synopsis}
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
Ethermint is a Cosmos SDK-based chain with full EVM support. Because of this architecture, tokens and assets in the network may come from different independent sources: the `bank` module and the `evm` module.
|
|
||||||
|
|
||||||
## Cosmos Coins
|
|
||||||
|
|
||||||
Accounts can own SDK coins in their balance, which are used for operations with other Cosmos modules and transactions. Examples of these are using the coins for staking, IBC transfers, governance deposits and EVM
|
|
||||||
|
|
||||||
### Photon
|
|
||||||
|
|
||||||
The denomination used for staking, governance and gas consumption on the EVM is the Photon. The Photon provides the utility of: securing the Proof-of-Stake chain, token used for governance proposals, fee distribution and as a mean of gas for running smart contracts on the EVM.
|
|
||||||
|
|
||||||
Ethermint uses [Atto](https://en.wikipedia.org/wiki/Atto-) Photon as the base denomination to maintain parity with Ethereum.
|
|
||||||
|
|
||||||
$$1 photon = 1 ~ * ~ 10^{18} aphoton$$
|
|
||||||
|
|
||||||
This matches Ethereum denomination of:
|
|
||||||
|
|
||||||
$$1 ETH = 1 ~ * ~ 10^{18} wei$$
|
|
||||||
|
|
||||||
### EVM Tokens
|
|
||||||
|
|
||||||
Ethermint is compatible with ERC20 tokens and other non-fungible token standards (EIP721, EIP1155)
|
|
||||||
that are natively supported by the EVM.
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 3
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Transaction Lifecycle
|
|
||||||
|
|
||||||
This document describes the lifecycle of a transaction from creation to committed state changes on the EVM. {synopsis}
|
|
||||||
|
|
||||||
## Pre-requisite Readings
|
|
||||||
|
|
||||||
- [SDK transaction lifecycle](https://docs.cosmos.network/master/basics/tx-lifecycle.html) {prereq}
|
|
||||||
|
|
||||||
<!-- TODO: rewrite. This is not a lifecycle doc -->
|
|
||||||
## Routing
|
|
||||||
|
|
||||||
Ethermint needs to parse and handle transactions routed for both the EVM and for Cosmos SDK modules. We
|
|
||||||
attempt to achieve this by mimicking [geth's](https://github.com/ethereum/go-ethereum) `Transaction`
|
|
||||||
structure and treat it as a unique Cosmos SDK message type. An Ethereum transaction is a single
|
|
||||||
[`sdk.Msg`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#Msg). All relevant Ethereum
|
|
||||||
transaction information is contained in this message. This includes the signature, gas, payload,
|
|
||||||
amount, etc.
|
|
||||||
|
|
||||||
Being that Ethermint implements the Tendermint ABCI application interface, as transactions are
|
|
||||||
consumed, they are passed through a series of handlers. Once such handler, the `AnteHandler`, is
|
|
||||||
responsible for performing preliminary message execution business logic such as fee payment,
|
|
||||||
signature verification, etc. This is particular to Cosmos SDK routed transactions. Ethereum routed
|
|
||||||
transactions will bypass this as the EVM handles the same business logic.
|
|
||||||
|
|
||||||
All EVM transactions are [RLP](./../core/encoding.md#rlp) encoded using a custom tx encoder.
|
|
||||||
|
|
||||||
## Signers
|
|
||||||
|
|
||||||
The signature processing and verification in Ethereum is performed by the `Signer` interface. The
|
|
||||||
protocol supports different signer types based on the chain configuration params and the block number.
|
|
||||||
|
|
||||||
+++ https://github.com/ethereum/go-ethereum/blob/v1.10.3/core/types/transaction_signing.go#L145-L166
|
|
||||||
|
|
||||||
Ethermint supports all Ethereum `Signer`s up to the latest go-ethereum version (London, Berlin,
|
|
||||||
EIP155, Homestead and Frontier). The chain will generate the latest `Signer` type depending on the
|
|
||||||
`ChainConfig`.
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: false
|
|
||||||
parent:
|
|
||||||
order: 4
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Core Concepts
|
|
||||||
|
|
||||||
This repository contains reference documentation on the core concepts of Ethermint.
|
|
||||||
|
|
||||||
1. [Encoding](./encoding.md)
|
|
||||||
2. [Pending State](./pending_state.md)
|
|
||||||
|
|
||||||
After reading the core concepts, head on to the [guides](../guides/README.md) to learn how to use Ethereum tooling with Ethermint.
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 1
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Encoding
|
|
||||||
|
|
||||||
Learn about the encoding formats used on Ethermint. {synopsis}
|
|
||||||
|
|
||||||
## Pre-requisite Readings
|
|
||||||
|
|
||||||
- [Cosmos SDK Encoding](https://docs.cosmos.network/master/core/encoding.html) {prereq}
|
|
||||||
- [Ethereum RLP](https://eth.wiki/en/fundamentals/rlp) {prereq}
|
|
||||||
|
|
||||||
## Encoding Formats
|
|
||||||
|
|
||||||
### Protocol Buffers
|
|
||||||
|
|
||||||
The Cosmos [Stargate](https://stargate.cosmos.network/) release introduces
|
|
||||||
[protobuf](https://developers.google.com/protocol-buffers) as the main encoding format for both
|
|
||||||
client and state serialization. All the EVM module types that are used for state and clients
|
|
||||||
(transaction messages, genesis, query services, etc) will be implemented as protocol buffer messages.
|
|
||||||
|
|
||||||
### Amino
|
|
||||||
|
|
||||||
The Cosmos SDK also supports the legacy Amino encoding format for backwards compatibility with
|
|
||||||
previous versions, specially for client encoding and signing with Ledger devices. Ethermint does not
|
|
||||||
support Amino in the EVM module, but it is supported for all other Cosmos SDK modules that enable it.
|
|
||||||
|
|
||||||
### RLP
|
|
||||||
|
|
||||||
Recursive Length Prefix ([RLP](https://eth.wiki/en/fundamentals/rlp)), is an encoding/decoding algorithm that serializes a message and
|
|
||||||
allows for quick reconstruction of encoded data. Ethermint uses RLP to encode/decode Ethereum
|
|
||||||
messages for JSON-RPC handling to conform messages to the proper Ethereum format. This allows
|
|
||||||
messages to be encoded and decoded in the exact format as Ethereum's.
|
|
||||||
|
|
||||||
The `x/evm` transactions (`MsgEthereumTx`) encoding is performed by casting the message to a go-ethereum's `Transaction` and then marshaling the transaction data using RLP:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// TxEncoder overwrites sdk.TxEncoder to support MsgEthereumTx
|
|
||||||
func (g txConfig) TxEncoder() sdk.TxEncoder {
|
|
||||||
return func(tx sdk.Tx) ([]byte, error) {
|
|
||||||
msg, ok := tx.(*evmtypes.MsgEthereumTx)
|
|
||||||
if ok {
|
|
||||||
return msg.AsTransaction().MarshalBinary()
|
|
||||||
}
|
|
||||||
return g.TxConfig.TxEncoder()(tx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TxDecoder overwrites sdk.TxDecoder to support MsgEthereumTx
|
|
||||||
func (g txConfig) TxDecoder() sdk.TxDecoder {
|
|
||||||
return func(txBytes []byte) (sdk.Tx, error) {
|
|
||||||
tx := ðtypes.Transaction{}
|
|
||||||
|
|
||||||
err := tx.UnmarshalBinary(txBytes)
|
|
||||||
if err == nil {
|
|
||||||
msg := &evmtypes.MsgEthereumTx{}
|
|
||||||
msg.FromEthereumTx(tx)
|
|
||||||
return msg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return g.TxConfig.TxDecoder()(txBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Next {hide}
|
|
||||||
|
|
||||||
Learn how [pending state](./pending_state.md) is handled on Ethermint. {hide}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: 2
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Pending State
|
|
||||||
|
|
||||||
Learn how Ethermint handles pending state queries. {synopsis}
|
|
||||||
|
|
||||||
## Pre-requisite Readings
|
|
||||||
|
|
||||||
- [Tendermint Mempool](https://docs.tendermint.com/master/tendermint-core/mempool.htm) {prereq}
|
|
||||||
|
|
||||||
## Ethermint vs Ethereum
|
|
||||||
|
|
||||||
In Ethereum, pending blocks are generated as they are queued for production by miners. These pending
|
|
||||||
blocks include pending transactions that are picked out by miners, based on the highest reward paid
|
|
||||||
in gas. This mechanism exists as block finality is not possible on the Ethereum network. Blocks are
|
|
||||||
committed with probabilistic finality, which means that transactions and blocks become less likely
|
|
||||||
to become reverted as more time (and blocks) passes.
|
|
||||||
|
|
||||||
Ethermint is designed quite differently on this front as there is no concept of a "pending state".
|
|
||||||
Ethermint uses [Tendermint Core](https://docs.tendermint.com/) BFT consensus which provides instant
|
|
||||||
finality for transaction. For this reason, Etheremint does not require a pending state mechanism, as
|
|
||||||
all (if not most) of the transactions will be committed to the next block (avg. block time on Cosmos chains is ~8s). However, this causes a
|
|
||||||
few hiccups in terms of the Ethereum Web3-compatible queries that can be made to pending state.
|
|
||||||
|
|
||||||
Another significant difference with Ethereum, is that blocks are produced by validators or block producers, who include transactions from their local mempool into blocks in a
|
|
||||||
first-in-first-out (FIFO) fashion. Transactions on Ethermint cannot be ordered or cherry picked out from the Tendermint node [mempool](https://docs.tendermint.com/master/tendermint-core/mempool.html#transaction-ordering).
|
|
||||||
|
|
||||||
## Pending State Queries
|
|
||||||
|
|
||||||
Ethermint will make queries which will account for any unconfirmed transactions present in a node's
|
|
||||||
transaction mempool. A pending state query made will be subjective and the query will be made on the
|
|
||||||
target node's mempool. Thus, the pending state will not be the same for the same query to two
|
|
||||||
different nodes.
|
|
||||||
|
|
||||||
### JSON-RPC Calls on Pending Transactions
|
|
||||||
|
|
||||||
- [`eth_getBalance`](./../api/json-rpc/endpoints.md#eth_getbalance)
|
|
||||||
- [`eth_getTransactionCount`](./../api/json-rpc/endpoints.md#eth-gettransactioncount)
|
|
||||||
- [`eth_getBlockTransactionCountByNumber`](./../api/json-rpc/endpoints.md#eth-getblocktransactioncountbynumber)
|
|
||||||
- [`eth_getBlockByNumber`](./../api/json-rpc/endpoints.md#eth-getblockbynumber)
|
|
||||||
- [`eth_getTransactionByHash`](./../api/json-rpc/endpoints.md#eth-gettransactionbyhash)
|
|
||||||
- [`eth_getTransactionByBlockNumberAndIndex`](./../api/json-rpc/endpoints.html#eth-gettransactionbyblockhashandindex)
|
|
||||||
- [`eth_sendTransaction`](./../api/json-rpc/endpoints.md#eth-sendtransaction)
|
|
||||||
|
|
||||||
## Next {hide}
|
|
||||||
|
|
||||||
Learn how to deploy a Solidity smart contract on Ethermint using [Truffle](./../guides/truffle.md) {hide}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
# Snapshot and Revert in Ethermint
|
|
||||||
|
|
||||||
EVM uses state-reverting exceptions to handle errors. Such an exception will undo all changes made to the state in the current call (and all its sub-calls), and the caller could handle the error and don't propagate. We need to implement the `Snapshot` and `RevertToSnapshot` apis in `StateDB` interfaces to support this feature.
|
|
||||||
|
|
||||||
[go-ethereum implementation](https://github.com/ethereum/go-ethereum/blob/master/core/state/journal.go#L39) manages transient states in memory, and uses a list of journal logs to record all the state modification operations done so far, snapshot is an index in the log list, and to revert to a snapshot it just undo the journal logs after the snapshot index in reversed order.
|
|
||||||
|
|
||||||
Ethermint uses cosmos-sdk's storage api to manage states, fortunately the storage api supports creating cached overlays, it works like this:
|
|
||||||
|
|
||||||
```golang
|
|
||||||
// create a cached overlay storage on top of ctx storage.
|
|
||||||
overlayCtx, commit := ctx.CacheContext()
|
|
||||||
// Modify states using the overlayed storage
|
|
||||||
err := doCall(overlayCtx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// commit will write the dirty states into the underlying storage
|
|
||||||
commit()
|
|
||||||
|
|
||||||
// Now, just drop the overlayCtx and keep using ctx
|
|
||||||
```
|
|
||||||
|
|
||||||
And it can be used in a nested way, like this:
|
|
||||||
|
|
||||||
```golang
|
|
||||||
overlayCtx1, commit1 := ctx.CacheContext()
|
|
||||||
doCall1(overlayCtx1)
|
|
||||||
{
|
|
||||||
overlayCtx2, commit2 := overlayCtx1.CacheContext()
|
|
||||||
doCall2(overlayCtx2)
|
|
||||||
commit2()
|
|
||||||
}
|
|
||||||
commit1()
|
|
||||||
```
|
|
||||||
|
|
||||||
With this feature, we can use a stake of overlayed contexts to implement nested `Snapshot` and `RevertToSnapshot` calls.
|
|
||||||
|
|
||||||
```golang
|
|
||||||
type cachedContext struct {
|
|
||||||
ctx sdk.Context
|
|
||||||
commit func()
|
|
||||||
}
|
|
||||||
var contextStack []cachedContext
|
|
||||||
func Snapshot() int {
|
|
||||||
ctx, commit := contextStack.Top().CacheContext()
|
|
||||||
contextStack.Push(cachedContext{ctx, commit})
|
|
||||||
return len(contextStack) - 1
|
|
||||||
}
|
|
||||||
func RevertToSnapshot(int snapshot) {
|
|
||||||
contextStack = contextStack[:snapshot]
|
|
||||||
}
|
|
||||||
func Commit() {
|
|
||||||
for i := len(contextStack) - 1; i >= 0; i-- {
|
|
||||||
contextStack[i].commit()
|
|
||||||
}
|
|
||||||
contextStack = {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<!--
|
|
||||||
order: false
|
|
||||||
parent:
|
|
||||||
order: 5
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Guides
|
|
||||||
|
|
||||||
1. Localnet
|
|
||||||
* [Single Node Localnet](./localnet/single_node)
|
|
||||||
* [Multi Node Localnet](./localnet/multi_node)
|
|
||||||
2. Keys and Wallets
|
|
||||||
* [Keyring](./keys-wallets/keyring)
|
|
||||||
* [MetaMask](./keys-wallets/metamask)
|
|
||||||
3. Ethereum Tooling
|
|
||||||
* [Remix](./tools/remix)
|
|
||||||
* [Hardhat](./tools/hardhat)
|
|
||||||
* [Truffle](./tools/truffle)
|
|
||||||
4. [Validators](./validators/overview)
|
|
||||||
5. [Key Management System](./kms/kms)
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 159 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user