mirror of
https://github.com/0glabs/0g-chain.git
synced 2025-04-04 15:55:23 +00:00
Compare commits
425 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
80208ed9b7 | ||
![]() |
96926b4cbf | ||
![]() |
da2e0feffb | ||
![]() |
2c436a7d45 | ||
![]() |
4c48f7ea63 | ||
![]() |
2cc584be0b | ||
![]() |
d8e968146b | ||
![]() |
962943d32b | ||
![]() |
b42c82d59c | ||
![]() |
08000544c9 | ||
![]() |
248db0f47c | ||
![]() |
0b027e10ed | ||
![]() |
e41c65c92d | ||
![]() |
c70b0a1c2b | ||
![]() |
9b171dbd4c | ||
![]() |
4ff1ab24d1 | ||
![]() |
384d899eff | ||
![]() |
c2fdb3109e | ||
![]() |
45508f5954 | ||
![]() |
72e8508651 | ||
![]() |
c066af2a47 | ||
![]() |
d1b83b5ac8 | ||
![]() |
dc888ceb78 | ||
![]() |
ea3e4b84e8 | ||
![]() |
553d111f40 | ||
![]() |
351c2cb132 | ||
![]() |
6f83c22853 | ||
![]() |
4d95fd5f30 | ||
![]() |
e54d5ba99a | ||
![]() |
a0426c63f7 | ||
![]() |
a32dad8373 | ||
![]() |
4f53e59af7 | ||
![]() |
8ecfda7bd2 | ||
![]() |
bbd02215f7 | ||
![]() |
d4066b6a3d | ||
![]() |
7900795654 | ||
![]() |
6df54c84b5 | ||
![]() |
ec7e0c3163 | ||
![]() |
ac043ff438 | ||
![]() |
e6b13d85a1 | ||
![]() |
f04c87506b | ||
![]() |
65a4f9128b | ||
![]() |
0a79fe53a2 | ||
![]() |
aed6a6161a | ||
![]() |
75cccf2c8f | ||
![]() |
db1d6463ec | ||
![]() |
1a039a0d13 | ||
![]() |
6ed21ea3fb | ||
![]() |
8b43aa4064 | ||
![]() |
2500f6cb31 | ||
![]() |
88304562cc | ||
![]() |
58871957a8 | ||
![]() |
aff086bf7b | ||
![]() |
0ff16c798a | ||
![]() |
e2668ad80d | ||
![]() |
2fa73957a9 | ||
![]() |
32cd094bbc | ||
![]() |
6037a00869 | ||
![]() |
559d1beb03 | ||
![]() |
4db9ee49b4 | ||
![]() |
ac57a9b4b4 | ||
![]() |
5051f75b52 | ||
![]() |
5c8ced4b37 | ||
![]() |
47b6341324 | ||
![]() |
ae7d1ad2a7 | ||
![]() |
3e427e5bdd | ||
![]() |
9e1ec04010 | ||
![]() |
76eebc57c1 | ||
![]() |
100bad3471 | ||
![]() |
605a71e826 | ||
![]() |
1602c96a40 | ||
![]() |
759d08a6eb | ||
![]() |
f2abb98d6c | ||
![]() |
77bfade203 | ||
![]() |
e308e44dd6 | ||
![]() |
58875c1bc9 | ||
![]() |
c80874b0ea | ||
![]() |
96e70d3cbd | ||
![]() |
f9ef0bac6e | ||
![]() |
5f2089b4c5 | ||
![]() |
a4b8d77411 | ||
![]() |
f5ce18dd5f | ||
![]() |
890e858558 | ||
![]() |
afacc89c8d | ||
![]() |
38764453a5 | ||
![]() |
a90bd43999 | ||
![]() |
46d159a18c | ||
![]() |
840deea660 | ||
![]() |
6c3360f102 | ||
![]() |
80b2dacbc2 | ||
![]() |
1152537679 | ||
![]() |
5bd6ac39ee | ||
![]() |
e0fcd07a08 | ||
![]() |
70ac592012 | ||
![]() |
de22587a5b | ||
![]() |
0c02c27a9d | ||
![]() |
4409bfc996 | ||
![]() |
723241f484 | ||
![]() |
84d1a89bec | ||
![]() |
94ddf20305 | ||
![]() |
4ebbb886bf | ||
![]() |
57943ec0e0 | ||
![]() |
04ce67f6a9 | ||
![]() |
500e66733d | ||
![]() |
8b691e61f8 | ||
![]() |
a0bdd2a142 | ||
![]() |
53dcea2867 | ||
![]() |
d31a599c60 | ||
![]() |
07cf4ad258 | ||
![]() |
cb4e6e006e | ||
![]() |
0e37d518ec | ||
![]() |
822e374be6 | ||
![]() |
9ca8359202 | ||
![]() |
32bcc7f4e3 | ||
![]() |
f50a429527 | ||
![]() |
8ff2277450 | ||
![]() |
cdf029c87a | ||
![]() |
5f9325c2a0 | ||
![]() |
5f4f1851cb | ||
![]() |
4c28427089 | ||
![]() |
0f40b721ee | ||
![]() |
ec3733a2c6 | ||
![]() |
8df7625ac1 | ||
![]() |
31c96eeb93 | ||
![]() |
ac1af4ae92 | ||
![]() |
0d54bb9202 | ||
![]() |
73158cd738 | ||
![]() |
73b7d800a3 | ||
![]() |
27ddc91956 | ||
![]() |
9962b7b0db | ||
![]() |
f415fb1332 | ||
![]() |
28b9c07e02 | ||
![]() |
45b7920181 | ||
![]() |
56d337df16 | ||
![]() |
85059d734e | ||
![]() |
6b4e8415da | ||
![]() |
77b817f9b8 | ||
![]() |
46378d6157 | ||
![]() |
d0721fd172 | ||
![]() |
5e34f5b289 | ||
![]() |
d6bca1b221 | ||
![]() |
8dc89ad08d | ||
![]() |
e4989f10cd | ||
![]() |
9839a244bf | ||
![]() |
c9043ca158 | ||
![]() |
8d48dadb02 | ||
![]() |
c80be7bbf7 | ||
![]() |
17fa02b554 | ||
![]() |
e348bd3748 | ||
![]() |
f44d7cc94d | ||
![]() |
0bfbd114c9 | ||
![]() |
483a939724 | ||
![]() |
547b0057c7 | ||
![]() |
1da9745903 | ||
![]() |
e952a4a705 | ||
![]() |
69a4a6298e | ||
![]() |
d05c2f9563 | ||
![]() |
82f54a1974 | ||
![]() |
3f1140dcd4 | ||
![]() |
849c95d93e | ||
![]() |
eee50a3f75 | ||
![]() |
1d2820a3b6 | ||
![]() |
950e4766d2 | ||
![]() |
91698d388f | ||
![]() |
4cf57457a7 | ||
![]() |
337f1c5cc8 | ||
![]() |
a437523ea2 | ||
![]() |
77ec52e16b | ||
![]() |
b1365fb792 | ||
![]() |
d61f4e94fd | ||
![]() |
8bc3b15c46 | ||
![]() |
e8008c9a3a | ||
![]() |
28fa4b7993 | ||
![]() |
bd0acdbd4b | ||
![]() |
7f62518464 | ||
![]() |
0b4c5da294 | ||
![]() |
ad93042155 | ||
![]() |
a7dd451e44 | ||
![]() |
c99879e9f7 | ||
![]() |
820a676709 | ||
![]() |
27feb30bb9 | ||
![]() |
17bd9a6c71 | ||
![]() |
c172fb3c55 | ||
![]() |
0eb947b594 | ||
![]() |
a2746657a1 | ||
![]() |
493ce0516f | ||
![]() |
65d091d458 | ||
![]() |
8023be0067 | ||
![]() |
eaacd83de5 | ||
![]() |
6862cde560 | ||
![]() |
b8e6e584b8 | ||
![]() |
27d63f157c | ||
![]() |
7aede3390d | ||
![]() |
49f7be8486 | ||
![]() |
fbce24abef | ||
![]() |
7e50ce8142 | ||
![]() |
43dd1a7c41 | ||
![]() |
72d30dde8a | ||
![]() |
c18ca45188 | ||
![]() |
f50d847c4f | ||
![]() |
568ff70ad7 | ||
![]() |
1355bd6ab1 | ||
![]() |
ceb4d774ff | ||
![]() |
ab3cf7c994 | ||
![]() |
8bd14a6c00 | ||
![]() |
78caabebe1 | ||
![]() |
f4408080e6 | ||
![]() |
1d2504b085 | ||
![]() |
33932e8ad6 | ||
![]() |
ab10ce628c | ||
![]() |
edf2935f31 | ||
![]() |
a4583be44b | ||
![]() |
3c4d91a443 | ||
![]() |
774e2efce8 | ||
![]() |
30728b75e9 | ||
![]() |
e822edfe8d | ||
![]() |
d2406d4efd | ||
![]() |
e8e2e3abd3 | ||
![]() |
2da75122b3 | ||
![]() |
ed5646b71a | ||
![]() |
4aa67c9efb | ||
![]() |
bd3d947e9b | ||
![]() |
a8c86f7f8b | ||
![]() |
058d9f2285 | ||
![]() |
3709a23632 | ||
![]() |
04dfd2a2e9 | ||
![]() |
932664efac | ||
![]() |
c949c06fce | ||
![]() |
14ca626365 | ||
![]() |
008b421fd2 | ||
![]() |
ac1fd4360d | ||
![]() |
d35b277cab | ||
![]() |
2c248aff18 | ||
![]() |
4ab0d3ee27 | ||
![]() |
8d761147a2 | ||
![]() |
4917eb5976 | ||
![]() |
f8d5f29078 | ||
![]() |
efee71e2e6 | ||
![]() |
6190839ddc | ||
![]() |
c1efdaa507 | ||
![]() |
62c5eaf515 | ||
![]() |
48c349c127 | ||
![]() |
4b09c6cd37 | ||
![]() |
02e96e6424 | ||
![]() |
b3a8343a19 | ||
![]() |
c6e4563cac | ||
![]() |
7d4828f415 | ||
![]() |
1fbf607360 | ||
![]() |
154dd509ee | ||
![]() |
986172d3a7 | ||
![]() |
4fabd4d011 | ||
![]() |
e25cc5f531 | ||
![]() |
6202424c27 | ||
![]() |
c7ed82b4f4 | ||
![]() |
a3f3aaaecc | ||
![]() |
701a0ba97e | ||
![]() |
1e0194262d | ||
![]() |
e3e47e5e2f | ||
![]() |
93cceff23c | ||
![]() |
1680cd6b32 | ||
![]() |
284181edc9 | ||
![]() |
422e940c28 | ||
![]() |
bb5d5130cf | ||
![]() |
b53783447b | ||
![]() |
6f2b402294 | ||
![]() |
82139161be | ||
![]() |
4798eea3ff | ||
![]() |
ee01ac7a7b | ||
![]() |
47cee39c64 | ||
![]() |
521f558f5d | ||
![]() |
adb09a7c82 | ||
![]() |
3da66a87e6 | ||
![]() |
19a202669a | ||
![]() |
eaf81e9465 | ||
![]() |
817a8a151a | ||
![]() |
78114aed73 | ||
![]() |
34a76200f0 | ||
![]() |
fe8c36f891 | ||
![]() |
8357cc2191 | ||
![]() |
f8e102fbd5 | ||
![]() |
d1c3f36bbe | ||
![]() |
89d3829646 | ||
![]() |
ffad9dbdd5 | ||
![]() |
0bbaeb0393 | ||
![]() |
cc4f72b165 | ||
![]() |
6a197a5db5 | ||
![]() |
e787cd052e | ||
![]() |
2454c94596 | ||
![]() |
454733f55b | ||
![]() |
14e1e3a7d4 | ||
![]() |
ca3ab93657 | ||
![]() |
c8bf4644c1 | ||
![]() |
272f82ec99 | ||
![]() |
e198eeb3b4 | ||
![]() |
bbfaa54ddf | ||
![]() |
4e66a56208 | ||
![]() |
9c629ad113 | ||
![]() |
b0d737d354 | ||
![]() |
a8df31b31a | ||
![]() |
6243944db6 | ||
![]() |
7f339d20ca | ||
![]() |
916ec6d30c | ||
![]() |
b4c04656ab | ||
![]() |
837e57ec2e | ||
![]() |
5f802fcfbd | ||
![]() |
f229afce1a | ||
![]() |
608f70b20a | ||
![]() |
74f76d125c | ||
![]() |
3853e276a6 | ||
![]() |
7aef2f09e9 | ||
![]() |
58d7c89f8e | ||
![]() |
d2d661276e | ||
![]() |
9de9de671e | ||
![]() |
ce6aac3a72 | ||
![]() |
23ce7d8169 | ||
![]() |
60a8073574 | ||
![]() |
2d07988994 | ||
![]() |
6a9eda8634 | ||
![]() |
4788c064bf | ||
![]() |
1743cf5275 | ||
![]() |
9aef8e4971 | ||
![]() |
38230d35e3 | ||
![]() |
af5eea690b | ||
![]() |
1c1db357f5 | ||
![]() |
409841c79c | ||
![]() |
4c3f6533a0 | ||
![]() |
e1bd6ffa2f | ||
![]() |
5b0e7c8c58 | ||
![]() |
8d85c1ae1e | ||
![]() |
80f2370d68 | ||
![]() |
16233d6031 | ||
![]() |
828f17897e | ||
![]() |
a79d852d1c | ||
![]() |
0306bec0ae | ||
![]() |
5c51530b8e | ||
![]() |
21dc0e21b3 | ||
![]() |
8d07d9cb3b | ||
![]() |
e7cc89a642 | ||
![]() |
2e8c7ce337 | ||
![]() |
110adcab2c | ||
![]() |
3d5f5902b8 | ||
![]() |
4cf41d18c2 | ||
![]() |
dbc3ad7fd2 | ||
![]() |
7990021431 | ||
![]() |
fa33947496 | ||
![]() |
4ff43eb270 | ||
![]() |
d66b7d2705 | ||
![]() |
025b7b2cdb | ||
![]() |
94914d4ca1 | ||
![]() |
3c53e72220 | ||
![]() |
871e26670c | ||
![]() |
da2f835bf7 | ||
![]() |
6a7fd4c8bd | ||
![]() |
f72b628b71 | ||
![]() |
3e877aca88 | ||
![]() |
360f21f9f8 | ||
![]() |
d981070ede | ||
![]() |
346f4be683 | ||
![]() |
1b6f1468ec | ||
![]() |
72e8641c8d | ||
![]() |
ac2e46f91e | ||
![]() |
4686a2a3e9 | ||
![]() |
667e532aaa | ||
![]() |
32a0193c45 | ||
![]() |
543417c01f | ||
![]() |
be5bf62ab8 | ||
![]() |
41b79e44af | ||
![]() |
0ea92335de | ||
![]() |
2a93c41fcc | ||
![]() |
3033529d9f | ||
![]() |
7ca43024e4 | ||
![]() |
c9d900be2c | ||
![]() |
8f93ca2048 | ||
![]() |
198b620cb4 | ||
![]() |
e34c94aa62 | ||
![]() |
d3233d65d5 | ||
![]() |
6ea518960a | ||
![]() |
673790465d | ||
![]() |
a548de05c2 | ||
![]() |
3afb656d1f | ||
![]() |
7f73061c13 | ||
![]() |
da8a4f8787 | ||
![]() |
e96fd1735d | ||
![]() |
eb9d3a3ed8 | ||
![]() |
969614d555 | ||
![]() |
7866ee2f74 | ||
![]() |
66e41733e7 | ||
![]() |
a681a5e631 | ||
![]() |
6b41ed84b8 | ||
![]() |
17691e95a8 | ||
![]() |
cf2d83b020 | ||
![]() |
5c0f27b952 | ||
![]() |
322f2ac056 | ||
![]() |
9bfd1ffd7d | ||
![]() |
f5384a1f11 | ||
![]() |
2a1e9a6631 | ||
![]() |
069be95dde | ||
![]() |
1d944d5219 | ||
![]() |
11d3ba3466 | ||
![]() |
2bc0c62570 | ||
![]() |
58d04e2996 | ||
![]() |
ad387e6a42 | ||
![]() |
550ecc8027 | ||
![]() |
5914f1db85 | ||
![]() |
ad03a75679 | ||
![]() |
c0df29333b | ||
![]() |
45aa631f18 | ||
![]() |
614d4e40fe | ||
![]() |
7efee6d536 | ||
![]() |
c59a491788 | ||
![]() |
2bccb6deaf | ||
![]() |
7b5de0a12a | ||
![]() |
4d62f47773 | ||
![]() |
3767030005 | ||
![]() |
58621577ae | ||
![]() |
f00727fe85 | ||
![]() |
b170f3bdd5 | ||
![]() |
1aa1348944 | ||
![]() |
ffd306ef52 | ||
![]() |
c63fab1317 | ||
![]() |
f70349ab02 | ||
![]() |
1d4ccf6657 | ||
![]() |
aca738fbc6 | ||
![]() |
39146747ac | ||
![]() |
967c6857e8 |
@ -1,9 +1,20 @@
|
||||
out/
|
||||
**/node_modules/
|
||||
.git/
|
||||
docs/
|
||||
.github/
|
||||
tests/
|
||||
|
||||
ci/
|
||||
contracts/
|
||||
contrib/
|
||||
docs/
|
||||
networks/
|
||||
scratch/
|
||||
|
||||
# Ignore build cache directories to avoid
|
||||
# errors when addings these to docker images
|
||||
build/.cache
|
||||
build/.golangci-lint
|
||||
|
||||
go.work
|
||||
go.work.sum
|
||||
|
3
.github/CODEOWNERS
vendored
Normal file
3
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
||||
# Global rule:
|
||||
* @rhuairahrighairidh @karzak @pirtleshell @drklee3 @nddeluca @DracoLi @evgeniy-scherbina @sesheffield @boodyvo @lbayas
|
20
.github/mergify.yml
vendored
20
.github/mergify.yml
vendored
@ -25,6 +25,8 @@ pull_request_rules:
|
||||
- release/v0.21.x
|
||||
- release/v0.23.x
|
||||
- release/v0.24.x
|
||||
- release/v0.25.x
|
||||
- release/v0.26.x
|
||||
|
||||
- name: Backport patches to the release/v0.17.x branch
|
||||
conditions:
|
||||
@ -79,3 +81,21 @@ pull_request_rules:
|
||||
backport:
|
||||
branches:
|
||||
- release/v0.24.x
|
||||
|
||||
- name: Backport patches to the release/v0.25.x branch
|
||||
conditions:
|
||||
- base=master
|
||||
- label=A:backport/v0.25.x
|
||||
actions:
|
||||
backport:
|
||||
branches:
|
||||
- release/v0.25.x
|
||||
|
||||
- name: Backport patches to the release/v0.26.x branch
|
||||
conditions:
|
||||
- base=master
|
||||
- label=A:backport/v0.26.x
|
||||
actions:
|
||||
backport:
|
||||
branches:
|
||||
- release/v0.26.x
|
||||
|
@ -33,7 +33,7 @@ kava config chain-id "${CHAIN_ID}"
|
||||
kava config keyring-backend test
|
||||
|
||||
# wait for transactions to be committed per CLI command
|
||||
kava config broadcast-mode block
|
||||
kava config broadcast-mode sync
|
||||
|
||||
# setup god's wallet
|
||||
echo "${KAVA_TESTNET_GOD_MNEMONIC}" | kava keys add --recover god
|
||||
@ -80,7 +80,7 @@ printf "original evm util module params\n %s" , "$originalEvmUtilParams"
|
||||
# change the params of the chain like a god - make it so 🖖🏽
|
||||
# make sure to update god committee member permissions for the module
|
||||
# and params being updated (see below for example)
|
||||
# https://github.com/Kava-Labs/kava/pull/1556/files#diff-0bd6043650c708661f37bbe6fa5b29b52149e0ec0069103c3954168fc9f12612R900-R903
|
||||
# https://github.com/0glabs/0g-chain/pull/1556/files#diff-0bd6043650c708661f37bbe6fa5b29b52149e0ec0069103c3954168fc9f12612R900-R903
|
||||
kava tx committee submit-proposal 1 "$proposalFileName" --gas 2000000 --gas-prices 0.01ukava --from god -y
|
||||
|
||||
# fetch current module params
|
||||
|
4
.github/scripts/install-rocksdb.sh
vendored
4
.github/scripts/install-rocksdb.sh
vendored
@ -7,9 +7,9 @@ sudo apt-get install -y libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4
|
||||
# get rocksdb sources
|
||||
git clone https://github.com/facebook/rocksdb.git /home/runner/rocksdb
|
||||
|
||||
cd /home/runner/rocksdb
|
||||
cd /home/runner/rocksdb || exit 1
|
||||
|
||||
git checkout "$ROCKSDB_VERSION"
|
||||
|
||||
# install rocksdb locally
|
||||
sudo make -j $(nproc --all) install-shared
|
||||
sudo make -j "$(nproc --all)" install-shared && sudo ldconfig
|
||||
|
82
.github/scripts/seed-internal-testnet.sh
vendored
82
.github/scripts/seed-internal-testnet.sh
vendored
@ -1,6 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
# by sleeping 1 block in between tx's
|
||||
# we can emulate the behavior of the
|
||||
# the deprecated and now removed (as of Kava 16)
|
||||
# broadcast mode of `block` in order to
|
||||
# minimize the chance tx's fail due to an
|
||||
# account sequence number mismatch
|
||||
AVG_SECONDS_BETWEEN_BLOCKS=6.5
|
||||
|
||||
# configure kava binary to talk to the desired chain endpoint
|
||||
kava config node "${CHAIN_API_URL}"
|
||||
kava config chain-id "${CHAIN_ID}"
|
||||
@ -9,7 +17,7 @@ kava config chain-id "${CHAIN_ID}"
|
||||
kava config keyring-backend test
|
||||
|
||||
# wait for transactions to be committed per CLI command
|
||||
kava config broadcast-mode block
|
||||
kava config broadcast-mode sync
|
||||
|
||||
# setup dev wallet
|
||||
echo "${DEV_WALLET_MNEMONIC}" | kava keys add --recover dev-wallet
|
||||
@ -23,6 +31,8 @@ echo "sweet ocean blush coil mobile ten floor sample nuclear power legend where
|
||||
# fund evm-contract-deployer account (using issuance)
|
||||
kava tx issuance issue 200000000ukava kava1van3znl6597xgwwh46jgquutnqkwvwszjg04fz --from dev-wallet --gas-prices 0.5ukava -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# deploy and fund USDC ERC20 contract
|
||||
MULTICHAIN_USDC_CONTRACT_DEPLOY=$(npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" deploy-erc20 "USD Coin" USDC 6)
|
||||
MULTICHAIN_USDC_CONTRACT_ADDRESS=${MULTICHAIN_USDC_CONTRACT_DEPLOY: -42}
|
||||
@ -73,6 +83,31 @@ TETHER_USDT_CONTRACT_DEPLOY=$(npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NA
|
||||
TETHER_USDT_CONTRACT_ADDRESS=${TETHER_USDT_CONTRACT_DEPLOY: -42}
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$TETHER_USDT_CONTRACT_ADDRESS" 0x6767114FFAA17C6439D7AEA480738B982CE63A02 1000000000000
|
||||
|
||||
# deploy and fund axlBNB ERC20 contract
|
||||
AXL_BNB_CONTRACT_DEPLOY=$(npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" deploy-erc20 "axlBNB" axlBNB 18)
|
||||
AXL_BNB_CONTRACT_ADDRESS=${AXL_BNB_CONTRACT_DEPLOY: -42}
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_BNB_CONTRACT_ADDRESS" 0x6767114FFAA17C6439D7AEA480738B982CE63A02 1000000000000000000000
|
||||
|
||||
# deploy and fund axlBUSD ERC20 contract
|
||||
AXL_BUSD_CONTRACT_DEPLOY=$(npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" deploy-erc20 "axlBUSD" axlBUSD 18)
|
||||
AXL_BUSD_CONTRACT_ADDRESS=${AXL_BUSD_CONTRACT_DEPLOY: -42}
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_BUSD_CONTRACT_ADDRESS" 0x6767114FFAA17C6439D7AEA480738B982CE63A02 1000000000000000000000
|
||||
|
||||
# deploy and fund axlXRPB ERC20 contract
|
||||
AXL_XRPB_CONTRACT_DEPLOY=$(npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" deploy-erc20 "axlXRPB" axlXRPB 18)
|
||||
AXL_XRPB_CONTRACT_ADDRESS=${AXL_XRPB_CONTRACT_DEPLOY: -42}
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_XRPB_CONTRACT_ADDRESS" 0x6767114FFAA17C6439D7AEA480738B982CE63A02 1000000000000000000000
|
||||
|
||||
# deploy and fund axlBTC ERC20 contract
|
||||
AXL_BTCB_CONTRACT_DEPLOY=$(npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" deploy-erc20 "axlBTCB" axlBTCB 18)
|
||||
AXL_BTCB_CONTRACT_ADDRESS=${AXL_BTCB_CONTRACT_DEPLOY: -42}
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_BTCB_CONTRACT_ADDRESS" 0x6767114FFAA17C6439D7AEA480738B982CE63A02 1000000000000000000000
|
||||
|
||||
# deploy and fund native wBTC ERC20 contract
|
||||
WBTC_CONTRACT_DEPLOY=$(npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" deploy-erc20 "wBTC" wBTC 8)
|
||||
WBTC_CONTRACT_ADDRESS=${WBTC_CONTRACT_DEPLOY: -42}
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$WBTC_CONTRACT_ADDRESS" 0x6767114FFAA17C6439D7AEA480738B982CE63A02 100000000000000000
|
||||
|
||||
# seed some evm wallets
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_WBTC_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 10000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$MULTICHAIN_wBTC_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 10000000000000
|
||||
@ -81,6 +116,11 @@ npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$wETH_CONTRAC
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_USDC_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 100000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$MULTICHAIN_USDT_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 100000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$TETHER_USDT_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 1000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_BNB_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 1000000000000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_BUSD_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 1000000000000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_XRPB_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 1000000000000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_BTCB_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 1000000000000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$WBTC_CONTRACT_ADDRESS" "$DEV_TEST_WALLET_ADDRESS" 10000000000000
|
||||
# seed webapp E2E whale account
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_WBTC_CONTRACT_ADDRESS" "$WEBAPP_E2E_WHALE_ADDRESS" 100000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$MULTICHAIN_wBTC_CONTRACT_ADDRESS" "$WEBAPP_E2E_WHALE_ADDRESS" 10000000000000
|
||||
@ -89,6 +129,11 @@ npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$wETH_CONTRAC
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_USDC_CONTRACT_ADDRESS" "$WEBAPP_E2E_WHALE_ADDRESS" 10000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$MULTICHAIN_USDT_CONTRACT_ADDRESS" "$WEBAPP_E2E_WHALE_ADDRESS" 1000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$TETHER_USDT_CONTRACT_ADDRESS" "$WEBAPP_E2E_WHALE_ADDRESS" 1000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_BNB_CONTRACT_ADDRESS" "$WEBAPP_E2E_WHALE_ADDRESS" 10000000000000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_BUSD_CONTRACT_ADDRESS" "$WEBAPP_E2E_WHALE_ADDRESS" 10000000000000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_BTCB_CONTRACT_ADDRESS" "$WEBAPP_E2E_WHALE_ADDRESS" 10000000000000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_XRPB_CONTRACT_ADDRESS" "$WEBAPP_E2E_WHALE_ADDRESS" 10000000000000000000000
|
||||
npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$WBTC_CONTRACT_ADDRESS" "$WBTC_CONTRACT_ADDRESS" 10000000000000
|
||||
|
||||
# give dev-wallet enough delegation power to pass proposals by itself
|
||||
|
||||
@ -96,6 +141,8 @@ npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$TETHER_USDT_
|
||||
kava tx issuance issue 6000000000ukava kava1vlpsrmdyuywvaqrv7rx6xga224sqfwz3fyfhwq \
|
||||
--from dev-wallet --gas-prices 0.5ukava -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# parse space seperated list of validators
|
||||
# into bash array
|
||||
read -r -a GENESIS_VALIDATOR_ADDRESS_ARRAY <<<"$GENESIS_VALIDATOR_ADDRESSES"
|
||||
@ -103,11 +150,14 @@ read -r -a GENESIS_VALIDATOR_ADDRESS_ARRAY <<<"$GENESIS_VALIDATOR_ADDRESSES"
|
||||
# delegate 300KAVA to each validator
|
||||
for validator in "${GENESIS_VALIDATOR_ADDRESS_ARRAY[@]}"; do
|
||||
kava tx staking delegate "${validator}" 300000000ukava --from dev-wallet --gas-prices 0.5ukava -y
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
done
|
||||
|
||||
# create a text proposal
|
||||
kava tx gov submit-legacy-proposal --deposit 1000000000ukava --type "Text" --title "Example Proposal" --description "This is an example proposal" --gas auto --gas-adjustment 1.2 --from dev-wallet --gas-prices 0.01ukava -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# setup god's wallet
|
||||
echo "${KAVA_TESTNET_GOD_MNEMONIC}" | kava keys add --recover god
|
||||
|
||||
@ -123,7 +173,7 @@ PARAM_CHANGE_PROP_TEMPLATE=$(
|
||||
{
|
||||
"subspace": "evmutil",
|
||||
"key": "EnabledConversionPairs",
|
||||
"value": "[{\"kava_erc20_address\":\"MULTICHAIN_USDC_CONTRACT_ADDRESS\",\"denom\":\"erc20/multichain/usdc\"},{\"kava_erc20_address\":\"MULTICHAIN_USDT_CONTRACT_ADDRESS\",\"denom\":\"erc20/multichain/usdt\"},{\"kava_erc20_address\":\"MULTICHAIN_wBTC_CONTRACT_ADDRESS\",\"denom\":\"erc20/multichain/wbtc\"},{\"kava_erc20_address\":\"AXL_USDC_CONTRACT_ADDRESS\",\"denom\":\"erc20/axelar/usdc\"},{\"kava_erc20_address\":\"AXL_WBTC_CONTRACT_ADDRESS\",\"denom\":\"erc20/axelar/wbtc\"},{\"kava_erc20_address\":\"wETH_CONTRACT_ADDRESS\",\"denom\":\"erc20/axelar/eth\"},{\"kava_erc20_address\":\"TETHER_USDT_CONTRACT_ADDRESS\",\"denom\":\"erc20/tether/usdt\"}]"
|
||||
"value": "[{\"kava_erc20_address\":\"MULTICHAIN_USDC_CONTRACT_ADDRESS\",\"denom\":\"erc20/multichain/usdc\"},{\"kava_erc20_address\":\"MULTICHAIN_USDT_CONTRACT_ADDRESS\",\"denom\":\"erc20/multichain/usdt\"},{\"kava_erc20_address\":\"MULTICHAIN_wBTC_CONTRACT_ADDRESS\",\"denom\":\"erc20/multichain/wbtc\"},{\"kava_erc20_address\":\"AXL_USDC_CONTRACT_ADDRESS\",\"denom\":\"erc20/axelar/usdc\"},{\"kava_erc20_address\":\"AXL_WBTC_CONTRACT_ADDRESS\",\"denom\":\"erc20/axelar/wbtc\"},{\"kava_erc20_address\":\"wETH_CONTRACT_ADDRESS\",\"denom\":\"erc20/axelar/eth\"},{\"kava_erc20_address\":\"TETHER_USDT_CONTRACT_ADDRESS\",\"denom\":\"erc20/tether/usdt\"},{\"kava_erc20_address\":\"AXL_BNB_CONTRACT_ADDRESS\",\"denom\":\"bnb\"},{\"kava_erc20_address\":\"AXL_BUSD_CONTRACT_ADDRESS\",\"denom\":\"busd\"},{\"kava_erc20_address\":\"AXL_BTCB_CONTRACT_ADDRESS\",\"denom\":\"btcb\"},{\"kava_erc20_address\":\"AXL_XRPB_CONTRACT_ADDRESS\",\"denom\":\"xrpb\"},{\"kava_erc20_address\":\"WBTC_CONTRACT_ADDRESS\",\"denom\":\"erc20/bitgo/wbtc\"}]"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -140,6 +190,11 @@ finalProposal="${finalProposal/AXL_USDC_CONTRACT_ADDRESS/$AXL_USDC_CONTRACT_ADDR
|
||||
finalProposal="${finalProposal/AXL_WBTC_CONTRACT_ADDRESS/$AXL_WBTC_CONTRACT_ADDRESS}"
|
||||
finalProposal="${finalProposal/wETH_CONTRACT_ADDRESS/$wETH_CONTRACT_ADDRESS}"
|
||||
finalProposal="${finalProposal/TETHER_USDT_CONTRACT_ADDRESS/$TETHER_USDT_CONTRACT_ADDRESS}"
|
||||
finalProposal="${finalProposal/AXL_BNB_CONTRACT_ADDRESS/$AXL_BNB_CONTRACT_ADDRESS}"
|
||||
finalProposal="${finalProposal/AXL_BUSD_CONTRACT_ADDRESS/$AXL_BUSD_CONTRACT_ADDRESS}"
|
||||
finalProposal="${finalProposal/AXL_BTCB_CONTRACT_ADDRESS/$AXL_BTCB_CONTRACT_ADDRESS}"
|
||||
finalProposal="${finalProposal/AXL_XRPB_CONTRACT_ADDRESS/$AXL_XRPB_CONTRACT_ADDRESS}"
|
||||
finalProposal="${finalProposal/WBTC_CONTRACT_ADDRESS/$WBTC_CONTRACT_ADDRESS}"
|
||||
|
||||
# create unique proposal filename
|
||||
proposalFileName="$(date +%s)-proposal.json"
|
||||
@ -155,20 +210,41 @@ printf "original evm util module params\n %s" , "$originalEvmUtilParams"
|
||||
# change the params of the chain like a god - make it so 🖖🏽
|
||||
# make sure to update god committee member permissions for the module
|
||||
# and params being updated (see below for example)
|
||||
# https://github.com/Kava-Labs/kava/pull/1556/files#diff-0bd6043650c708661f37bbe6fa5b29b52149e0ec0069103c3954168fc9f12612R900-R903
|
||||
# https://github.com/0glabs/0g-chain/pull/1556/files#diff-0bd6043650c708661f37bbe6fa5b29b52149e0ec0069103c3954168fc9f12612R900-R903
|
||||
# committee 1 is the stability committee. on internal testnet, this has only one member.
|
||||
kava tx committee submit-proposal 1 "$proposalFileName" --gas 2000000 --gas-prices 0.01ukava --from god -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# vote on the proposal. this assumes no other committee proposal has ever been submitted (id=1)
|
||||
kava tx committee vote 1 yes --gas 2000000 --gas-prices 0.01ukava --from god -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# fetch current module params
|
||||
updatedEvmUtilParams=$(curl https://api.app.internal.testnet.us-east.production.kava.io/kava/evmutil/v1beta1/params)
|
||||
printf "updated evm util module params\n %s" , "$updatedEvmUtilParams"
|
||||
|
||||
# submit a kava token committee proposal
|
||||
COMMITTEE_PROP_TEMPLATE=$(
|
||||
cat <<'END_HEREDOC'
|
||||
{
|
||||
"@type": "/cosmos.gov.v1beta1.TextProposal",
|
||||
"title": "The next big thing signaling proposal.",
|
||||
"description": "The purpose of this proposal is to signal support/opposition to the next big thing"
|
||||
}
|
||||
END_HEREDOC
|
||||
)
|
||||
committeeProposalFileName="$(date +%s)-committee-proposal.json"
|
||||
echo "$COMMITTEE_PROP_TEMPLATE" >$committeeProposalFileName
|
||||
tokenCommitteeId=4
|
||||
kava tx committee submit-proposal "$tokenCommitteeId" "$committeeProposalFileName" --gas auto --gas-adjustment 1.5 --gas-prices 0.01ukava --from god -y
|
||||
|
||||
# if adding more cosmos coins -> er20s, ensure that the deployment order below remains the same.
|
||||
# convert 1 HARD to an erc20. doing this ensures the contract is deployed.
|
||||
kava tx evmutil convert-cosmos-coin-to-erc20 \
|
||||
"$DEV_TEST_WALLET_ADDRESS" \
|
||||
1000000hard \
|
||||
--from dev-wallet --gas 2000000 --gas-prices 0.001ukava -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
25
.github/scripts/seed-protonet.sh
vendored
25
.github/scripts/seed-protonet.sh
vendored
@ -1,6 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
# by sleeping 1 block in between tx's
|
||||
# we can emulate the behavior of the
|
||||
# the deprecated and now removed (as of Kava 16)
|
||||
# broadcast mode of `block` in order to
|
||||
# minimize the chance tx's fail due to an
|
||||
# account sequence number mismatch
|
||||
AVG_SECONDS_BETWEEN_BLOCKS=6.5
|
||||
|
||||
# configure kava binary to talk to the desired chain endpoint
|
||||
kava config node "${CHAIN_API_URL}"
|
||||
kava config chain-id "${CHAIN_ID}"
|
||||
@ -9,7 +17,7 @@ kava config chain-id "${CHAIN_ID}"
|
||||
kava config keyring-backend test
|
||||
|
||||
# wait for transactions to be committed per CLI command
|
||||
kava config broadcast-mode block
|
||||
kava config broadcast-mode sync
|
||||
|
||||
# setup dev wallet
|
||||
echo "${DEV_WALLET_MNEMONIC}" | kava keys add --recover dev-wallet
|
||||
@ -23,9 +31,13 @@ echo "sweet ocean blush coil mobile ten floor sample nuclear power legend where
|
||||
# fund evm-contract-deployer account (using issuance)
|
||||
kava tx issuance issue 200000000ukava kava1van3znl6597xgwwh46jgquutnqkwvwszjg04fz --from dev-wallet --gas-prices 0.5ukava -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# fund 5k kava to x/community account
|
||||
kava tx community fund-community-pool 5000000000ukava --from dev-wallet --gas-prices 0.5ukava -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# deploy and fund USDC ERC20 contract
|
||||
MULTICHAIN_USDC_CONTRACT_DEPLOY=$(npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" deploy-erc20 "USD Coin" USDC 6)
|
||||
MULTICHAIN_USDC_CONTRACT_ADDRESS=${MULTICHAIN_USDC_CONTRACT_DEPLOY: -42}
|
||||
@ -89,6 +101,8 @@ npx hardhat --network "${ERC20_DEPLOYER_NETWORK_NAME}" mint-erc20 "$AXL_USDC_CON
|
||||
kava tx issuance issue 6000000000ukava kava1vlpsrmdyuywvaqrv7rx6xga224sqfwz3fyfhwq \
|
||||
--from dev-wallet --gas-prices 0.5ukava -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# parse space seperated list of validators
|
||||
# into bash array
|
||||
read -r -a GENESIS_VALIDATOR_ADDRESS_ARRAY <<< "$GENESIS_VALIDATOR_ADDRESSES"
|
||||
@ -97,11 +111,14 @@ read -r -a GENESIS_VALIDATOR_ADDRESS_ARRAY <<< "$GENESIS_VALIDATOR_ADDRESSES"
|
||||
for validator in "${GENESIS_VALIDATOR_ADDRESS_ARRAY[@]}"
|
||||
do
|
||||
kava tx staking delegate "${validator}" 300000000ukava --from dev-wallet --gas-prices 0.5ukava -y
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
done
|
||||
|
||||
# create a text proposal
|
||||
kava tx gov submit-legacy-proposal --deposit 1000000000ukava --type "Text" --title "Example Proposal" --description "This is an example proposal" --gas auto --gas-adjustment 1.2 --from dev-wallet --gas-prices 0.01ukava -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# setup god's wallet
|
||||
echo "${KAVA_TESTNET_GOD_MNEMONIC}" | kava keys add --recover god
|
||||
|
||||
@ -147,12 +164,16 @@ printf "original evm util module params\n %s" , "$originalEvmUtilParams"
|
||||
# change the params of the chain like a god - make it so 🖖🏽
|
||||
# make sure to update god committee member permissions for the module
|
||||
# and params being updated (see below for example)
|
||||
# https://github.com/Kava-Labs/kava/pull/1556/files#diff-0bd6043650c708661f37bbe6fa5b29b52149e0ec0069103c3954168fc9f12612R900-R903
|
||||
# https://github.com/0glabs/0g-chain/pull/1556/files#diff-0bd6043650c708661f37bbe6fa5b29b52149e0ec0069103c3954168fc9f12612R900-R903
|
||||
kava tx committee submit-proposal 1 "$proposalFileName" --gas 2000000 --gas-prices 0.01ukava --from god -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# vote on the proposal. this assumes no other committee proposal has ever been submitted (id=1)
|
||||
kava tx committee vote 1 yes --gas 2000000 --gas-prices 0.01ukava --from god -y
|
||||
|
||||
sleep $AVG_SECONDS_BETWEEN_BLOCKS
|
||||
|
||||
# fetch current module params
|
||||
updatedEvmUtilParams=$(curl https://api.app.internal.testnet.us-east.production.kava.io/kava/evmutil/v1beta1/params)
|
||||
printf "updated evm util module params\n %s" , "$updatedEvmUtilParams"
|
||||
|
54
.github/workflows/cd-internal-testnet-manual.yml
vendored
54
.github/workflows/cd-internal-testnet-manual.yml
vendored
@ -1,54 +0,0 @@
|
||||
name: Manual Deployment (Internal Testnet)
|
||||
# allow to be triggered manually
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
# in order:
|
||||
# enter standby (prevents autoscaling group from killing node during deploy)
|
||||
# stop kava
|
||||
# take ebs + zfs snapshots
|
||||
# download updated binary and genesis
|
||||
# reset application database state (only done on internal testnet)
|
||||
reset-chain-to-zero-state:
|
||||
uses: ./.github/workflows/cd-reset-internal-testnet.yml
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
chain-id: kava_2221-17000
|
||||
ssm-document-name: kava-testnet-internal-node-update
|
||||
playbook-name: reset-internal-testnet-playbook.yml
|
||||
playbook-infrastructure-branch: master
|
||||
secrets: inherit
|
||||
|
||||
# start kava with new binary and genesis state on api, peer and seed nodes, place nodes in service once they start and are synched to live
|
||||
start-chain-api:
|
||||
uses: ./.github/workflows/cd-start-chain.yml
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
chain-id: kava_2221-17000
|
||||
ssm-document-name: kava-testnet-internal-node-update
|
||||
playbook-name: start-chain-api-playbook.yml
|
||||
playbook-infrastructure-branch: master
|
||||
secrets: inherit
|
||||
needs: [reset-chain-to-zero-state]
|
||||
|
||||
# setup test and development accounts and balances, deploy contracts by calling the chain's api
|
||||
seed-chain-state:
|
||||
uses: ./.github/workflows/cd-seed-chain.yml
|
||||
with:
|
||||
chain-api-url: https://rpc.app.internal.testnet.us-east.production.kava.io:443
|
||||
chain-id: kava_2221-17000
|
||||
seed-script-filename: seed-internal-testnet.sh
|
||||
erc20-deployer-network-name: internal_testnet
|
||||
genesis_validator_addresses: "kavavaloper1xcgtffvv2yeqmgs3yz4gv29kgjrj8usxrnrlwp kavavaloper1w66m9hdzwgd6uc8g93zqkcumgwzrpcw958sh3s"
|
||||
kava_version_filepath: ./ci/env/kava-internal-testnet/KAVA.VERSION
|
||||
secrets: inherit
|
||||
needs: [start-chain-api]
|
||||
post-pipeline-metrics:
|
||||
uses: ./.github/workflows/metric-pipeline.yml
|
||||
if: always() # always run so we metric failures and successes
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
metric-name: kava.deploys.testnet.internal
|
||||
namespace: Kava/ContinuousDeployment
|
||||
secrets: inherit
|
||||
needs: [seed-chain-state]
|
60
.github/workflows/cd-internal-testnet.yml
vendored
60
.github/workflows/cd-internal-testnet.yml
vendored
@ -1,60 +0,0 @@
|
||||
name: Continuous Deployment (Internal Testnet)
|
||||
# run after every successful CI job of new commits to the master branch
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Continuous Integration (Kava Master)]
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
# in order:
|
||||
# enter standby (prevents autoscaling group from killing node during deploy)
|
||||
# stop kava
|
||||
# take ebs + zfs snapshots
|
||||
# download updated binary and genesis
|
||||
# reset application database state (only done on internal testnet)
|
||||
reset-chain-to-zero-state:
|
||||
# only start cd pipeline if last ci run was successful
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
uses: ./.github/workflows/cd-reset-internal-testnet.yml
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
chain-id: kava_2221-17000
|
||||
ssm-document-name: kava-testnet-internal-node-update
|
||||
playbook-name: reset-internal-testnet-playbook.yml
|
||||
playbook-infrastructure-branch: master
|
||||
secrets: inherit
|
||||
|
||||
# start kava with new binary and genesis state on api, peer and seed nodes, place nodes in service once they start and are synched to live
|
||||
start-chain-api:
|
||||
uses: ./.github/workflows/cd-start-chain.yml
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
chain-id: kava_2221-17000
|
||||
ssm-document-name: kava-testnet-internal-node-update
|
||||
playbook-name: start-chain-api-playbook.yml
|
||||
playbook-infrastructure-branch: master
|
||||
secrets: inherit
|
||||
needs: [reset-chain-to-zero-state]
|
||||
|
||||
# setup test and development accounts and balances, deploy contracts by calling the chain's api
|
||||
seed-chain-state:
|
||||
uses: ./.github/workflows/cd-seed-chain.yml
|
||||
with:
|
||||
chain-api-url: https://rpc.app.internal.testnet.us-east.production.kava.io:443
|
||||
chain-id: kava_2221-17000
|
||||
seed-script-filename: seed-internal-testnet.sh
|
||||
erc20-deployer-network-name: internal_testnet
|
||||
genesis_validator_addresses: "kavavaloper1xcgtffvv2yeqmgs3yz4gv29kgjrj8usxrnrlwp kavavaloper1w66m9hdzwgd6uc8g93zqkcumgwzrpcw958sh3s"
|
||||
kava_version_filepath: ./ci/env/kava-internal-testnet/KAVA.VERSION
|
||||
secrets: inherit
|
||||
needs: [start-chain-api]
|
||||
post-pipeline-metrics:
|
||||
uses: ./.github/workflows/metric-pipeline.yml
|
||||
if: always() # always run so we metric failures and successes
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
metric-name: kava.deploys.testnet.internal
|
||||
namespace: Kava/ContinuousDeployment
|
||||
secrets: inherit
|
||||
needs: [seed-chain-state]
|
60
.github/workflows/cd-protonet.yml
vendored
60
.github/workflows/cd-protonet.yml
vendored
@ -1,60 +0,0 @@
|
||||
name: Continuous Deployment (Protonet)
|
||||
# run after every successful CI job of new commits to the master branch
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Continuous Integration (Kava Master)]
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
# in order:
|
||||
# enter standby (prevents autoscaling group from killing node during deploy)
|
||||
# stop kava
|
||||
# take ebs + zfs snapshots
|
||||
# download updated binary and genesis
|
||||
# reset application database state (only done on internal testnet)
|
||||
reset-chain-to-zero-state:
|
||||
# only start cd pipeline if last ci run was successful
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
uses: ./.github/workflows/cd-reset-internal-testnet.yml
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
chain-id: proto_2221-17000
|
||||
ssm-document-name: kava-testnet-internal-node-update
|
||||
playbook-name: reset-protonet-playbook.yml
|
||||
playbook-infrastructure-branch: master
|
||||
secrets: inherit
|
||||
|
||||
# start kava with new binary and genesis state on api, peer and seed nodes, place nodes in service once they start and are synched to live
|
||||
start-chain-api:
|
||||
uses: ./.github/workflows/cd-start-chain.yml
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
chain-id: proto_2221-17000
|
||||
ssm-document-name: kava-testnet-internal-node-update
|
||||
playbook-name: start-chain-api-playbook.yml
|
||||
playbook-infrastructure-branch: master
|
||||
secrets: inherit
|
||||
needs: [reset-chain-to-zero-state]
|
||||
|
||||
# setup test and development accounts and balances, deploy contracts by calling the chain's api
|
||||
seed-chain-state:
|
||||
uses: ./.github/workflows/cd-seed-chain.yml
|
||||
with:
|
||||
chain-api-url: https://rpc.app.protonet.us-east.production.kava.io:443
|
||||
chain-id: proto_2221-17000
|
||||
seed-script-filename: seed-protonet.sh
|
||||
erc20-deployer-network-name: protonet
|
||||
genesis_validator_addresses: "kavavaloper14w4avgdvqrlpww6l5dhgj4egfn6ln7gmtp7r2m"
|
||||
kava_version_filepath: ./ci/env/kava-protonet/KAVA.VERSION
|
||||
secrets: inherit
|
||||
needs: [start-chain-api]
|
||||
post-pipeline-metrics:
|
||||
uses: ./.github/workflows/metric-pipeline.yml
|
||||
if: always() # always run so we metric failures and successes
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
metric-name: kava.deploys.testnet.proto
|
||||
namespace: Kava/ContinuousDeployment
|
||||
secrets: inherit
|
||||
needs: [seed-chain-state]
|
82
.github/workflows/cd-reset-internal-testnet.yml
vendored
82
.github/workflows/cd-reset-internal-testnet.yml
vendored
@ -1,82 +0,0 @@
|
||||
name: Reset Internal Testnet
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
chain-id:
|
||||
required: true
|
||||
type: string
|
||||
aws-region:
|
||||
required: true
|
||||
type: string
|
||||
ssm-document-name:
|
||||
required: true
|
||||
type: string
|
||||
playbook-name:
|
||||
required: true
|
||||
type: string
|
||||
playbook-infrastructure-branch:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
CI_AWS_KEY_ID:
|
||||
required: true
|
||||
CI_AWS_KEY_SECRET:
|
||||
required: true
|
||||
KAVA_PRIVATE_GITHUB_ACCESS_TOKEN:
|
||||
required: true
|
||||
|
||||
# in order:
|
||||
# enter standby (prevents autoscaling group from killing node during deploy)
|
||||
# stop kava
|
||||
# download updated binary and genesis
|
||||
# reset application database state (only done on internal testnet)
|
||||
jobs:
|
||||
place-chain-nodes-on-standby:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo from current commit
|
||||
uses: actions/checkout@v3
|
||||
- name: take the chain offline
|
||||
run: bash ${GITHUB_WORKSPACE}/.github/scripts/put-all-chain-nodes-on-standby.sh
|
||||
env:
|
||||
CHAIN_ID: ${{ inputs.chain-id }}
|
||||
AWS_REGION: ${{ inputs.aws-region }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CI_AWS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_AWS_KEY_SECRET }}
|
||||
- name: checkout infrastructure repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Kava-Labs/infrastructure
|
||||
token: ${{ secrets.KAVA_PRIVATE_GITHUB_ACCESS_TOKEN }}
|
||||
path: infrastructure
|
||||
ref: master
|
||||
- name: set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: build kava node updater
|
||||
run: cd infrastructure/cli/kava-node-updater && make install && cd ../../../
|
||||
- name: run reset playbook on all chain nodes
|
||||
run: |
|
||||
kava-node-updater \
|
||||
--debug \
|
||||
--max-retries=2 \
|
||||
--aws-ssm-document-name=$SSM_DOCUMENT_NAME \
|
||||
--infrastructure-git-pointer=$PLAYBOOK_INFRASTRUCTURE_BRANCH \
|
||||
--update-playbook-filename=$PLAYBOOK_NAME \
|
||||
--chain-id=$CHAIN_ID \
|
||||
--max-upgrade-batch-size=0 \
|
||||
--node-states=Standby \
|
||||
--wait-for-node-sync-after-upgrade=false
|
||||
env:
|
||||
SSM_DOCUMENT_NAME: ${{ inputs.ssm-document-name }}
|
||||
PLAYBOOK_NAME: ${{ inputs.playbook-name }}
|
||||
CHAIN_ID: ${{ inputs.chain-id }}
|
||||
AWS_REGION: ${{ inputs.aws-region }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CI_AWS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_AWS_KEY_SECRET }}
|
||||
AWS_SDK_LOAD_CONFIG: 1
|
||||
PLAYBOOK_INFRASTRUCTURE_BRANCH: ${{ inputs.playbook-infrastructure-branch }}
|
96
.github/workflows/cd-seed-chain.yml
vendored
96
.github/workflows/cd-seed-chain.yml
vendored
@ -1,96 +0,0 @@
|
||||
name: Seed Chain
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
chain-api-url:
|
||||
required: true
|
||||
type: string
|
||||
chain-id:
|
||||
required: true
|
||||
type: string
|
||||
seed-script-filename:
|
||||
required: true
|
||||
type: string
|
||||
erc20-deployer-network-name:
|
||||
required: true
|
||||
type: string
|
||||
genesis_validator_addresses:
|
||||
required: true
|
||||
type: string
|
||||
kava_version_filepath:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
DEV_WALLET_MNEMONIC:
|
||||
required: true
|
||||
KAVA_TESTNET_GOD_MNEMONIC:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
seed-chain-state:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo from master
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: master
|
||||
- name: checkout version of kava used by network
|
||||
run: |
|
||||
git pull -p
|
||||
git checkout $(cat ${KAVA_VERSION_FILEPATH})
|
||||
env:
|
||||
KAVA_VERSION_FILEPATH: ${{ inputs.kava_version_filepath }}
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: build kava binary
|
||||
run: make install
|
||||
- name: checkout go evm tools repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: ethereum/go-ethereum
|
||||
path: go-ethereum
|
||||
ref: v1.10.26
|
||||
- name: install go evm tools
|
||||
run: |
|
||||
make
|
||||
make devtools
|
||||
working-directory: go-ethereum
|
||||
- name: checkout kava bridge repo for deploying evm contracts
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Kava-Labs/kava-bridge
|
||||
path: kava-bridge
|
||||
ref: main
|
||||
- name: install nodeJS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: npm
|
||||
node-version: 18
|
||||
cache-dependency-path: kava-bridge/contract/package.json
|
||||
- name: "install ERC20 contract deployment dependencies"
|
||||
run: "npm install"
|
||||
working-directory: kava-bridge/contract
|
||||
- name: compile default erc20 contracts
|
||||
run: make compile-contracts
|
||||
working-directory: kava-bridge
|
||||
- name: download seed script from master
|
||||
run: wget https://raw.githubusercontent.com/Kava-Labs/kava/master/.github/scripts/${SEED_SCRIPT_FILENAME} && chmod +x ${SEED_SCRIPT_FILENAME}
|
||||
working-directory: kava-bridge/contract
|
||||
env:
|
||||
SEED_SCRIPT_FILENAME: ${{ inputs.seed-script-filename }}
|
||||
- name: run seed scripts
|
||||
run: bash ./${SEED_SCRIPT_FILENAME}
|
||||
working-directory: kava-bridge/contract
|
||||
env:
|
||||
CHAIN_API_URL: ${{ inputs.chain-api-url }}
|
||||
CHAIN_ID: ${{ inputs.chain-id }}
|
||||
DEV_WALLET_MNEMONIC: ${{ secrets.DEV_WALLET_MNEMONIC }}
|
||||
KAVA_TESTNET_GOD_MNEMONIC: ${{ secrets.KAVA_TESTNET_GOD_MNEMONIC }}
|
||||
SEED_SCRIPT_FILENAME: ${{ inputs.seed-script-filename }}
|
||||
ERC20_DEPLOYER_NETWORK_NAME: ${{ inputs.erc20-deployer-network-name }}
|
||||
GENESIS_VALIDATOR_ADDRESSES: ${{ inputs.genesis_validator_addresses }}
|
80
.github/workflows/cd-start-chain.yml
vendored
80
.github/workflows/cd-start-chain.yml
vendored
@ -1,80 +0,0 @@
|
||||
name: Start Chain
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
chain-id:
|
||||
required: true
|
||||
type: string
|
||||
aws-region:
|
||||
required: true
|
||||
type: string
|
||||
ssm-document-name:
|
||||
required: true
|
||||
type: string
|
||||
playbook-name:
|
||||
required: true
|
||||
type: string
|
||||
playbook-infrastructure-branch:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
CI_AWS_KEY_ID:
|
||||
required: true
|
||||
CI_AWS_KEY_SECRET:
|
||||
required: true
|
||||
KAVA_PRIVATE_GITHUB_ACCESS_TOKEN:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
# start kava, allow nodes to start processing requests from users once they are synced to live
|
||||
serve-traffic:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo from current commit
|
||||
uses: actions/checkout@v3
|
||||
- name: take the chain offline
|
||||
run: bash ${GITHUB_WORKSPACE}/.github/scripts/put-all-chain-nodes-on-standby.sh
|
||||
env:
|
||||
CHAIN_ID: ${{ inputs.chain-id }}
|
||||
AWS_REGION: ${{ inputs.aws-region }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CI_AWS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_AWS_KEY_SECRET }}
|
||||
- name: checkout infrastructure repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Kava-Labs/infrastructure
|
||||
token: ${{ secrets.KAVA_PRIVATE_GITHUB_ACCESS_TOKEN }}
|
||||
path: infrastructure
|
||||
ref: master
|
||||
- name: set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: build kava node updater
|
||||
run: cd infrastructure/cli/kava-node-updater && make install && cd ../../../
|
||||
- name: run start-chain playbook on all chain nodes
|
||||
run: |
|
||||
kava-node-updater \
|
||||
--debug \
|
||||
--max-retries=2 \
|
||||
--aws-ssm-document-name=$SSM_DOCUMENT_NAME \
|
||||
--infrastructure-git-pointer=$PLAYBOOK_INFRASTRUCTURE_BRANCH \
|
||||
--update-playbook-filename=$PLAYBOOK_NAME \
|
||||
--chain-id=$CHAIN_ID \
|
||||
--max-upgrade-batch-size=0 \
|
||||
--node-states=Standby \
|
||||
--wait-for-node-sync-after-upgrade=true
|
||||
env:
|
||||
SSM_DOCUMENT_NAME: ${{ inputs.ssm-document-name }}
|
||||
PLAYBOOK_NAME: ${{ inputs.playbook-name }}
|
||||
CHAIN_ID: ${{ inputs.chain-id }}
|
||||
AWS_REGION: ${{ inputs.aws-region }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CI_AWS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_AWS_KEY_SECRET }}
|
||||
AWS_SDK_LOAD_CONFIG: 1
|
||||
PLAYBOOK_INFRASTRUCTURE_BRANCH: ${{ inputs.playbook-infrastructure-branch }}
|
||||
- name: bring the chain online
|
||||
run: bash ${GITHUB_WORKSPACE}/.github/scripts/exit-standby-all-chain-nodes.sh
|
7
.github/workflows/ci-commit.yml
vendored
7
.github/workflows/ci-commit.yml
vendored
@ -1,7 +0,0 @@
|
||||
name: Continuous Integration (Commit)
|
||||
on:
|
||||
push:
|
||||
# run per commit ci checks against this commit
|
||||
jobs:
|
||||
lint:
|
||||
uses: ./.github/workflows/ci-lint.yml
|
81
.github/workflows/ci-default.yml
vendored
81
.github/workflows/ci-default.yml
vendored
@ -1,81 +0,0 @@
|
||||
name: Continuous Integration (Default Checks)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo from current commit
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: build application
|
||||
run: make build
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo from current commit
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: run unit tests
|
||||
run: make test
|
||||
- name: run e2e tests
|
||||
run: make docker-build test-e2e
|
||||
validate-internal-testnet-genesis:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo from current commit
|
||||
uses: actions/checkout@v3
|
||||
- name: save version of kava that will be deployed if this pr is merged
|
||||
id: kava-version
|
||||
run: |
|
||||
echo "KAVA_VERSION=$(cat ./ci/env/kava-internal-testnet/KAVA.VERSION)" >> $GITHUB_OUTPUT
|
||||
- name: checkout repo from master
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: master
|
||||
- name: checkout version of kava that will be deployed if this pr is merged
|
||||
run: |
|
||||
git pull -p
|
||||
git checkout $KAVA_VERSION
|
||||
env:
|
||||
KAVA_VERSION: ${{ steps.kava-version.outputs.KAVA_VERSION }}
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: build kava cli
|
||||
run: make install
|
||||
- name: checkout repo from current commit to validate current branch's genesis
|
||||
uses: actions/checkout@v3
|
||||
- name: validate testnet genesis
|
||||
run: kava validate-genesis ci/env/kava-internal-testnet/genesis.json
|
||||
validate-protonet-genesis:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo from current commit
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: build kava cli
|
||||
run: make install
|
||||
- name: validate protonet genesis
|
||||
run: kava validate-genesis ci/env/kava-protonet/genesis.json
|
47
.github/workflows/ci-docker.yml
vendored
47
.github/workflows/ci-docker.yml
vendored
@ -1,47 +0,0 @@
|
||||
name: Build & Publish Docker Images
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
dockerhub-username:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
CI_DOCKERHUB_TOKEN:
|
||||
required: true
|
||||
|
||||
# runs in ci-master after successful checks
|
||||
# you can use images built by this action in future jobs.
|
||||
# https://docs.docker.com/build/ci/github-actions/examples/#share-built-image-between-jobs
|
||||
jobs:
|
||||
docker:
|
||||
# https://github.com/marketplace/actions/build-and-push-docker-images
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# ensure working with latest code
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
# generate a git commit hash to be used as image tag
|
||||
- name: Generate short hash
|
||||
id: commit-hash
|
||||
run: echo "short=$( git rev-parse --short $GITHUB_SHA )" >> $GITHUB_OUTPUT
|
||||
# qemu is used to emulate different platform architectures
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
# cross-platform build of the image
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
# authenticate for publish to docker hub
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ inputs.dockerhub-username }}
|
||||
password: ${{ secrets.CI_DOCKERHUB_TOKEN }}
|
||||
# publish to docker hub, tag with short git hash
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: kava/kava:${{ steps.commit-hash.outputs.short }},kava/kava:master
|
17
.github/workflows/ci-lint.yml
vendored
17
.github/workflows/ci-lint.yml
vendored
@ -1,17 +0,0 @@
|
||||
name: Lint Checks
|
||||
on:
|
||||
workflow_call:
|
||||
# run per commit ci checks against this commit
|
||||
jobs:
|
||||
proto-lint:
|
||||
uses: ./.github/workflows/proto.yml
|
||||
golangci-lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: golangci-lint
|
||||
uses: reviewdog/action-golangci-lint@v2
|
||||
with:
|
||||
github_token: ${{ secrets.github_token }}
|
||||
reporter: github-pr-review
|
||||
golangci_lint_flags: --timeout 10m
|
57
.github/workflows/ci-master.yml
vendored
57
.github/workflows/ci-master.yml
vendored
@ -1,57 +0,0 @@
|
||||
name: Continuous Integration (Kava Master)
|
||||
on:
|
||||
push:
|
||||
# run CI on any push to the master branch
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
# run per commit ci checks against master branch
|
||||
lint-checks:
|
||||
uses: ./.github/workflows/ci-lint.yml
|
||||
# run default ci checks against master branch
|
||||
default-checks:
|
||||
uses: ./.github/workflows/ci-default.yml
|
||||
# build and upload versions of kava for use on internal infrastructure
|
||||
# configurations for databases, cpu architectures and operating systems
|
||||
publish-internal:
|
||||
# only run if all checks pass
|
||||
needs: [lint-checks, default-checks]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo from current commit
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: set build tag
|
||||
run: echo "BUILD_TAG=$(date +%s)-$(git rev-parse HEAD | cut -c 1-8)" >> $GITHUB_ENV
|
||||
- name: build rocksdb dependency
|
||||
run: bash ${GITHUB_WORKSPACE}/.github/scripts/install-rocksdb.sh
|
||||
env:
|
||||
ROCKSDB_VERSION: v8.1.1
|
||||
- name: Build and upload release artifacts
|
||||
run: bash ${GITHUB_WORKSPACE}/.github/scripts/publish-internal-release-artifacts.sh
|
||||
env:
|
||||
BUILD_TAG: ${{ env.BUILD_TAG }}
|
||||
AWS_REGION: us-east-1
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CI_AWS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_AWS_KEY_SECRET }}
|
||||
docker:
|
||||
# only run if all checks pass
|
||||
needs: [lint-checks, default-checks]
|
||||
uses: ./.github/workflows/ci-docker.yml
|
||||
with:
|
||||
dockerhub-username: kavaops
|
||||
secrets: inherit
|
||||
post-pipeline-metrics:
|
||||
uses: ./.github/workflows/metric-pipeline.yml
|
||||
if: always() # always run so we metric failures and successes
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
metric-name: kava.releases.merge
|
||||
namespace: Kava/ContinuousIntegration
|
||||
secrets: inherit
|
||||
needs: [publish-internal]
|
23
.github/workflows/ci-pr.yml
vendored
23
.github/workflows/ci-pr.yml
vendored
@ -1,23 +0,0 @@
|
||||
name: Continuous Integration (PR)
|
||||
on:
|
||||
pull_request:
|
||||
# run CI on pull requests to master or a release branch
|
||||
branches:
|
||||
- master
|
||||
- 'release/**'
|
||||
- 'releases/**'
|
||||
# run default ci checks against current PR
|
||||
jobs:
|
||||
default:
|
||||
uses: ./.github/workflows/ci-default.yml
|
||||
rocksdb:
|
||||
uses: ./.github/workflows/ci-rocksdb-build.yml
|
||||
post-pipeline-metrics:
|
||||
uses: ./.github/workflows/metric-pipeline.yml
|
||||
if: always() # always run so we metric failures and successes
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
metric-name: kava.releases.pr
|
||||
namespace: Kava/ContinuousIntegration
|
||||
secrets: inherit
|
||||
needs: [default]
|
47
.github/workflows/ci-rocksdb-build.yml
vendored
47
.github/workflows/ci-rocksdb-build.yml
vendored
@ -1,47 +0,0 @@
|
||||
name: Continuous Integration (Rocksdb Build)
|
||||
|
||||
env:
|
||||
ROCKSDB_VERSION: v8.1.1
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo from current commit
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: build rocksdb dependency
|
||||
run: bash ${GITHUB_WORKSPACE}/.github/scripts/install-rocksdb.sh
|
||||
- name: build application
|
||||
run: make build COSMOS_BUILD_OPTIONS=rocksdb
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: install RocksDB dependencies
|
||||
run: sudo apt-get update
|
||||
&& sudo apt-get install -y git make gcc libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev
|
||||
- name: install RocksDB as shared library
|
||||
run: git clone https://github.com/facebook/rocksdb.git
|
||||
&& cd rocksdb
|
||||
&& git checkout $ROCKSDB_VERSION
|
||||
&& sudo make -j$(nproc) install-shared
|
||||
&& sudo ldconfig
|
||||
- name: checkout repo from current commit
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.20"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: run unit tests
|
||||
run: make test-rocksdb
|
45
.github/workflows/metric-pipeline.yml
vendored
45
.github/workflows/metric-pipeline.yml
vendored
@ -1,45 +0,0 @@
|
||||
name: Metric Pipeline
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
aws-region:
|
||||
required: true
|
||||
type: string
|
||||
metric-name:
|
||||
required: true
|
||||
type: string
|
||||
namespace:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
CI_AWS_KEY_ID:
|
||||
required: true
|
||||
CI_AWS_KEY_SECRET:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
metric-pipeline-result:
|
||||
runs-on: ubuntu-latest
|
||||
if: always() # always run to capture workflow success or failure
|
||||
steps:
|
||||
# Make sure the secrets are stored in you repo settings
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.CI_AWS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.CI_AWS_KEY_SECRET }}
|
||||
aws-region: ${{ inputs.aws-region }}
|
||||
- name: Calculate Pipleline Success
|
||||
# run this action to get the workflow conclusion
|
||||
# You can get the conclusion via env (env.WORKFLOW_CONCLUSION)
|
||||
# values: neutral, success, skipped, cancelled, timed_out,
|
||||
# action_required, failure
|
||||
uses: technote-space/workflow-conclusion-action@v3
|
||||
- name: Metric Pipleline Success
|
||||
# replace TAG by the latest tag in the repository
|
||||
uses: ros-tooling/action-cloudwatch-metrics@0.0.5
|
||||
with:
|
||||
metric-value: ${{ env.WORKFLOW_CONCLUSION == 'success' }}
|
||||
metric-name: ${{ inputs.metric-name }}
|
||||
namespace: ${{ inputs.namespace }}
|
26
.github/workflows/proto.yml
vendored
26
.github/workflows/proto.yml
vendored
@ -1,26 +0,0 @@
|
||||
name: Protobuf Checks
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
check-proto:
|
||||
name: "Check Proto"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache: true
|
||||
- run: go mod download
|
||||
- run: make install-build-deps
|
||||
- run: make check-proto-deps
|
||||
- run: make check-proto-lint
|
||||
- run: make check-proto-format
|
||||
- run: make check-proto-breaking-remote
|
||||
- run: BUF_CHECK_BREAKING_AGAINST_REMOTE="branch=$GITHUB_BASE_REF" make check-proto-breaking-remote
|
||||
if: github.event_name == 'pull_request'
|
||||
- run: make check-proto-gen
|
||||
- run: make check-proto-gen-doc
|
||||
- run: make check-proto-gen-swagger
|
25
.github/workflows/upload-release-assets.yml
vendored
Normal file
25
.github/workflows/upload-release-assets.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
name: Upload Release Assets
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.21'
|
||||
- name: Build
|
||||
run: sudo LINK_STATICALLY=true make build-release
|
||||
- name: Rename file
|
||||
run: sudo mv ./out/linux/0gchaind ./out/linux/0gchaind-linux-${{ github.ref_name }}
|
||||
- name: Upload Release Asset
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: ./out/linux/0gchaind-linux-${{ github.ref_name }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ZG_UPLOAD_ASSET }}
|
13
.gitignore
vendored
13
.gitignore
vendored
@ -31,6 +31,9 @@ out
|
||||
# Ignore build cache dir
|
||||
build/.cache
|
||||
|
||||
# Ignore make lint cache
|
||||
build/.golangci-lint
|
||||
|
||||
# Ignore installed binaires
|
||||
build/bin
|
||||
|
||||
@ -41,3 +44,13 @@ build/linux
|
||||
# Go workspace files
|
||||
go.work
|
||||
go.work.sum
|
||||
.build/0gchaind
|
||||
.build/da
|
||||
|
||||
# runtime
|
||||
run
|
||||
|
||||
# contracts
|
||||
precompiles/interfaces/build
|
||||
precompiles/interfaces/node_modules
|
||||
precompiles/interfaces/abis
|
1
.golangci-version
Normal file
1
.golangci-version
Normal file
@ -0,0 +1 @@
|
||||
v1.59
|
130
.golangci.yml
Normal file
130
.golangci.yml
Normal file
@ -0,0 +1,130 @@
|
||||
run:
|
||||
timeout: 20m # set maximum time allowed for the linter to run. If the linting process exceeds this duration, it will be terminated
|
||||
modules-download-mode: readonly # Ensures that modules are not modified during the linting process
|
||||
allow-parallel-runners: true # enables parallel execution of linters to speed up linting process
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- asasalint
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- bodyclose
|
||||
- containedctx
|
||||
- contextcheck
|
||||
- decorder
|
||||
- dogsled
|
||||
# - dupl
|
||||
# - dupword
|
||||
- durationcheck
|
||||
- errcheck
|
||||
- errchkjson
|
||||
- errname
|
||||
- errorlint
|
||||
# - exhaustive
|
||||
- exportloopref
|
||||
- funlen
|
||||
- gci
|
||||
- ginkgolinter
|
||||
- gocheckcompilerdirectives
|
||||
# - gochecknoglobals
|
||||
# - gochecknoinits
|
||||
- goconst
|
||||
- gocritic
|
||||
- godox
|
||||
- gofmt
|
||||
# - gofumpt
|
||||
- goheader
|
||||
- goimports
|
||||
- mnd
|
||||
# - gomodguard
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- grouper
|
||||
- importas
|
||||
- ineffassign
|
||||
# - interfacebloat
|
||||
- lll
|
||||
- loggercheck
|
||||
- makezero
|
||||
- mirror
|
||||
- misspell
|
||||
- musttag
|
||||
# - nakedret
|
||||
# - nestif
|
||||
- nilerr
|
||||
# - nilnil
|
||||
# - noctx
|
||||
- nolintlint
|
||||
# - nonamedreturns
|
||||
- nosprintfhostport
|
||||
- prealloc
|
||||
- predeclared
|
||||
- promlinter
|
||||
# - reassign
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- staticcheck
|
||||
# - stylecheck
|
||||
- tagalign
|
||||
# - testpackage
|
||||
# - thelper
|
||||
# - tparallel
|
||||
- typecheck
|
||||
# - unconvert
|
||||
- unparam
|
||||
- unused
|
||||
# - usestdlibvars
|
||||
- wastedassign
|
||||
# - whitespace
|
||||
- wrapcheck
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
# Disable funlen for "func Test..." or func (suite *Suite) Test..." type functions
|
||||
# These functions tend to be descriptive and exceed length limits.
|
||||
- source: "^func (\\(.*\\) )?Test"
|
||||
linters:
|
||||
- funlen
|
||||
|
||||
linters-settings:
|
||||
errcheck:
|
||||
check-blank: true # check for assignments to the blank identifier '_' when errors are returned
|
||||
check-type-assertions: false # check type assertion
|
||||
errorlint:
|
||||
check-generated: false # disabled linting of generated files
|
||||
default-signifies-exhaustive: false # exhaustive handling of error types
|
||||
exhaustive:
|
||||
default-signifies-exhaustive: false # exhaustive handling of error types
|
||||
gci:
|
||||
sections: # defines the order of import sections
|
||||
- standard
|
||||
- default
|
||||
- localmodule
|
||||
goconst:
|
||||
min-len: 3 # min length for string constants to be checked
|
||||
min-occurrences: 3 # min occurrences of the same constant before it's flagged
|
||||
godox:
|
||||
keywords: # specific keywords to flag for further action
|
||||
- BUG
|
||||
- FIXME
|
||||
- HACK
|
||||
gosec:
|
||||
exclude-generated: true
|
||||
lll:
|
||||
line-length: 120
|
||||
misspell:
|
||||
locale: US
|
||||
ignore-words: expect
|
||||
nolintlint:
|
||||
allow-leading-space: false
|
||||
require-explanation: true
|
||||
require-specific: true
|
||||
prealloc:
|
||||
simple: true # enables simple preallocation checks
|
||||
range-loops: true # enabled preallocation checks in range loops
|
||||
for-loops: false # disables preallocation checks in for loops
|
||||
unparam:
|
||||
check-exported: true # checks exported functions and methods for unused params
|
16
.mockery.yaml
Normal file
16
.mockery.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
# Generate EXPECT() methods, type-safe methods to generate call expectations
|
||||
with-expecter: true
|
||||
|
||||
# Generate mocks in adjacent mocks directory to the interfaces
|
||||
dir: "{{.InterfaceDir}}/mocks"
|
||||
mockname: "Mock{{.InterfaceName}}"
|
||||
outpkg: "mocks"
|
||||
filename: "Mock{{.InterfaceName}}.go"
|
||||
|
||||
packages:
|
||||
github.com/0glabs/0g-chain/x/precisebank/types:
|
||||
# package-specific config
|
||||
config:
|
||||
interfaces:
|
||||
AccountKeeper:
|
||||
BankKeeper:
|
@ -1,2 +1,2 @@
|
||||
golang 1.20
|
||||
nodejs 18.16.0
|
||||
golang 1.21.9
|
||||
nodejs 20.16.0
|
||||
|
61
CHANGELOG.md
61
CHANGELOG.md
@ -36,15 +36,43 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v0.26.0]
|
||||
|
||||
### Features
|
||||
- (precisebank) [#1906] Add new `x/precisebank` module with bank decimal extension for EVM usage.
|
||||
- (cli) [#1922] Add `iavlviewer` CLI command for low-level iavl db debugging.
|
||||
|
||||
### Improvements
|
||||
- (rocksdb) [#1903] Bump cometbft-db dependency for use with rocksdb v8.10.0
|
||||
- (deps) [#1988] Bump cometbft to v0.37.9-kava.1
|
||||
|
||||
## [v0.26.0]
|
||||
|
||||
### Features
|
||||
|
||||
- (cli) [#1785] Add `shard` CLI command to support creating partitions of data for standalone nodes
|
||||
- (cdp) [#1818] Add module param and logic for running x/cdp begin blocker every `n` blocks
|
||||
- (cli) [#1804] Add `rocksdb compact` command for manual DB compaction of state or blockstore
|
||||
- (cosmos-sdk) [#1811] [#1846] Upgrades app to cosmos-sdk v0.47.10 with iavl v1 support
|
||||
- (validator-vesting) [#1832] Add grpc query service to replace removed legacy querier
|
||||
- (incentive) [#1836] Update x/incentive cli to use grpc query client
|
||||
- (ibc) [#1839] Add ibc packet forward middleware for ibc transfers
|
||||
- (evmutil) [#1848] Update evm native conversion logic to handle bep3 assets
|
||||
|
||||
## [v0.25.0]
|
||||
|
||||
### Features
|
||||
|
||||
- (community) [#1704] Add module params
|
||||
- (community) [#1706] Add disable inflation upgrade
|
||||
- (community) [#1745] Enable params update via governance with `MsgUpdateParams`
|
||||
- (client) [#1784] Add Kava gRPC client
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- (ethermint) [#1788] Fixes issue where tracing a transaction could show it's status as successful when isolated in simulation even if the tx when executed on the chain failed due to an error such as exhausting the block gas meter
|
||||
- (evmutil) [#1655] Initialize x/evmutil module account in InitGenesis
|
||||
cosmos ledger app 2.34.12
|
||||
|
||||
## State Machine Breaking
|
||||
|
||||
@ -56,9 +84,19 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
- (community) [#1755] Keep funds in `x/community` in `CommunityPoolLendWithdrawProposal` handler
|
||||
- (staking) [#1761] Set validator minimum commission to 5% for all validators under 5%
|
||||
|
||||
## [v0.24.1](https://github.com/Kava-Labs/kava/releases/tag/v0.24.1)
|
||||
## [v0.24.3]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- (deps) [#1770] Bump ledger-cosmos-go to v0.13.1 to resolve signing error with
|
||||
- (rocksdb) [#1767] Fix resolution of rocksdb database path introduced in v0.24.2
|
||||
|
||||
**Note**: There was a bug released as v0.24.2. The tag has been removed and the commit should not be used.
|
||||
|
||||
## [v0.24.1]
|
||||
|
||||
### Features
|
||||
|
||||
- (metrics) [#1668] Adds non-state breaking x/metrics module for custom telemetry.
|
||||
- (metrics) [#1669] Add performance timing metrics to all Begin/EndBlockers
|
||||
- (community) [#1751] Add `AnnualizedRewards` query endpoint
|
||||
@ -302,6 +340,20 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md).
|
||||
- [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run
|
||||
large-scale simulations remotely using aws-batch
|
||||
|
||||
[#1988]: https://github.com/Kava-Labs/kava/pull/1988
|
||||
[#1922]: https://github.com/Kava-Labs/kava/pull/1922
|
||||
[#1906]: https://github.com/Kava-Labs/kava/pull/1906
|
||||
[#1903]: https://github.com/Kava-Labs/kava/pull/1903
|
||||
[#1846]: https://github.com/Kava-Labs/kava/pull/1846
|
||||
[#1848]: https://github.com/Kava-Labs/kava/pull/1848
|
||||
[#1839]: https://github.com/Kava-Labs/kava/pull/1839
|
||||
[#1836]: https://github.com/Kava-Labs/kava/pull/1836
|
||||
[#1832]: https://github.com/Kava-Labs/kava/pull/1832
|
||||
[#1811]: https://github.com/Kava-Labs/kava/pull/1811
|
||||
[#1804]: https://github.com/Kava-Labs/kava/pull/1804
|
||||
[#1785]: https://github.com/Kava-Labs/kava/pull/1785
|
||||
[#1784]: https://github.com/Kava-Labs/kava/pull/1784
|
||||
[#1770]: https://github.com/Kava-Labs/kava/pull/1770
|
||||
[#1755]: https://github.com/Kava-Labs/kava/pull/1755
|
||||
[#1761]: https://github.com/Kava-Labs/kava/pull/1761
|
||||
[#1752]: https://github.com/Kava-Labs/kava/pull/1752
|
||||
@ -354,10 +406,13 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md).
|
||||
[#750]: https://github.com/Kava-Labs/kava/pull/750
|
||||
[#751]: https://github.com/Kava-Labs/kava/pull/751
|
||||
[#780]: https://github.com/Kava-Labs/kava/pull/780
|
||||
[unreleased]: https://github.com/Kava-Labs/kava/compare/v0.24.0...HEAD
|
||||
[unreleased]: https://github.com/Kava-Labs/kava/compare/v0.26.0...HEAD
|
||||
[v0.26.0]: https://github.com/Kava-Labs/kava/compare/v0.25.0...v0.26.0
|
||||
[v0.25.0]: https://github.com/Kava-Labs/kava/compare/v0.24.3...v0.25.0
|
||||
[v0.24.3]: https://github.com/Kava-Labs/kava/compare/v0.24.3...v0.24.1
|
||||
[v0.24.1]: https://github.com/Kava-Labs/kava/compare/v0.24.1...v0.24.0
|
||||
[v0.24.0]: https://github.com/Kava-Labs/kava/compare/v0.24.0...v0.23.2
|
||||
[v0.23.2]: https://github.com/Kava-Labs/kava/compare/v0.23.1...v0.23.2
|
||||
[v0.23.1]: https://github.com/Kava-Labs/kava/compare/v0.23.0...v0.23.1
|
||||
[v0.23.0]: https://github.com/Kava-Labs/kava/compare/v0.21.1...v0.23.0
|
||||
[v0.16.1]: https://github.com/Kava-Labs/kava/compare/v0.16.0...v0.16.1
|
||||
[v0.16.0]: https://github.com/Kava-Labs/kava/compare/v0.15.2...v0.16.0
|
||||
|
27
Dockerfile
27
Dockerfile
@ -1,4 +1,4 @@
|
||||
FROM golang:1.20-alpine AS build-env
|
||||
FROM golang:1.21-alpine AS build-env
|
||||
|
||||
# Set up dependencies
|
||||
# bash, jq, curl for debugging
|
||||
@ -7,9 +7,27 @@ FROM golang:1.20-alpine AS build-env
|
||||
RUN apk add bash git make libc-dev gcc linux-headers eudev-dev jq curl
|
||||
|
||||
# Set working directory for the build
|
||||
WORKDIR /root/kava
|
||||
WORKDIR /root/0g-chain
|
||||
# default home directory is /root
|
||||
|
||||
# Copy dependency files first to facilitate dependency caching
|
||||
COPY ./go.mod ./
|
||||
COPY ./go.sum ./
|
||||
|
||||
# Download dependencies
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go version && go mod download
|
||||
|
||||
# Cosmwasm - Download correct libwasmvm version
|
||||
RUN ARCH=$(uname -m) && WASMVM_VERSION=$(go list -m github.com/CosmWasm/wasmvm | sed 's/.* //') && \
|
||||
wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/libwasmvm_muslc.$ARCH.a \
|
||||
-O /lib/libwasmvm.$ARCH.a && \
|
||||
# verify checksum
|
||||
wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/checksums.txt -O /tmp/checksums.txt && \
|
||||
sha256sum /lib/libwasmvm.$ARCH.a | grep $(cat /tmp/checksums.txt | grep libwasmvm_muslc.$ARCH | cut -d ' ' -f 1)
|
||||
|
||||
|
||||
# Add source files
|
||||
COPY . .
|
||||
|
||||
@ -18,11 +36,12 @@ COPY . .
|
||||
# Mount go build and mod caches as container caches, persisted between builder invocations
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
LINK_STATICALLY=true \
|
||||
make install
|
||||
|
||||
FROM alpine:3.15
|
||||
|
||||
RUN apk add bash jq curl
|
||||
COPY --from=build-env /go/bin/kava /bin/kava
|
||||
COPY --from=build-env /go/bin/0gchaind /bin/0gchaind
|
||||
|
||||
CMD ["kava"]
|
||||
CMD ["0gchaind"]
|
||||
|
42
Dockerfile-node
Normal file
42
Dockerfile-node
Normal file
@ -0,0 +1,42 @@
|
||||
FROM --platform=linux/amd64 ubuntu:24.04
|
||||
|
||||
# Install dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
git \
|
||||
sudo \
|
||||
wget \
|
||||
jq \
|
||||
make \
|
||||
gcc \
|
||||
unzip && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Go
|
||||
RUN wget https://golang.org/dl/go1.22.5.linux-amd64.tar.gz && \
|
||||
tar -C /usr/local -xzf go1.22.5.linux-amd64.tar.gz && \
|
||||
rm go1.22.5.linux-amd64.tar.gz
|
||||
# Set Go environment variables
|
||||
ENV GOPATH=/root/go
|
||||
ENV PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
|
||||
# Create Go workspace directory
|
||||
RUN mkdir -p /root/go
|
||||
|
||||
WORKDIR /root
|
||||
|
||||
# https://docs.0g.ai/0g-doc/run-a-node/validator-node
|
||||
RUN git clone -b v0.2.3 https://github.com/0glabs/0g-chain.git
|
||||
RUN ./0g-chain/networks/testnet/install.sh
|
||||
|
||||
RUN 0gchaind config chain-id zgtendermint_16600-2
|
||||
|
||||
RUN 0gchaind init testnetnode --chain-id zgtendermint_16600-2
|
||||
|
||||
RUN rm ~/.0gchain/config/genesis.json
|
||||
RUN wget -P ~/.0gchain/config https://github.com/0glabs/0g-chain/releases/download/v0.2.3/genesis.json
|
||||
|
||||
RUN 0gchaind validate-genesis
|
||||
|
||||
RUN sed -i 's|seeds = ""|seeds = "81987895a11f6689ada254c6b57932ab7ed909b6@54.241.167.190:26656,010fb4de28667725a4fef26cdc7f9452cc34b16d@54.176.175.48:26656,e9b4bc203197b62cc7e6a80a64742e752f4210d5@54.193.250.204:26656,68b9145889e7576b652ca68d985826abd46ad660@18.166.164.232:26656"|' $HOME/.0gchain/config/config.toml
|
||||
|
||||
ENTRYPOINT ["0gchaind", "start"]
|
@ -1,34 +1,27 @@
|
||||
FROM golang:1.20-bullseye AS kava-builder
|
||||
FROM kava/rocksdb:v8.10.1-go1.21 AS kava-builder
|
||||
|
||||
# Set up dependencies
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y git make gcc libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update
|
||||
|
||||
# Set working directory for the build
|
||||
WORKDIR /root
|
||||
# default home directory is /root
|
||||
WORKDIR /root/0gchain
|
||||
# Copy dependency files first to facilitate dependency caching
|
||||
COPY ./go.mod ./
|
||||
COPY ./go.sum ./
|
||||
|
||||
# install rocksdb
|
||||
ARG rocksdb_version=v8.1.1
|
||||
ENV ROCKSDB_VERSION=$rocksdb_version
|
||||
# Download dependencies
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go version && go mod download
|
||||
|
||||
RUN git clone https://github.com/facebook/rocksdb.git \
|
||||
&& cd rocksdb \
|
||||
&& git checkout $ROCKSDB_VERSION \
|
||||
&& make -j$(nproc) install-shared \
|
||||
&& ldconfig
|
||||
# Add source files
|
||||
COPY . .
|
||||
|
||||
# Add source files for kava
|
||||
COPY . kava
|
||||
|
||||
ARG kava_database_backend=rocksdb
|
||||
ENV KAVA_DATABASE_BACKEND=$kava_database_backend
|
||||
ARG 0gchain_database_backend=rocksdb
|
||||
ENV 0GCHAIN_DATABASE_BACKEND=$0gchain_database_backend
|
||||
|
||||
# Mount go build and mod caches as container caches, persisted between builder invocations
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
cd kava && make install COSMOS_BUILD_OPTIONS=$KAVA_DATABASE_BACKEND
|
||||
make install COSMOS_BUILD_OPTIONS=$0GCHAIN_DATABASE_BACKEND
|
||||
|
||||
|
||||
FROM ubuntu:22.04
|
||||
@ -38,10 +31,10 @@ RUN apt-get update \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# copy rocksdb shared objects
|
||||
COPY --from=kava-builder /usr/local/lib/ /usr/local/lib/
|
||||
COPY --from=chain-builder /usr/local/lib/ /usr/local/lib/
|
||||
RUN ldconfig
|
||||
|
||||
# copy kava binary
|
||||
COPY --from=kava-builder /go/bin/kava /bin/kava
|
||||
# copy 0g-chain binary
|
||||
COPY --from=chain-builder /go/bin/0gchaind /bin/0gchaind
|
||||
|
||||
CMD ["kava"]
|
||||
CMD ["0gchaind"]
|
||||
|
22
Dockerfile-rocksdb-base
Normal file
22
Dockerfile-rocksdb-base
Normal file
@ -0,0 +1,22 @@
|
||||
# published to https://hub.docker.com/repository/docker/kava/rocksdb/tags
|
||||
# docker buildx build --platform linux/amd64,linux/arm64 -t kava/rocksdb:v8.10.1-go1.21 -f Dockerfile-rocksdb-base . --push
|
||||
FROM golang:1.21-bullseye
|
||||
|
||||
# Set up dependencies
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y git make gcc libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set working directory for the build
|
||||
WORKDIR /root
|
||||
# default home directory is /root
|
||||
|
||||
# install rocksdb
|
||||
ARG rocksdb_version=v8.10.0
|
||||
ENV ROCKSDB_VERSION=$rocksdb_version
|
||||
|
||||
RUN git clone https://github.com/facebook/rocksdb.git \
|
||||
&& cd rocksdb \
|
||||
&& git checkout $ROCKSDB_VERSION \
|
||||
&& make -j$(nproc) install-shared \
|
||||
&& ldconfig
|
103
Makefile
103
Makefile
@ -1,9 +1,13 @@
|
||||
################################################################################
|
||||
### Project Info ###
|
||||
################################################################################
|
||||
PROJECT_NAME := kava# unique namespace for project
|
||||
|
||||
PROJECT_NAME := 0g-chain# unique namespace for project
|
||||
BINARY_NAME := 0gchaind
|
||||
MAIN_ENTRY := ./cmd/$(BINARY_NAME)
|
||||
DOCKER_IMAGE_NAME := 0glabs/$(PROJECT_NAME)
|
||||
GO_BIN ?= go
|
||||
ARCH := $(shell uname -m)
|
||||
WASMVM_VERSION := $(shell $(GO_BIN) list -m github.com/CosmWasm/wasmvm | sed 's/.* //')
|
||||
|
||||
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
||||
GIT_COMMIT := $(shell git rev-parse HEAD)
|
||||
@ -28,7 +32,7 @@ VERSION := $(GIT_COMMIT_SHORT)
|
||||
VERSION_NUMBER := $(VERSION)
|
||||
endif
|
||||
|
||||
TENDERMINT_VERSION := $(shell $(GO_BIN) list -m github.com/tendermint/tendermint | sed 's:.* ::')
|
||||
TENDERMINT_VERSION := $(shell $(GO_BIN) list -m github.com/cometbft/cometbft | sed 's:.* ::')
|
||||
COSMOS_SDK_VERSION := $(shell $(GO_BIN) list -m github.com/cosmos/cosmos-sdk | sed 's:.* ::')
|
||||
|
||||
.PHONY: print-git-info
|
||||
@ -37,7 +41,7 @@ print-git-info:
|
||||
|
||||
.PHONY: print-version
|
||||
print-version:
|
||||
@echo "kava $(VERSION)\ntendermint $(TENDERMINT_VERSION)\ncosmos $(COSMOS_SDK_VERSION)"
|
||||
@echo "$(BINARY_NAME) $(VERSION)\ntendermint $(TENDERMINT_VERSION)\ncosmos $(COSMOS_SDK_VERSION)"
|
||||
|
||||
################################################################################
|
||||
### Project Settings ###
|
||||
@ -45,7 +49,7 @@ print-version:
|
||||
LEDGER_ENABLED ?= true
|
||||
DOCKER:=docker
|
||||
DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf
|
||||
HTTPS_GIT := https://github.com/Kava-Labs/kava.git
|
||||
HTTPS_GIT := https://github.com/0glabs/0g-chain.git
|
||||
|
||||
################################################################################
|
||||
### Machine Info ###
|
||||
@ -76,7 +80,7 @@ print-machine-info:
|
||||
BUILD_DIR := build# build files
|
||||
BIN_DIR := $(BUILD_DIR)/bin# for binary dev dependencies
|
||||
BUILD_CACHE_DIR := $(BUILD_DIR)/.cache# caching for non-artifact outputs
|
||||
OUT_DIR := out# for artifact intermediates and outputs
|
||||
OUT_DIR := ./.build# for artifact intermediates and outputs
|
||||
|
||||
ROOT_DIR := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))# absolute path to root
|
||||
export PATH := $(ROOT_DIR)/$(BIN_DIR):$(PATH)# add local bin first in path
|
||||
@ -101,6 +105,8 @@ include $(BUILD_DIR)/deps.mk
|
||||
include $(BUILD_DIR)/proto.mk
|
||||
include $(BUILD_DIR)/proto-deps.mk
|
||||
|
||||
include $(BUILD_DIR)/lint.mk
|
||||
|
||||
#export GO111MODULE = on
|
||||
# process build tags
|
||||
build_tags = netgo
|
||||
@ -142,12 +148,12 @@ build_tags_comma_sep := $(subst $(whitespace),$(comma),$(build_tags))
|
||||
|
||||
# process linker flags
|
||||
|
||||
ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=kava \
|
||||
-X github.com/cosmos/cosmos-sdk/version.AppName=kava \
|
||||
ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=$(PROJECT_NAME) \
|
||||
-X github.com/cosmos/cosmos-sdk/version.AppName=$(PROJECT_NAME) \
|
||||
-X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION_NUMBER) \
|
||||
-X github.com/cosmos/cosmos-sdk/version.Commit=$(GIT_COMMIT) \
|
||||
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \
|
||||
-X github.com/tendermint/tendermint/version.TMCoreSemVer=$(TENDERMINT_VERSION)
|
||||
-X github.com/cometbft/cometbft/version.TMCoreSemVer=$(TENDERMINT_VERSION)
|
||||
|
||||
# DB backend selection
|
||||
ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS)))
|
||||
@ -172,6 +178,10 @@ endif
|
||||
ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS)))
|
||||
ldflags += -w -s
|
||||
endif
|
||||
|
||||
ifeq ($(LINK_STATICALLY),true)
|
||||
ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static -lm"
|
||||
endif
|
||||
ldflags += $(LDFLAGS)
|
||||
ldflags := $(strip $(ldflags))
|
||||
|
||||
@ -188,16 +198,28 @@ all: install
|
||||
|
||||
build: go.sum
|
||||
ifeq ($(OS), Windows_NT)
|
||||
$(GO_BIN) build -mod=readonly $(BUILD_FLAGS) -o out/$(shell $(GO_BIN) env GOOS)/kava.exe ./cmd/kava
|
||||
$(GO_BIN) build -mod=readonly $(BUILD_FLAGS) -o out/$(shell $(GO_BIN) env GOOS)/$(BINARY_NAME).exe $(MAIN_ENTRY)
|
||||
else
|
||||
$(GO_BIN) build -mod=readonly $(BUILD_FLAGS) -o out/$(shell $(GO_BIN) env GOOS)/kava ./cmd/kava
|
||||
$(GO_BIN) build -mod=readonly $(BUILD_FLAGS) -o out/$(shell $(GO_BIN) env GOOS)/$(BINARY_NAME) $(MAIN_ENTRY)
|
||||
endif
|
||||
|
||||
build-release: go.sum
|
||||
wget -q https://github.com/CosmWasm/wasmvm/releases/download/$(WASMVM_VERSION)/libwasmvm_muslc.$(ARCH).a -O /lib/libwasmvm.$(ARCH).a
|
||||
$(GO_BIN) build -mod=readonly $(BUILD_FLAGS) -o out/$(shell $(GO_BIN) env GOOS)/$(BINARY_NAME) $(MAIN_ENTRY)
|
||||
|
||||
build-linux: go.sum
|
||||
LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build
|
||||
|
||||
# build on rocksdb-backed kava on macOS with shared libs from brew
|
||||
# this assumes you are on macOS & these deps have been installed with brew:
|
||||
# rocksdb, snappy, lz4, and zstd
|
||||
# use like `make build-rocksdb-brew COSMOS_BUILD_OPTIONS=rocksdb`
|
||||
build-rocksdb-brew:
|
||||
export CGO_CFLAGS := -I$(shell brew --prefix rocksdb)/include
|
||||
export CGO_LDFLAGS := -L$(shell brew --prefix rocksdb)/lib -lrocksdb -lstdc++ -lm -lz -L$(shell brew --prefix snappy)/lib -L$(shell brew --prefix lz4)/lib -L$(shell brew --prefix zstd)/lib
|
||||
|
||||
install: go.sum
|
||||
$(GO_BIN) install -mod=readonly $(BUILD_FLAGS) ./cmd/kava
|
||||
$(GO_BIN) install -mod=readonly $(BUILD_FLAGS) $(MAIN_ENTRY)
|
||||
|
||||
########################################
|
||||
### Tools & dependencies
|
||||
@ -219,49 +241,43 @@ go.sum: go.mod
|
||||
# Set to exclude riot links as they trigger false positives
|
||||
link-check:
|
||||
@$(GO_BIN) get -u github.com/raviqqe/liche@f57a5d1c5be4856454cb26de155a65a4fd856ee3
|
||||
# TODO: replace kava in following line with project name
|
||||
liche -r . --exclude "^http://127.*|^https://riot.im/app*|^http://kava-testnet*|^https://testnet-dex*|^https://kava3.data.kava.io*|^https://ipfs.io*|^https://apps.apple.com*|^https://kava.quicksync.io*"
|
||||
|
||||
|
||||
lint:
|
||||
golangci-lint run
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" | xargs gofmt -d -s
|
||||
$(GO_BIN) mod verify
|
||||
.PHONY: lint
|
||||
|
||||
format:
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs gofmt -w -s
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs misspell -w
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs goimports -w -local github.com/tendermint
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs goimports -w -local github.com/cosmos/cosmos-sdk
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs goimports -w -local github.com/kava-labs/kava
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs goimports -w -local github.com/0glabs/0g-chain
|
||||
.PHONY: format
|
||||
|
||||
###############################################################################
|
||||
### Localnet ###
|
||||
###############################################################################
|
||||
|
||||
# Build docker image and tag as kava/kava:local
|
||||
# Build docker image and tag as 0glabs/0g-chain:local
|
||||
docker-build:
|
||||
DOCKER_BUILDKIT=1 $(DOCKER) build -t kava/kava:local .
|
||||
DOCKER_BUILDKIT=1 $(DOCKER) build -t $(DOCKER_IMAGE_NAME):local .
|
||||
|
||||
docker-build-rocksdb:
|
||||
DOCKER_BUILDKIT=1 $(DOCKER) build -f Dockerfile-rocksdb -t kava/kava:local .
|
||||
DOCKER_BUILDKIT=1 $(DOCKER) build -f Dockerfile-rocksdb -t $(DOCKER_IMAGE_NAME):local .
|
||||
|
||||
build-docker-local-kava:
|
||||
build-docker-local-0gchain:
|
||||
@$(MAKE) -C networks/local
|
||||
|
||||
# Run a 4-node testnet locally
|
||||
localnet-start: build-linux localnet-stop
|
||||
@if ! [ -f build/node0/kvd/config/genesis.json ]; then docker run --rm -v $(CURDIR)/build:/kvd:Z kava/kavanode testnet --v 4 -o . --starting-ip-address 192.168.10.2 --keyring-backend=test ; fi
|
||||
docker-compose up -d
|
||||
$(DOCKER) compose up -d
|
||||
|
||||
localnet-stop:
|
||||
docker-compose down
|
||||
$(DOCKER) compose down
|
||||
|
||||
# Launch a new single validator chain
|
||||
start:
|
||||
./contrib/devnet/init-new-chain.sh
|
||||
kava start
|
||||
$(BINARY_NAME) start
|
||||
|
||||
#proto-format:
|
||||
#@echo "Formatting Protobuf files"
|
||||
@ -298,12 +314,14 @@ test-basic: test
|
||||
test-e2e: docker-build
|
||||
$(GO_BIN) test -failfast -count=1 -v ./tests/e2e/...
|
||||
|
||||
# run interchaintest tests (./tests/e2e-ibc)
|
||||
test-ibc: docker-build
|
||||
cd tests/e2e-ibc && KAVA_TAG=local $(GO_BIN) test -timeout 10m .
|
||||
.PHONY: test-ibc
|
||||
|
||||
test:
|
||||
@$(GO_BIN) test $$($(GO_BIN) list ./... | grep -v 'contrib' | grep -v 'tests/e2e')
|
||||
|
||||
test-rocksdb:
|
||||
@go test -tags=rocksdb ./cmd/kava/opendb
|
||||
|
||||
# Run cli integration tests
|
||||
# `-p 4` to use 4 cores, `-tags cli_test` to tell $(GO_BIN) not to ignore the cli package
|
||||
# These tests use the `kvd` or `kvcli` binaries in the build dir, or in `$BUILDDIR` if that env var is set.
|
||||
@ -314,23 +332,36 @@ test-cli: build
|
||||
test-migrate:
|
||||
@$(GO_BIN) test -v -count=1 ./migrate/...
|
||||
|
||||
# Use the old Apple linker to workaround broken xcode - https://github.com/golang/go/issues/65169
|
||||
ifeq ($(OS_FAMILY),Darwin)
|
||||
FUZZLDFLAGS := -ldflags=-extldflags=-Wl,-ld_classic
|
||||
endif
|
||||
|
||||
test-fuzz:
|
||||
@$(GO_BIN) test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzMintCoins ./x/precisebank/keeper
|
||||
@$(GO_BIN) test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzBurnCoins ./x/precisebank/keeper
|
||||
@$(GO_BIN) test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzSendCoins ./x/precisebank/keeper
|
||||
@$(GO_BIN) test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzGenesisStateValidate_NonZeroRemainder ./x/precisebank/types
|
||||
@$(GO_BIN) test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzGenesisStateValidate_ZeroRemainder ./x/precisebank/types
|
||||
|
||||
# Kick start lots of sims on an AWS cluster.
|
||||
# This submits an AWS Batch job to run a lot of sims, each within a docker image. Results are uploaded to S3
|
||||
start-remote-sims:
|
||||
# build the image used for running sims in, and tag it
|
||||
docker build -f simulations/Dockerfile -t kava/kava-sim:master .
|
||||
docker build -f simulations/Dockerfile -t $(DOCKER_IMAGE_NAME)-sim:master .
|
||||
# push that image to the hub
|
||||
docker push kava/kava-sim:master
|
||||
docker push $(DOCKER_IMAGE_NAME)-sim:master
|
||||
# submit an array job on AWS Batch, using 1000 seeds, spot instances
|
||||
aws batch submit-job \
|
||||
-—job-name "master-$(VERSION)" \
|
||||
-—job-queue “simulation-1-queue-spot" \
|
||||
-—job-queue "simulation-1-queue-spot" \
|
||||
-—array-properties size=1000 \
|
||||
-—job-definition kava-sim-master \
|
||||
-—job-definition $(BINARY_NAME)-sim-master \
|
||||
-—container-override environment=[{SIM_NAME=master-$(VERSION)}]
|
||||
|
||||
update-kvtool:
|
||||
git submodule update
|
||||
git submodule init || true
|
||||
git submodule update --remote
|
||||
cd tests/e2e/kvtool && make install
|
||||
|
||||
.PHONY: all build-linux install clean build test test-cli test-all test-rest test-basic start-remote-sims
|
||||
.PHONY: all build-linux install build test test-cli test-all test-rest test-basic test-fuzz start-remote-sims
|
||||
|
76
README.md
76
README.md
@ -1,65 +1,35 @@
|
||||
<br />
|
||||
<p align="center">
|
||||
<img src="./kava-logo.svg" width="300">
|
||||
<img src="https://framerusercontent.com/images/JJi9BT4FAjp4W63c3jjNz0eezQ.png" alt="Logo" width="140" height="140">
|
||||
</p>
|
||||
<p align="center">
|
||||
<b><font size="5">0G is limitless scalability</font></b>
|
||||
</p>
|
||||
<br />
|
||||
|
||||
<div align="center">
|
||||
# 0G Chain
|
||||
Zero Gravity (0G) is the foundational infrastructure for high-performance dapps and chains particularly for AI.
|
||||
|
||||
[](https://github.com/kava-labs/kava/releases/latest)
|
||||
[](https://circleci.com/gh/Kava-Labs/kava/tree/master)
|
||||
[](https://goreportcard.com/report/github.com/kava-labs/kava)
|
||||
[](https://godoc.org/github.com/Kava-Labs/kava)
|
||||
[](https://github.com/Kava-Labs/kava/blob/master/LICENSE.md)
|
||||
[](https://twitter.com/KAVA_CHAIN)
|
||||
[](https://discord.com/invite/kQzh3Uv)
|
||||
It efficiently orchestrates utilization of hardware resources such as storage and compute and software assets such as data and models to handle the scale and complexity of AI workloads.
|
||||
|
||||
</div>
|
||||
Continue reading [here](https://docs.0g.ai/intro) if you want to learn more about 0G dAIOS and how its various layers enable limitless scalability.
|
||||
|
||||
<div align="center">
|
||||
## 0G Product Suite
|
||||
- DA: ultra high-performance data availability layer with KZG and quorum-based DAS
|
||||
- Storage: decentralized storage with erasure coding and replication
|
||||
- Inference Serving: flexible serving framework for inferences and finetuning
|
||||
- Network: high-performance, low-latency, and decentralized network
|
||||
|
||||
### [Telegram](https://t.me/kavalabs) | [Medium](https://medium.com/kava-labs) | [Discord](https://discord.gg/JJYnuCx)
|
||||
## Documentation
|
||||
- If you want to build with 0G's network, DA layer, inference serving, or storage SDK, please refer to the [Build with 0G Documentation](https://docs.0g.ai/build-with-0g/contracts).
|
||||
|
||||
</div>
|
||||
- If you want to run a validator node, DA node, or storage node, please refer to the [Run a Node Documentation](https://docs.0g.ai/run-a-node/overview).
|
||||
|
||||
Reference implementation of Kava, a blockchain for cross-chain DeFi. Built using the [cosmos-sdk](https://github.com/cosmos/cosmos-sdk).
|
||||
|
||||
## Mainnet
|
||||
## Support and Additional Resources
|
||||
We want to do everything we can to help you be successful while working on your contribution and projects. Here you'll find various resources and communities that may help you complete a project or contribute to 0G.
|
||||
|
||||
The current recommended version of the software for mainnet is [v0.24.1](https://github.com/Kava-Labs/kava/releases/tag/v0.24.1). The master branch of this repository often contains considerable development work since the last mainnet release and is __not__ runnable on mainnet.
|
||||
|
||||
### Installation and Setup
|
||||
For detailed instructions see [the Kava docs](https://docs.kava.io/docs/participate/validator-node).
|
||||
|
||||
```bash
|
||||
git checkout v0.24.1
|
||||
make install
|
||||
```
|
||||
|
||||
End-to-end tests of Kava use a tool for generating networks with different configurations: [kvtool](https://github.com/Kava-Labs/kvtool).
|
||||
This is included as a git submodule at [`tests/e2e/kvtool`](tests/e2e/kvtool/).
|
||||
When first cloning the repository, if you intend to run the e2e integration tests, you must also
|
||||
clone the submodules:
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/Kava-Labs/kava.git
|
||||
```
|
||||
|
||||
Or, if you have already cloned the repo: `git submodule update --init`
|
||||
|
||||
## Testnet
|
||||
|
||||
For further information on joining the testnet, head over to the [testnet repo](https://github.com/Kava-Labs/kava-testnets).
|
||||
|
||||
## Docs
|
||||
|
||||
Kava protocol and client documentation can be found in the [Kava docs](https://docs.kava.io).
|
||||
|
||||
If you have technical questions or concerns, ask a developer or community member in the [Kava discord](https://discord.com/invite/kQzh3Uv).
|
||||
|
||||
## Security
|
||||
|
||||
If you find a security issue, please report it to security [at] kava.io. Depending on the verification and severity, a bug bounty may be available.
|
||||
|
||||
## License
|
||||
|
||||
Copyright © Kava Labs, Inc. All rights reserved.
|
||||
|
||||
Licensed under the [Apache v2 License](LICENSE.md).
|
||||
### Communities
|
||||
- [0G Telegram](https://t.me/web3_0glabs)
|
||||
- [0G Discord](https://discord.com/invite/0glabs)
|
@ -11,15 +11,15 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
dbm "github.com/cometbft/cometbft-db"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
|
||||
"cosmossdk.io/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/simapp/helpers"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
@ -32,15 +32,10 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
|
||||
"github.com/kava-labs/kava/x/auction"
|
||||
"github.com/kava-labs/kava/x/bep3"
|
||||
"github.com/kava-labs/kava/x/cdp"
|
||||
"github.com/kava-labs/kava/x/committee"
|
||||
"github.com/kava-labs/kava/x/incentive"
|
||||
"github.com/kava-labs/kava/x/kavadist"
|
||||
"github.com/kava-labs/kava/x/pricefeed"
|
||||
"github.com/kava-labs/kava/x/swap"
|
||||
validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
|
||||
"github.com/0glabs/0g-chain/x/bep3"
|
||||
"github.com/0glabs/0g-chain/x/committee"
|
||||
"github.com/0glabs/0g-chain/x/pricefeed"
|
||||
validatorvesting "github.com/0glabs/0g-chain/x/validator-vesting"
|
||||
)
|
||||
|
||||
type StoreKeysPrefixes struct {
|
||||
@ -280,7 +275,7 @@ func TestAppStateDeterminism(t *testing.T) {
|
||||
config.ExportParamsPath = ""
|
||||
config.OnOperation = false
|
||||
config.AllInvariants = false
|
||||
config.ChainID = helpers.SimAppChainID
|
||||
config.ChainID = sims.SimAppChainID
|
||||
|
||||
numTimesToRunPerSeed := 2
|
||||
appHashList := make([]json.RawMessage, numTimesToRunPerSeed)
|
||||
|
@ -8,8 +8,13 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
tmbytes "github.com/cometbft/cometbft/libs/bytes"
|
||||
ctypes "github.com/cometbft/cometbft/rpc/core/types"
|
||||
jsonrpctypes "github.com/cometbft/cometbft/rpc/jsonrpc/types"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
@ -18,10 +23,6 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
jsonrpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
)
|
||||
|
||||
type SimulateRequestTestSuite struct {
|
||||
@ -51,9 +52,9 @@ func (suite *SimulateRequestTestSuite) TearDownTest() {
|
||||
}
|
||||
|
||||
func (suite *SimulateRequestTestSuite) TestSimulateRequest() {
|
||||
fromAddr, err := sdk.AccAddressFromBech32("kava1esagqd83rhqdtpy5sxhklaxgn58k2m3s3mnpea")
|
||||
fromAddr, err := sdk.AccAddressFromBech32("0g1esagqd83rhqdtpy5sxhklaxgn58k2m3s3mnpea")
|
||||
suite.Require().NoError(err)
|
||||
toAddr, err := sdk.AccAddressFromBech32("kava1mq9qxlhze029lm0frzw2xr6hem8c3k9ts54w0w")
|
||||
toAddr, err := sdk.AccAddressFromBech32("0g1mq9qxlhze029lm0frzw2xr6hem8c3k9ts54w0w")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
simRequest := app.SimulateRequest{
|
||||
@ -61,11 +62,11 @@ func (suite *SimulateRequestTestSuite) TestSimulateRequest() {
|
||||
bank.MsgSend{
|
||||
FromAddress: fromAddr,
|
||||
ToAddress: toAddr,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(1e6))),
|
||||
Amount: sdk.NewCoins(chaincfg.MakeCoinForGasDenom(1e6)),
|
||||
},
|
||||
},
|
||||
Fee: auth.StdFee{
|
||||
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(5e4))),
|
||||
Amount: sdk.NewCoins(chaincfg.MakeCoinForGasDenom(5e4)),
|
||||
Gas: 1e6,
|
||||
},
|
||||
Memo: "test memo",
|
||||
|
341
app/abci_utils.go
Normal file
341
app/abci_utils.go
Normal file
@ -0,0 +1,341 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
)
|
||||
|
||||
type (
|
||||
// GasTx defines the contract that a transaction with a gas limit must implement.
|
||||
GasTx interface {
|
||||
GetGas() uint64
|
||||
}
|
||||
|
||||
// ProposalTxVerifier defines the interface that is implemented by BaseApp,
|
||||
// that any custom ABCI PrepareProposal and ProcessProposal handler can use
|
||||
// to verify a transaction.
|
||||
ProposalTxVerifier interface {
|
||||
PrepareProposalVerifyTx(tx sdk.Tx) ([]byte, error)
|
||||
ProcessProposalVerifyTx(txBz []byte) (sdk.Tx, error)
|
||||
}
|
||||
|
||||
// DefaultProposalHandler defines the default ABCI PrepareProposal and
|
||||
// ProcessProposal handlers.
|
||||
DefaultProposalHandler struct {
|
||||
mempool mempool.Mempool
|
||||
txVerifier ProposalTxVerifier
|
||||
txSelector TxSelector
|
||||
}
|
||||
)
|
||||
|
||||
func NewDefaultProposalHandler(mp mempool.Mempool, txVerifier ProposalTxVerifier) *DefaultProposalHandler {
|
||||
return &DefaultProposalHandler{
|
||||
mempool: mp,
|
||||
txVerifier: txVerifier,
|
||||
txSelector: NewDefaultTxSelector(),
|
||||
}
|
||||
}
|
||||
|
||||
// SetTxSelector sets the TxSelector function on the DefaultProposalHandler.
|
||||
func (h *DefaultProposalHandler) SetTxSelector(ts TxSelector) {
|
||||
h.txSelector = ts
|
||||
}
|
||||
|
||||
// PrepareProposalHandler returns the default implementation for processing an
|
||||
// ABCI proposal. The application's mempool is enumerated and all valid
|
||||
// transactions are added to the proposal. Transactions are valid if they:
|
||||
//
|
||||
// 1) Successfully encode to bytes.
|
||||
// 2) Are valid (i.e. pass runTx, AnteHandler only).
|
||||
//
|
||||
// Enumeration is halted once RequestPrepareProposal.MaxBytes of transactions is
|
||||
// reached or the mempool is exhausted.
|
||||
//
|
||||
// Note:
|
||||
//
|
||||
// - Step (2) is identical to the validation step performed in
|
||||
// DefaultProcessProposal. It is very important that the same validation logic
|
||||
// is used in both steps, and applications must ensure that this is the case in
|
||||
// non-default handlers.
|
||||
//
|
||||
// - If no mempool is set or if the mempool is a no-op mempool, the transactions
|
||||
// requested from CometBFT will simply be returned, which, by default, are in
|
||||
// FIFO order.
|
||||
func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
|
||||
return func(ctx sdk.Context, req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
|
||||
var maxBlockGas uint64
|
||||
if b := ctx.ConsensusParams().Block; b != nil {
|
||||
maxBlockGas = uint64(b.MaxGas)
|
||||
}
|
||||
|
||||
defer h.txSelector.Clear()
|
||||
|
||||
// If the mempool is nil or NoOp we simply return the transactions
|
||||
// requested from CometBFT, which, by default, should be in FIFO order.
|
||||
//
|
||||
// Note, we still need to ensure the transactions returned respect req.MaxTxBytes.
|
||||
_, isNoOp := h.mempool.(mempool.NoOpMempool)
|
||||
if h.mempool == nil || isNoOp {
|
||||
for _, txBz := range req.Txs {
|
||||
// XXX: We pass nil as the memTx because we have no way of decoding the
|
||||
// txBz. We'd need to break (update) the ProposalTxVerifier interface.
|
||||
// As a result, we CANNOT account for block max gas.
|
||||
stop := h.txSelector.SelectTxForProposal(uint64(req.MaxTxBytes), maxBlockGas, nil, txBz)
|
||||
if stop {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return abci.ResponsePrepareProposal{Txs: h.txSelector.SelectedTxs()}
|
||||
}
|
||||
|
||||
selectedTxsSignersSeqs := make(map[string]uint64)
|
||||
var selectedTxsNums int
|
||||
|
||||
var waitRemoveTxs []sdk.Tx
|
||||
|
||||
mempool.SelectBy(ctx, h.mempool, req.Txs, func(memTx sdk.Tx) bool {
|
||||
sigs, err := memTx.(signing.SigVerifiableTx).GetSignaturesV2()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to get signatures: %w", err))
|
||||
}
|
||||
// If the signers aren't in selectedTxsSignersSeqs then we haven't seen them before
|
||||
// so we add them and continue given that we don't need to check the sequence.
|
||||
shouldAdd := true
|
||||
txSignersSeqs := make(map[string]uint64)
|
||||
if len(sigs) == 0 {
|
||||
msgs := memTx.GetMsgs()
|
||||
if len(msgs) == 1 {
|
||||
msgEthTx, ok := msgs[0].(*evmtypes.MsgEthereumTx)
|
||||
if ok {
|
||||
ethTx := msgEthTx.AsTransaction()
|
||||
signer := gethtypes.NewEIP2930Signer(ethTx.ChainId())
|
||||
ethSender, err := signer.Sender(ethTx)
|
||||
if err == nil {
|
||||
signer := sdk.AccAddress(ethSender.Bytes()).String()
|
||||
nonce := ethTx.Nonce()
|
||||
seq, ok := selectedTxsSignersSeqs[signer]
|
||||
if !ok {
|
||||
txSignersSeqs[signer] = nonce
|
||||
} else {
|
||||
// If we have seen this signer before in this block, we must make
|
||||
// sure that the current sequence is seq+1; otherwise is invalid
|
||||
// and we skip it.
|
||||
if seq+1 != nonce {
|
||||
shouldAdd = false
|
||||
} else {
|
||||
txSignersSeqs[signer] = nonce
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, sig := range sigs {
|
||||
signer := sdk.AccAddress(sig.PubKey.Address()).String()
|
||||
seq, ok := selectedTxsSignersSeqs[signer]
|
||||
if !ok {
|
||||
txSignersSeqs[signer] = sig.Sequence
|
||||
continue
|
||||
}
|
||||
|
||||
// If we have seen this signer before in this block, we must make
|
||||
// sure that the current sequence is seq+1; otherwise is invalid
|
||||
// and we skip it.
|
||||
if seq+1 != sig.Sequence {
|
||||
shouldAdd = false
|
||||
break
|
||||
}
|
||||
txSignersSeqs[signer] = sig.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
if shouldAdd {
|
||||
// NOTE: Since transaction verification was already executed in CheckTx,
|
||||
// which calls mempool.Insert, in theory everything in the pool should be
|
||||
// valid. But some mempool implementations may insert invalid txs, so we
|
||||
// check again.
|
||||
txBz, err := h.txVerifier.PrepareProposalVerifyTx(memTx)
|
||||
if err != nil {
|
||||
waitRemoveTxs = append(waitRemoveTxs, memTx)
|
||||
} else {
|
||||
stop := h.txSelector.SelectTxForProposal(uint64(req.MaxTxBytes), maxBlockGas, memTx, txBz)
|
||||
if stop {
|
||||
return false
|
||||
}
|
||||
|
||||
txsLen := len(h.txSelector.SelectedTxs())
|
||||
for sender, seq := range txSignersSeqs {
|
||||
// If txsLen != selectedTxsNums is true, it means that we've
|
||||
// added a new tx to the selected txs, so we need to update
|
||||
// the sequence of the sender.
|
||||
if txsLen != selectedTxsNums {
|
||||
selectedTxsSignersSeqs[sender] = seq
|
||||
} else if _, ok := selectedTxsSignersSeqs[sender]; !ok {
|
||||
// The transaction hasn't been added but it passed the
|
||||
// verification, so we know that the sequence is correct.
|
||||
// So we set this sender's sequence to seq-1, in order
|
||||
// to avoid unnecessary calls to PrepareProposalVerifyTx.
|
||||
selectedTxsSignersSeqs[sender] = seq - 1
|
||||
}
|
||||
}
|
||||
selectedTxsNums = txsLen
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
for i := range waitRemoveTxs {
|
||||
err := h.mempool.Remove(waitRemoveTxs[i])
|
||||
if err != nil && !errors.Is(err, mempool.ErrTxNotFound) {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return abci.ResponsePrepareProposal{Txs: h.txSelector.SelectedTxs()}
|
||||
}
|
||||
}
|
||||
|
||||
// ProcessProposalHandler returns the default implementation for processing an
|
||||
// ABCI proposal. Every transaction in the proposal must pass 2 conditions:
|
||||
//
|
||||
// 1. The transaction bytes must decode to a valid transaction.
|
||||
// 2. The transaction must be valid (i.e. pass runTx, AnteHandler only)
|
||||
//
|
||||
// If any transaction fails to pass either condition, the proposal is rejected.
|
||||
// Note that step (2) is identical to the validation step performed in
|
||||
// DefaultPrepareProposal. It is very important that the same validation logic
|
||||
// is used in both steps, and applications must ensure that this is the case in
|
||||
// non-default handlers.
|
||||
func (h *DefaultProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
|
||||
// If the mempool is nil or NoOp we simply return ACCEPT,
|
||||
// because PrepareProposal may have included txs that could fail verification.
|
||||
_, isNoOp := h.mempool.(mempool.NoOpMempool)
|
||||
if h.mempool == nil || isNoOp {
|
||||
return NoOpProcessProposal()
|
||||
}
|
||||
|
||||
return func(ctx sdk.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal {
|
||||
var totalTxGas uint64
|
||||
|
||||
var maxBlockGas int64
|
||||
if b := ctx.ConsensusParams().Block; b != nil {
|
||||
maxBlockGas = b.MaxGas
|
||||
}
|
||||
|
||||
for _, txBytes := range req.Txs {
|
||||
tx, err := h.txVerifier.ProcessProposalVerifyTx(txBytes)
|
||||
if err != nil {
|
||||
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
|
||||
}
|
||||
|
||||
if maxBlockGas > 0 {
|
||||
gasTx, ok := tx.(GasTx)
|
||||
if ok {
|
||||
totalTxGas += gasTx.GetGas()
|
||||
}
|
||||
|
||||
if totalTxGas > uint64(maxBlockGas) {
|
||||
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
|
||||
}
|
||||
}
|
||||
|
||||
// NoOpPrepareProposal defines a no-op PrepareProposal handler. It will always
|
||||
// return the transactions sent by the client's request.
|
||||
func NoOpPrepareProposal() sdk.PrepareProposalHandler {
|
||||
return func(_ sdk.Context, req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
|
||||
return abci.ResponsePrepareProposal{Txs: req.Txs}
|
||||
}
|
||||
}
|
||||
|
||||
// NoOpProcessProposal defines a no-op ProcessProposal Handler. It will always
|
||||
// return ACCEPT.
|
||||
func NoOpProcessProposal() sdk.ProcessProposalHandler {
|
||||
return func(_ sdk.Context, _ abci.RequestProcessProposal) abci.ResponseProcessProposal {
|
||||
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
|
||||
}
|
||||
}
|
||||
|
||||
// TxSelector defines a helper type that assists in selecting transactions during
|
||||
// mempool transaction selection in PrepareProposal. It keeps track of the total
|
||||
// number of bytes and total gas of the selected transactions. It also keeps
|
||||
// track of the selected transactions themselves.
|
||||
type TxSelector interface {
|
||||
// SelectedTxs should return a copy of the selected transactions.
|
||||
SelectedTxs() [][]byte
|
||||
|
||||
// Clear should clear the TxSelector, nulling out all relevant fields.
|
||||
Clear()
|
||||
|
||||
// SelectTxForProposal should attempt to select a transaction for inclusion in
|
||||
// a proposal based on inclusion criteria defined by the TxSelector. It must
|
||||
// return <true> if the caller should halt the transaction selection loop
|
||||
// (typically over a mempool) or <false> otherwise.
|
||||
SelectTxForProposal(maxTxBytes, maxBlockGas uint64, memTx sdk.Tx, txBz []byte) bool
|
||||
}
|
||||
|
||||
type defaultTxSelector struct {
|
||||
totalTxBytes uint64
|
||||
totalTxGas uint64
|
||||
selectedTxs [][]byte
|
||||
}
|
||||
|
||||
func NewDefaultTxSelector() TxSelector {
|
||||
return &defaultTxSelector{}
|
||||
}
|
||||
|
||||
func (ts *defaultTxSelector) SelectedTxs() [][]byte {
|
||||
txs := make([][]byte, len(ts.selectedTxs))
|
||||
copy(txs, ts.selectedTxs)
|
||||
return txs
|
||||
}
|
||||
|
||||
func (ts *defaultTxSelector) Clear() {
|
||||
ts.totalTxBytes = 0
|
||||
ts.totalTxGas = 0
|
||||
ts.selectedTxs = nil
|
||||
}
|
||||
|
||||
func (ts *defaultTxSelector) SelectTxForProposal(maxTxBytes, maxBlockGas uint64, memTx sdk.Tx, txBz []byte) bool {
|
||||
txSize := uint64(len(txBz))
|
||||
|
||||
var txGasLimit uint64
|
||||
if memTx != nil {
|
||||
if gasTx, ok := memTx.(GasTx); ok {
|
||||
txGasLimit = gasTx.GetGas()
|
||||
}
|
||||
}
|
||||
|
||||
// only add the transaction to the proposal if we have enough capacity
|
||||
if (txSize + ts.totalTxBytes) <= maxTxBytes {
|
||||
// If there is a max block gas limit, add the tx only if the limit has
|
||||
// not been met.
|
||||
if maxBlockGas > 0 {
|
||||
if (txGasLimit + ts.totalTxGas) <= maxBlockGas {
|
||||
ts.totalTxGas += txGasLimit
|
||||
ts.totalTxBytes += txSize
|
||||
ts.selectedTxs = append(ts.selectedTxs, txBz)
|
||||
}
|
||||
} else {
|
||||
ts.totalTxBytes += txSize
|
||||
ts.selectedTxs = append(ts.selectedTxs, txBz)
|
||||
}
|
||||
}
|
||||
|
||||
// check if we've reached capacity; if so, we cannot select any more transactions
|
||||
return ts.totalTxBytes >= maxTxBytes || (maxBlockGas > 0 && (ts.totalTxGas >= maxBlockGas))
|
||||
}
|
@ -5,16 +5,16 @@ import (
|
||||
"runtime/debug"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
tmlog "github.com/cometbft/cometbft/libs/log"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
ibcante "github.com/cosmos/ibc-go/v6/modules/core/ante"
|
||||
ibckeeper "github.com/cosmos/ibc-go/v6/modules/core/keeper"
|
||||
ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante"
|
||||
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"
|
||||
evmante "github.com/evmos/ethermint/app/ante"
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
tmlog "github.com/tendermint/tendermint/libs/log"
|
||||
)
|
||||
|
||||
// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC
|
||||
@ -168,6 +168,7 @@ func newEthAnteHandler(options HandlerOptions) sdk.AnteHandler {
|
||||
evmante.NewEthSetUpContextDecorator(options.EvmKeeper), // outermost AnteDecorator. SetUpContext must be called first
|
||||
evmante.NewEthMempoolFeeDecorator(options.EvmKeeper), // Check eth effective gas price against minimal-gas-prices
|
||||
evmante.NewEthValidateBasicDecorator(options.EvmKeeper),
|
||||
evmante.NewEvmMinGasPriceDecorator(options.EvmKeeper),
|
||||
evmante.NewEthSigVerificationDecorator(options.EvmKeeper),
|
||||
evmante.NewEthAccountVerificationDecorator(options.AccountKeeper, options.EvmKeeper),
|
||||
evmante.NewCanTransferDecorator(options.EvmKeeper),
|
||||
|
@ -7,9 +7,13 @@ import (
|
||||
"time"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
tmdb "github.com/cometbft/cometbft-db"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp/helpers"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
@ -17,17 +21,15 @@ import (
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmdb "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
bep3types "github.com/kava-labs/kava/x/bep3/types"
|
||||
pricefeedtypes "github.com/kava-labs/kava/x/pricefeed/types"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
bep3types "github.com/0glabs/0g-chain/x/bep3/types"
|
||||
pricefeedtypes "github.com/0glabs/0g-chain/x/pricefeed/types"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
app.SetSDKConfig()
|
||||
chaincfg.SetSDKConfig()
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
@ -50,22 +52,26 @@ func TestAppAnteHandler_AuthorizedMempool(t *testing.T) {
|
||||
|
||||
tApp := app.TestApp{
|
||||
App: *app.NewApp(
|
||||
log.NewNopLogger(),
|
||||
tmdb.NewMemDB(),
|
||||
app.DefaultNodeHome,
|
||||
chaincfg.DefaultNodeHome,
|
||||
nil,
|
||||
encodingConfig,
|
||||
opts,
|
||||
app.NewBaseApp(
|
||||
log.NewNopLogger(),
|
||||
tmdb.NewMemDB(),
|
||||
encodingConfig,
|
||||
baseapp.SetChainID(app.TestChainId),
|
||||
),
|
||||
),
|
||||
}
|
||||
|
||||
chainID := "kavatest_1-1"
|
||||
chainID := app.TestChainId
|
||||
tApp = tApp.InitializeFromGenesisStatesWithTimeAndChainID(
|
||||
time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
chainID,
|
||||
app.NewFundedGenStateWithSameCoins(
|
||||
tApp.AppCodec(),
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 1e9)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(1e9)),
|
||||
testAddresses,
|
||||
),
|
||||
newBep3GenStateMulti(tApp.AppCodec(), deputy),
|
||||
@ -106,18 +112,18 @@ func TestAppAnteHandler_AuthorizedMempool(t *testing.T) {
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
stdTx, err := helpers.GenSignedMockTx(
|
||||
stdTx, err := sims.GenSignedMockTx(
|
||||
rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
encodingConfig.TxConfig,
|
||||
[]sdk.Msg{
|
||||
banktypes.NewMsgSend(
|
||||
tc.address,
|
||||
testAddresses[0],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 1_000_000)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(1_000_000)),
|
||||
),
|
||||
},
|
||||
sdk.NewCoins(), // no fee
|
||||
helpers.DefaultGenTxGas,
|
||||
sims.DefaultGenTxGas,
|
||||
chainID,
|
||||
[]uint64{0},
|
||||
[]uint64{0}, // fixed sequence numbers will cause tests to fail sig verification if the same address is used twice
|
||||
@ -209,7 +215,7 @@ func TestAppAnteHandler_RejectMsgsInAuthz(t *testing.T) {
|
||||
return msg
|
||||
}
|
||||
|
||||
chainID := "kavatest_1-1"
|
||||
chainID := app.TestChainId
|
||||
encodingConfig := app.MakeEncodingConfig()
|
||||
|
||||
testcases := []struct {
|
||||
@ -238,12 +244,12 @@ func TestAppAnteHandler_RejectMsgsInAuthz(t *testing.T) {
|
||||
chainID,
|
||||
)
|
||||
|
||||
stdTx, err := helpers.GenSignedMockTx(
|
||||
stdTx, err := sims.GenSignedMockTx(
|
||||
rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
encodingConfig.TxConfig,
|
||||
[]sdk.Msg{tc.msg},
|
||||
sdk.NewCoins(), // no fee
|
||||
helpers.DefaultGenTxGas,
|
||||
sims.DefaultGenTxGas,
|
||||
chainID,
|
||||
[]uint64{0},
|
||||
[]uint64{0},
|
||||
|
@ -5,13 +5,14 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp/helpers"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/app/ante"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/app/ante"
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
)
|
||||
|
||||
var _ sdk.AnteHandler = (&MockAnteHandler{}).AnteHandle
|
||||
@ -38,18 +39,18 @@ func TestAuthenticatedMempoolDecorator_AnteHandle_NotCheckTx(t *testing.T) {
|
||||
fetcher := mockAddressFetcher(testAddresses[1:]...)
|
||||
|
||||
decorator := ante.NewAuthenticatedMempoolDecorator(fetcher)
|
||||
tx, err := helpers.GenSignedMockTx(
|
||||
tx, err := sims.GenSignedMockTx(
|
||||
rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
txConfig,
|
||||
[]sdk.Msg{
|
||||
banktypes.NewMsgSend(
|
||||
testAddresses[0],
|
||||
testAddresses[1],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100_000_000)),
|
||||
),
|
||||
},
|
||||
sdk.NewCoins(), // no fee
|
||||
helpers.DefaultGenTxGas,
|
||||
sims.DefaultGenTxGas,
|
||||
"testing-chain-id",
|
||||
[]uint64{0},
|
||||
[]uint64{0},
|
||||
@ -73,23 +74,23 @@ func TestAuthenticatedMempoolDecorator_AnteHandle_Pass(t *testing.T) {
|
||||
|
||||
decorator := ante.NewAuthenticatedMempoolDecorator(fetcher)
|
||||
|
||||
tx, err := helpers.GenSignedMockTx(
|
||||
tx, err := sims.GenSignedMockTx(
|
||||
rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
txConfig,
|
||||
[]sdk.Msg{
|
||||
banktypes.NewMsgSend(
|
||||
testAddresses[0],
|
||||
testAddresses[1],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100)),
|
||||
),
|
||||
banktypes.NewMsgSend(
|
||||
testAddresses[2],
|
||||
testAddresses[1],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100)),
|
||||
),
|
||||
},
|
||||
sdk.NewCoins(), // no fee
|
||||
helpers.DefaultGenTxGas,
|
||||
sims.DefaultGenTxGas,
|
||||
"testing-chain-id",
|
||||
[]uint64{0, 123},
|
||||
[]uint64{0, 123},
|
||||
@ -114,18 +115,18 @@ func TestAuthenticatedMempoolDecorator_AnteHandle_Reject(t *testing.T) {
|
||||
|
||||
decorator := ante.NewAuthenticatedMempoolDecorator(fetcher)
|
||||
|
||||
tx, err := helpers.GenSignedMockTx(
|
||||
tx, err := sims.GenSignedMockTx(
|
||||
rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
txConfig,
|
||||
[]sdk.Msg{
|
||||
banktypes.NewMsgSend(
|
||||
testAddresses[0],
|
||||
testAddresses[1],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100)),
|
||||
),
|
||||
},
|
||||
sdk.NewCoins(), // no fee
|
||||
helpers.DefaultGenTxGas,
|
||||
sims.DefaultGenTxGas,
|
||||
"testing-chain-id",
|
||||
[]uint64{0},
|
||||
[]uint64{0},
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp/helpers"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
@ -14,8 +14,9 @@ import (
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/app/ante"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/app/ante"
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
)
|
||||
|
||||
func newMsgGrant(granter sdk.AccAddress, grantee sdk.AccAddress, a authz.Authorization, expiration time.Time) *authz.MsgGrant {
|
||||
@ -58,7 +59,7 @@ func TestAuthzLimiterDecorator(t *testing.T) {
|
||||
banktypes.NewMsgSend(
|
||||
testAddresses[0],
|
||||
testAddresses[1],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100e6)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100e6)),
|
||||
),
|
||||
},
|
||||
checkTx: false,
|
||||
@ -128,7 +129,7 @@ func TestAuthzLimiterDecorator(t *testing.T) {
|
||||
[]sdk.Msg{banktypes.NewMsgSend(
|
||||
testAddresses[0],
|
||||
testAddresses[3],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100e6)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100e6)),
|
||||
)}),
|
||||
},
|
||||
checkTx: false,
|
||||
@ -161,7 +162,7 @@ func TestAuthzLimiterDecorator(t *testing.T) {
|
||||
banktypes.NewMsgSend(
|
||||
testAddresses[0],
|
||||
testAddresses[3],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100e6)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100e6)),
|
||||
),
|
||||
&evmtypes.MsgEthereumTx{},
|
||||
},
|
||||
@ -212,12 +213,12 @@ func TestAuthzLimiterDecorator(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tx, err := helpers.GenSignedMockTx(
|
||||
tx, err := sims.GenSignedMockTx(
|
||||
rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
txConfig,
|
||||
tc.msgs,
|
||||
sdk.NewCoins(),
|
||||
helpers.DefaultGenTxGas,
|
||||
sims.DefaultGenTxGas,
|
||||
"testing-chain-id",
|
||||
[]uint64{0},
|
||||
[]uint64{0},
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp/helpers"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
@ -20,6 +20,11 @@ import (
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cometbft/cometbft/crypto/tmhash"
|
||||
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
tmversion "github.com/cometbft/cometbft/proto/tendermint/version"
|
||||
"github.com/cometbft/cometbft/version"
|
||||
"github.com/evmos/ethermint/crypto/ethsecp256k1"
|
||||
"github.com/evmos/ethermint/ethereum/eip712"
|
||||
"github.com/evmos/ethermint/tests"
|
||||
@ -27,23 +32,17 @@ import (
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
feemarkettypes "github.com/evmos/ethermint/x/feemarket/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
tmversion "github.com/tendermint/tendermint/proto/tendermint/version"
|
||||
"github.com/tendermint/tendermint/version"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
cdptypes "github.com/kava-labs/kava/x/cdp/types"
|
||||
evmutilkeeper "github.com/kava-labs/kava/x/evmutil/keeper"
|
||||
evmutiltestutil "github.com/kava-labs/kava/x/evmutil/testutil"
|
||||
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
|
||||
hardtypes "github.com/kava-labs/kava/x/hard/types"
|
||||
pricefeedtypes "github.com/kava-labs/kava/x/pricefeed/types"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
evmutilkeeper "github.com/0glabs/0g-chain/x/evmutil/keeper"
|
||||
evmutiltestutil "github.com/0glabs/0g-chain/x/evmutil/testutil"
|
||||
evmutiltypes "github.com/0glabs/0g-chain/x/evmutil/types"
|
||||
pricefeedtypes "github.com/0glabs/0g-chain/x/pricefeed/types"
|
||||
)
|
||||
|
||||
const (
|
||||
ChainID = "kavatest_1-1"
|
||||
ChainID = app.TestChainId
|
||||
USDCCoinDenom = "erc20/usdc"
|
||||
USDCCDPType = "erc20-usdc"
|
||||
)
|
||||
@ -138,6 +137,7 @@ func (suite *EIP712TestSuite) createTestEIP712CosmosTxBuilder(
|
||||
func (suite *EIP712TestSuite) SetupTest() {
|
||||
tApp := app.NewTestApp()
|
||||
suite.tApp = tApp
|
||||
|
||||
cdc := tApp.AppCodec()
|
||||
suite.evmutilKeeper = tApp.GetEvmutilKeeper()
|
||||
|
||||
@ -157,7 +157,7 @@ func (suite *EIP712TestSuite) SetupTest() {
|
||||
// Genesis states
|
||||
evmGs := evmtypes.NewGenesisState(
|
||||
evmtypes.NewParams(
|
||||
"akava", // evmDenom
|
||||
chaincfg.EvmDenom, // evmDenom
|
||||
false, // allowedUnprotectedTxs
|
||||
true, // enableCreate
|
||||
true, // enableCall
|
||||
@ -172,47 +172,6 @@ func (suite *EIP712TestSuite) SetupTest() {
|
||||
feemarketGenesis.Params.EnableHeight = 1
|
||||
feemarketGenesis.Params.NoBaseFee = false
|
||||
|
||||
cdpGenState := cdptypes.DefaultGenesisState()
|
||||
cdpGenState.Params.GlobalDebtLimit = sdk.NewInt64Coin("usdx", 53000000000000)
|
||||
cdpGenState.Params.CollateralParams = cdptypes.CollateralParams{
|
||||
{
|
||||
Denom: USDCCoinDenom,
|
||||
Type: USDCCDPType,
|
||||
LiquidationRatio: sdk.MustNewDecFromStr("1.01"),
|
||||
DebtLimit: sdk.NewInt64Coin("usdx", 500000000000),
|
||||
StabilityFee: sdk.OneDec(),
|
||||
AuctionSize: sdkmath.NewIntFromUint64(10000000000),
|
||||
LiquidationPenalty: sdk.MustNewDecFromStr("0.05"),
|
||||
CheckCollateralizationIndexCount: sdkmath.NewInt(10),
|
||||
KeeperRewardPercentage: sdk.MustNewDecFromStr("0.01"),
|
||||
SpotMarketID: "usdc:usd",
|
||||
LiquidationMarketID: "usdc:usd:30",
|
||||
ConversionFactor: sdkmath.NewInt(18),
|
||||
},
|
||||
}
|
||||
|
||||
hardGenState := hardtypes.DefaultGenesisState()
|
||||
hardGenState.Params.MoneyMarkets = []hardtypes.MoneyMarket{
|
||||
{
|
||||
Denom: "usdx",
|
||||
BorrowLimit: hardtypes.BorrowLimit{
|
||||
HasMaxLimit: true,
|
||||
MaximumLimit: sdk.MustNewDecFromStr("100000000000"),
|
||||
LoanToValue: sdk.MustNewDecFromStr("1"),
|
||||
},
|
||||
SpotMarketID: "usdx:usd",
|
||||
ConversionFactor: sdkmath.NewInt(1_000_000),
|
||||
InterestRateModel: hardtypes.InterestRateModel{
|
||||
BaseRateAPY: sdk.MustNewDecFromStr("0.05"),
|
||||
BaseMultiplier: sdk.MustNewDecFromStr("2"),
|
||||
Kink: sdk.MustNewDecFromStr("0.8"),
|
||||
JumpMultiplier: sdk.MustNewDecFromStr("10"),
|
||||
},
|
||||
ReserveFactor: sdk.MustNewDecFromStr("0.05"),
|
||||
KeeperRewardPercentage: sdk.ZeroDec(),
|
||||
},
|
||||
}
|
||||
|
||||
pricefeedGenState := pricefeedtypes.DefaultGenesisState()
|
||||
pricefeedGenState.Params.Markets = []pricefeedtypes.Market{
|
||||
{
|
||||
@ -261,15 +220,13 @@ func (suite *EIP712TestSuite) SetupTest() {
|
||||
genState := app.GenesisState{
|
||||
evmtypes.ModuleName: cdc.MustMarshalJSON(evmGs),
|
||||
feemarkettypes.ModuleName: cdc.MustMarshalJSON(feemarketGenesis),
|
||||
cdptypes.ModuleName: cdc.MustMarshalJSON(&cdpGenState),
|
||||
hardtypes.ModuleName: cdc.MustMarshalJSON(&hardGenState),
|
||||
pricefeedtypes.ModuleName: cdc.MustMarshalJSON(&pricefeedGenState),
|
||||
}
|
||||
|
||||
// funds our test accounts with some ukava
|
||||
// funds our test accounts with some gas denom
|
||||
coinsGenState := app.NewFundedGenStateWithSameCoins(
|
||||
tApp.AppCodec(),
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 1e9)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(1e9)),
|
||||
[]sdk.AccAddress{suite.testAddr, suite.testAddr2},
|
||||
)
|
||||
|
||||
@ -334,6 +291,11 @@ func (suite *EIP712TestSuite) SetupTest() {
|
||||
)
|
||||
suite.usdcEVMAddr = pair.GetAddress()
|
||||
|
||||
// update consensus params
|
||||
cParams := tApp.GetConsensusParams(suite.ctx)
|
||||
cParams.Block.MaxGas = sims.DefaultGenTxGas * 20
|
||||
tApp.StoreConsensusParams(suite.ctx, cParams)
|
||||
|
||||
// Add a contract to evmutil conversion pair
|
||||
evmutilParams := suite.evmutilKeeper.GetParams(suite.ctx)
|
||||
evmutilParams.EnabledConversionPairs =
|
||||
@ -351,45 +313,17 @@ func (suite *EIP712TestSuite) SetupTest() {
|
||||
params := evmKeeper.GetParams(suite.ctx)
|
||||
params.EIP712AllowedMsgs = []evmtypes.EIP712AllowedMsg{
|
||||
{
|
||||
MsgTypeUrl: "/kava.evmutil.v1beta1.MsgConvertERC20ToCoin",
|
||||
MsgTypeUrl: "/zgc.evmutil.v1beta1.MsgConvertERC20ToCoin",
|
||||
MsgValueTypeName: "MsgValueEVMConvertERC20ToCoin",
|
||||
ValueTypes: []evmtypes.EIP712MsgAttrType{
|
||||
{Name: "initiator", Type: "string"},
|
||||
{Name: "receiver", Type: "string"},
|
||||
{Name: "kava_erc20_address", Type: "string"},
|
||||
{Name: "zgchain_erc20_address", Type: "string"},
|
||||
{Name: "amount", Type: "string"},
|
||||
},
|
||||
},
|
||||
{
|
||||
MsgTypeUrl: "/kava.cdp.v1beta1.MsgCreateCDP",
|
||||
MsgValueTypeName: "MsgValueCDPCreate",
|
||||
ValueTypes: []evmtypes.EIP712MsgAttrType{
|
||||
{Name: "sender", Type: "string"},
|
||||
{Name: "collateral", Type: "Coin"},
|
||||
{Name: "principal", Type: "Coin"},
|
||||
{Name: "collateral_type", Type: "string"},
|
||||
},
|
||||
},
|
||||
{
|
||||
MsgTypeUrl: "/kava.cdp.v1beta1.MsgDeposit",
|
||||
MsgValueTypeName: "MsgValueCDPDeposit",
|
||||
ValueTypes: []evmtypes.EIP712MsgAttrType{
|
||||
{Name: "depositor", Type: "string"},
|
||||
{Name: "owner", Type: "string"},
|
||||
{Name: "collateral", Type: "Coin"},
|
||||
{Name: "collateral_type", Type: "string"},
|
||||
},
|
||||
},
|
||||
{
|
||||
MsgTypeUrl: "/kava.hard.v1beta1.MsgDeposit",
|
||||
MsgValueTypeName: "MsgValueHardDeposit",
|
||||
ValueTypes: []evmtypes.EIP712MsgAttrType{
|
||||
{Name: "depositor", Type: "string"},
|
||||
{Name: "amount", Type: "Coin[]"},
|
||||
},
|
||||
},
|
||||
{
|
||||
MsgTypeUrl: "/kava.evmutil.v1beta1.MsgConvertCoinToERC20",
|
||||
MsgTypeUrl: "/zgc.evmutil.v1beta1.MsgConvertCoinToERC20",
|
||||
MsgValueTypeName: "MsgValueEVMConvertCoinToERC20",
|
||||
ValueTypes: []evmtypes.EIP712MsgAttrType{
|
||||
{Name: "initiator", Type: "string"},
|
||||
@ -397,23 +331,6 @@ func (suite *EIP712TestSuite) SetupTest() {
|
||||
{Name: "amount", Type: "Coin"},
|
||||
},
|
||||
},
|
||||
{
|
||||
MsgTypeUrl: "/kava.cdp.v1beta1.MsgRepayDebt",
|
||||
MsgValueTypeName: "MsgValueCDPRepayDebt",
|
||||
ValueTypes: []evmtypes.EIP712MsgAttrType{
|
||||
{Name: "sender", Type: "string"},
|
||||
{Name: "collateral_type", Type: "string"},
|
||||
{Name: "payment", Type: "Coin"},
|
||||
},
|
||||
},
|
||||
{
|
||||
MsgTypeUrl: "/kava.hard.v1beta1.MsgWithdraw",
|
||||
MsgValueTypeName: "MsgValueHardWithdraw",
|
||||
ValueTypes: []evmtypes.EIP712MsgAttrType{
|
||||
{Name: "depositor", Type: "string"},
|
||||
{Name: "amount", Type: "Coin[]"},
|
||||
},
|
||||
},
|
||||
}
|
||||
evmKeeper.SetParams(suite.ctx, params)
|
||||
|
||||
@ -459,7 +376,7 @@ func (suite *EIP712TestSuite) deployUSDCERC20(app app.TestApp, ctx sdk.Context)
|
||||
suite.tApp.FundModuleAccount(
|
||||
suite.ctx,
|
||||
evmutiltypes.ModuleName,
|
||||
sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(0))),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(0)),
|
||||
)
|
||||
|
||||
contractAddr, err := suite.evmutilKeeper.DeployTestMintableERC20Contract(suite.ctx, "USDC", "USDC", uint8(18))
|
||||
@ -481,40 +398,43 @@ func (suite *EIP712TestSuite) TestEIP712Tx() {
|
||||
failCheckTx bool
|
||||
errMsg string
|
||||
}{
|
||||
// TODO: need fix
|
||||
// {
|
||||
// name: "processes deposit eip712 messages successfully",
|
||||
// usdcDepositAmt: 100,
|
||||
// usdxToMintAmt: 99,
|
||||
// },
|
||||
{
|
||||
name: "processes deposit eip712 messages successfully",
|
||||
usdcDepositAmt: 100,
|
||||
usdxToMintAmt: 99,
|
||||
},
|
||||
{
|
||||
name: "fails when convertion more erc20 usdc than balance",
|
||||
name: "fails when conversion more erc20 usdc than balance",
|
||||
usdcDepositAmt: 51_000,
|
||||
usdxToMintAmt: 100,
|
||||
errMsg: "transfer amount exceeds balance",
|
||||
},
|
||||
{
|
||||
name: "fails when minting more usdx than allowed",
|
||||
usdcDepositAmt: 100,
|
||||
usdxToMintAmt: 100,
|
||||
errMsg: "proposed collateral ratio is below liquidation ratio",
|
||||
},
|
||||
{
|
||||
name: "fails when trying to convert usdc for another address",
|
||||
usdcDepositAmt: 100,
|
||||
usdxToMintAmt: 90,
|
||||
errMsg: "unauthorized",
|
||||
failCheckTx: true,
|
||||
updateMsgs: func(msgs []sdk.Msg) []sdk.Msg {
|
||||
convertMsg := evmutiltypes.NewMsgConvertERC20ToCoin(
|
||||
suite.testEVMAddr2,
|
||||
suite.testAddr,
|
||||
suite.usdcEVMAddr,
|
||||
suite.getEVMAmount(100),
|
||||
)
|
||||
msgs[0] = &convertMsg
|
||||
return msgs
|
||||
},
|
||||
},
|
||||
// TODO: need fix
|
||||
// {
|
||||
// name: "fails when minting more usdx than allowed",
|
||||
// usdcDepositAmt: 100,
|
||||
// usdxToMintAmt: 100,
|
||||
// errMsg: "proposed collateral ratio is below liquidation ratio",
|
||||
// },
|
||||
// TODO: need fix
|
||||
// {
|
||||
// name: "fails when trying to convert usdc for another address",
|
||||
// usdcDepositAmt: 100,
|
||||
// usdxToMintAmt: 90,
|
||||
// errMsg: "unauthorized",
|
||||
// failCheckTx: true,
|
||||
// updateMsgs: func(msgs []sdk.Msg) []sdk.Msg {
|
||||
// convertMsg := evmutiltypes.NewMsgConvertERC20ToCoin(
|
||||
// suite.testEVMAddr2,
|
||||
// suite.testAddr,
|
||||
// suite.usdcEVMAddr,
|
||||
// suite.getEVMAmount(100),
|
||||
// )
|
||||
// msgs[0] = &convertMsg
|
||||
// return msgs
|
||||
// },
|
||||
// },
|
||||
{
|
||||
name: "fails when trying to convert erc20 for non-whitelisted contract",
|
||||
usdcDepositAmt: 100,
|
||||
@ -541,7 +461,7 @@ func (suite *EIP712TestSuite) TestEIP712Tx() {
|
||||
var option *codectypes.Any
|
||||
option, _ = codectypes.NewAnyWithValue(ðerminttypes.ExtensionOptionsWeb3Tx{
|
||||
FeePayer: suite.testAddr.String(),
|
||||
TypedDataChainID: 1,
|
||||
TypedDataChainID: 2221,
|
||||
FeePayerSig: []byte("sig"),
|
||||
})
|
||||
builder, _ := txBuilder.(authtx.ExtensionOptionsTxBuilder)
|
||||
@ -556,7 +476,7 @@ func (suite *EIP712TestSuite) TestEIP712Tx() {
|
||||
errMsg: "insufficient funds",
|
||||
updateTx: func(txBuilder client.TxBuilder, msgs []sdk.Msg) client.TxBuilder {
|
||||
bk := suite.tApp.GetBankKeeper()
|
||||
gasCoins := bk.GetBalance(suite.ctx, suite.testAddr, "ukava")
|
||||
gasCoins := bk.GetBalance(suite.ctx, suite.testAddr, chaincfg.GasDenom)
|
||||
suite.tApp.GetBankKeeper().SendCoins(suite.ctx, suite.testAddr, suite.testAddr2, sdk.NewCoins(gasCoins))
|
||||
return txBuilder
|
||||
},
|
||||
@ -568,9 +488,9 @@ func (suite *EIP712TestSuite) TestEIP712Tx() {
|
||||
failCheckTx: true,
|
||||
errMsg: "invalid chain-id",
|
||||
updateTx: func(txBuilder client.TxBuilder, msgs []sdk.Msg) client.TxBuilder {
|
||||
gasAmt := sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(20)))
|
||||
gasAmt := sdk.NewCoins(chaincfg.MakeCoinForGasDenom(20))
|
||||
return suite.createTestEIP712CosmosTxBuilder(
|
||||
suite.testAddr, suite.testPrivKey, "kavatest_12-1", uint64(helpers.DefaultGenTxGas*10), gasAmt, msgs,
|
||||
suite.testAddr, suite.testPrivKey, "kavatest_12-1", uint64(sims.DefaultGenTxGas*10), gasAmt, msgs,
|
||||
)
|
||||
},
|
||||
},
|
||||
@ -581,9 +501,9 @@ func (suite *EIP712TestSuite) TestEIP712Tx() {
|
||||
failCheckTx: true,
|
||||
errMsg: "invalid pubkey",
|
||||
updateTx: func(txBuilder client.TxBuilder, msgs []sdk.Msg) client.TxBuilder {
|
||||
gasAmt := sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(20)))
|
||||
gasAmt := sdk.NewCoins(chaincfg.MakeCoinForGasDenom(20))
|
||||
return suite.createTestEIP712CosmosTxBuilder(
|
||||
suite.testAddr2, suite.testPrivKey2, ChainID, uint64(helpers.DefaultGenTxGas*10), gasAmt, msgs,
|
||||
suite.testAddr2, suite.testPrivKey2, ChainID, uint64(sims.DefaultGenTxGas*10), gasAmt, msgs,
|
||||
)
|
||||
},
|
||||
},
|
||||
@ -601,29 +521,17 @@ func (suite *EIP712TestSuite) TestEIP712Tx() {
|
||||
suite.usdcEVMAddr,
|
||||
usdcAmt,
|
||||
)
|
||||
usdxAmt := sdkmath.NewInt(1_000_000).Mul(sdkmath.NewInt(tc.usdxToMintAmt))
|
||||
mintMsg := cdptypes.NewMsgCreateCDP(
|
||||
suite.testAddr,
|
||||
sdk.NewCoin(USDCCoinDenom, usdcAmt),
|
||||
sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt),
|
||||
USDCCDPType,
|
||||
)
|
||||
lendMsg := hardtypes.NewMsgDeposit(
|
||||
suite.testAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt)),
|
||||
)
|
||||
|
||||
msgs := []sdk.Msg{
|
||||
&convertMsg,
|
||||
&mintMsg,
|
||||
&lendMsg,
|
||||
}
|
||||
if tc.updateMsgs != nil {
|
||||
msgs = tc.updateMsgs(msgs)
|
||||
}
|
||||
|
||||
gasAmt := sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(20)))
|
||||
gasAmt := sdk.NewCoins(chaincfg.MakeCoinForGasDenom(20))
|
||||
txBuilder := suite.createTestEIP712CosmosTxBuilder(
|
||||
suite.testAddr, suite.testPrivKey, ChainID, uint64(helpers.DefaultGenTxGas*10), gasAmt, msgs,
|
||||
suite.testAddr, suite.testPrivKey, ChainID, uint64(sims.DefaultGenTxGas*10), gasAmt, msgs,
|
||||
)
|
||||
if tc.updateTx != nil {
|
||||
txBuilder = tc.updateTx(txBuilder, msgs)
|
||||
@ -659,17 +567,17 @@ func (suite *EIP712TestSuite) TestEIP712Tx() {
|
||||
suite.Require().Equal(sdk.ZeroInt(), amt.Amount)
|
||||
|
||||
// validate cdp
|
||||
cdp, found := suite.tApp.GetCDPKeeper().GetCdpByOwnerAndCollateralType(suite.ctx, suite.testAddr, USDCCDPType)
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(suite.testAddr, cdp.Owner)
|
||||
suite.Require().Equal(sdk.NewCoin(USDCCoinDenom, suite.getEVMAmount(100)), cdp.Collateral)
|
||||
suite.Require().Equal(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000)), cdp.Principal)
|
||||
// cdp, found := suite.tApp.GetCDPKeeper().GetCdpByOwnerAndCollateralType(suite.ctx, suite.testAddr, USDCCDPType)
|
||||
// suite.Require().True(found)
|
||||
// suite.Require().Equal(suite.testAddr, cdp.Owner)
|
||||
// suite.Require().Equal(sdk.NewCoin(USDCCoinDenom, suite.getEVMAmount(100)), cdp.Collateral)
|
||||
// suite.Require().Equal(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000)), cdp.Principal)
|
||||
|
||||
// validate hard
|
||||
hardDeposit, found := suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(suite.testAddr, hardDeposit.Depositor)
|
||||
suite.Require().Equal(sdk.NewCoins(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000))), hardDeposit.Amount)
|
||||
// hardDeposit, found := suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
|
||||
// suite.Require().True(found)
|
||||
// suite.Require().Equal(suite.testAddr, hardDeposit.Depositor)
|
||||
// suite.Require().Equal(sdk.NewCoins(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000))), hardDeposit.Amount)
|
||||
} else {
|
||||
suite.Require().NotEqual(resDeliverTx.Code, uint32(0), resCheckTx.Log)
|
||||
suite.Require().Contains(resDeliverTx.Log, tc.errMsg)
|
||||
@ -689,27 +597,15 @@ func (suite *EIP712TestSuite) TestEIP712Tx_DepositAndWithdraw() {
|
||||
suite.usdcEVMAddr,
|
||||
usdcAmt,
|
||||
)
|
||||
usdxAmt := sdkmath.NewInt(1_000_000).Mul(sdkmath.NewInt(99))
|
||||
mintMsg := cdptypes.NewMsgCreateCDP(
|
||||
suite.testAddr,
|
||||
sdk.NewCoin(USDCCoinDenom, usdcAmt),
|
||||
sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt),
|
||||
USDCCDPType,
|
||||
)
|
||||
lendMsg := hardtypes.NewMsgDeposit(
|
||||
suite.testAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt)),
|
||||
)
|
||||
|
||||
depositMsgs := []sdk.Msg{
|
||||
&convertMsg,
|
||||
&mintMsg,
|
||||
&lendMsg,
|
||||
}
|
||||
|
||||
// deliver deposit msg
|
||||
gasAmt := sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(20)))
|
||||
gasAmt := sdk.NewCoins(chaincfg.MakeCoinForGasDenom(20))
|
||||
txBuilder := suite.createTestEIP712CosmosTxBuilder(
|
||||
suite.testAddr, suite.testPrivKey, ChainID, uint64(helpers.DefaultGenTxGas*10), gasAmt, depositMsgs,
|
||||
suite.testAddr, suite.testPrivKey, ChainID, uint64(sims.DefaultGenTxGas*10), gasAmt, depositMsgs,
|
||||
)
|
||||
txBytes, err := encodingConfig.TxConfig.TxEncoder()(txBuilder.GetTx())
|
||||
suite.Require().NoError(err)
|
||||
@ -721,10 +617,10 @@ func (suite *EIP712TestSuite) TestEIP712Tx_DepositAndWithdraw() {
|
||||
suite.Require().Equal(resDeliverTx.Code, uint32(0), resDeliverTx.Log)
|
||||
|
||||
// validate hard
|
||||
hardDeposit, found := suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(suite.testAddr, hardDeposit.Depositor)
|
||||
suite.Require().Equal(sdk.NewCoins(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000))), hardDeposit.Amount)
|
||||
// hardDeposit, found := suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
|
||||
// suite.Require().True(found)
|
||||
// suite.Require().Equal(suite.testAddr, hardDeposit.Depositor)
|
||||
// suite.Require().Equal(sdk.NewCoins(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000))), hardDeposit.Amount)
|
||||
|
||||
// validate erc20 balance
|
||||
coinBal, err := suite.evmutilKeeper.QueryERC20BalanceOf(suite.ctx, suite.usdcEVMAddr, suite.testEVMAddr)
|
||||
@ -737,24 +633,13 @@ func (suite *EIP712TestSuite) TestEIP712Tx_DepositAndWithdraw() {
|
||||
suite.testEVMAddr.String(),
|
||||
sdk.NewCoin(USDCCoinDenom, usdcAmt),
|
||||
)
|
||||
cdpWithdrawMsg := cdptypes.NewMsgRepayDebt(
|
||||
suite.testAddr,
|
||||
USDCCDPType,
|
||||
sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt),
|
||||
)
|
||||
hardWithdrawMsg := hardtypes.NewMsgWithdraw(
|
||||
suite.testAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt)),
|
||||
)
|
||||
withdrawMsgs := []sdk.Msg{
|
||||
&hardWithdrawMsg,
|
||||
&cdpWithdrawMsg,
|
||||
&withdrawConvertMsg,
|
||||
}
|
||||
|
||||
// deliver withdraw msg
|
||||
txBuilder = suite.createTestEIP712CosmosTxBuilder(
|
||||
suite.testAddr, suite.testPrivKey, ChainID, uint64(helpers.DefaultGenTxGas*10), gasAmt, withdrawMsgs,
|
||||
suite.testAddr, suite.testPrivKey, ChainID, uint64(sims.DefaultGenTxGas*10), gasAmt, withdrawMsgs,
|
||||
)
|
||||
txBytes, err = encodingConfig.TxConfig.TxEncoder()(txBuilder.GetTx())
|
||||
suite.Require().NoError(err)
|
||||
@ -766,10 +651,10 @@ func (suite *EIP712TestSuite) TestEIP712Tx_DepositAndWithdraw() {
|
||||
suite.Require().Equal(resDeliverTx.Code, uint32(0), resDeliverTx.Log)
|
||||
|
||||
// validate hard & cdp should be repayed
|
||||
_, found = suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
|
||||
suite.Require().False(found)
|
||||
_, found = suite.tApp.GetCDPKeeper().GetCdpByOwnerAndCollateralType(suite.ctx, suite.testAddr, USDCCDPType)
|
||||
suite.Require().False(found)
|
||||
// _, found = suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
|
||||
// suite.Require().False(found)
|
||||
// _, found = suite.tApp.GetCDPKeeper().GetCdpByOwnerAndCollateralType(suite.ctx, suite.testAddr, USDCCDPType)
|
||||
// suite.Require().False(found)
|
||||
|
||||
// validate user cosmos erc20/usd balance
|
||||
bk := suite.tApp.GetBankKeeper()
|
||||
|
@ -4,15 +4,16 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
tmtime "github.com/cometbft/cometbft/types/time"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/app/ante"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/app/ante"
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
)
|
||||
|
||||
func mustParseDecCoins(value string) sdk.DecCoins {
|
||||
@ -30,7 +31,7 @@ func TestEvmMinGasFilter(t *testing.T) {
|
||||
|
||||
ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now()})
|
||||
tApp.GetEvmKeeper().SetParams(ctx, evmtypes.Params{
|
||||
EvmDenom: "akava",
|
||||
EvmDenom: chaincfg.EvmDenom,
|
||||
})
|
||||
|
||||
testCases := []struct {
|
||||
@ -44,29 +45,29 @@ func TestEvmMinGasFilter(t *testing.T) {
|
||||
mustParseDecCoins(""),
|
||||
},
|
||||
{
|
||||
"zero ukava gas price",
|
||||
mustParseDecCoins("0ukava"),
|
||||
mustParseDecCoins("0ukava"),
|
||||
"zero ua0gi gas price",
|
||||
mustParseDecCoins("0ua0gi"),
|
||||
mustParseDecCoins("0ua0gi"),
|
||||
},
|
||||
{
|
||||
"non-zero ukava gas price",
|
||||
mustParseDecCoins("0.001ukava"),
|
||||
mustParseDecCoins("0.001ukava"),
|
||||
"non-zero ua0gi gas price",
|
||||
mustParseDecCoins("0.001ua0gi"),
|
||||
mustParseDecCoins("0.001ua0gi"),
|
||||
},
|
||||
{
|
||||
"zero ukava gas price, min akava price",
|
||||
mustParseDecCoins("0ukava;100000akava"),
|
||||
mustParseDecCoins("0ukava"), // akava is removed
|
||||
"zero ua0gi gas price, min neuron price",
|
||||
mustParseDecCoins("0ua0gi;100000neuron"),
|
||||
mustParseDecCoins("0ua0gi"), // neuron is removed
|
||||
},
|
||||
{
|
||||
"zero ukava gas price, min akava price, other token",
|
||||
mustParseDecCoins("0ukava;100000akava;0.001other"),
|
||||
mustParseDecCoins("0ukava;0.001other"), // akava is removed
|
||||
"zero ua0gi gas price, min neuron price, other token",
|
||||
mustParseDecCoins("0ua0gi;100000neuron;0.001other"),
|
||||
mustParseDecCoins("0ua0gi;0.001other"), // neuron is removed
|
||||
},
|
||||
{
|
||||
"non-zero ukava gas price, min akava price",
|
||||
mustParseDecCoins("0.25ukava;100000akava;0.001other"),
|
||||
mustParseDecCoins("0.25ukava;0.001other"), // akava is removed
|
||||
"non-zero ua0gi gas price, min neuron price",
|
||||
mustParseDecCoins("0.25ua0gi;100000neuron;0.001other"),
|
||||
mustParseDecCoins("0.25ua0gi;0.001other"), // neuron is removed
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
)
|
||||
|
||||
var _ sdk.AnteDecorator = VestingAccountDecorator{}
|
||||
@ -17,9 +16,9 @@ type VestingAccountDecorator struct {
|
||||
func NewVestingAccountDecorator() VestingAccountDecorator {
|
||||
return VestingAccountDecorator{
|
||||
disabledMsgTypeUrls: []string{
|
||||
sdk.MsgTypeURL(&vesting.MsgCreateVestingAccount{}),
|
||||
sdk.MsgTypeURL(&vesting.MsgCreatePermanentLockedAccount{}),
|
||||
sdk.MsgTypeURL(&vesting.MsgCreatePeriodicVestingAccount{}),
|
||||
// sdk.MsgTypeURL(&vesting.MsgCreateVestingAccount{}),
|
||||
// sdk.MsgTypeURL(&vesting.MsgCreatePermanentLockedAccount{}),
|
||||
// sdk.MsgTypeURL(&vesting.MsgCreatePeriodicVestingAccount{}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,14 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp/helpers"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/app/ante"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/app/ante"
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
)
|
||||
|
||||
func TestVestingMempoolDecorator_MsgCreateVestingAccount_Unauthorized(t *testing.T) {
|
||||
@ -33,7 +34,7 @@ func TestVestingMempoolDecorator_MsgCreateVestingAccount_Unauthorized(t *testing
|
||||
"MsgCreateVestingAccount",
|
||||
vesting.NewMsgCreateVestingAccount(
|
||||
testAddresses[0], testAddresses[1],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100)),
|
||||
time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC).Unix(),
|
||||
false,
|
||||
),
|
||||
@ -44,7 +45,7 @@ func TestVestingMempoolDecorator_MsgCreateVestingAccount_Unauthorized(t *testing
|
||||
"MsgCreateVestingAccount",
|
||||
vesting.NewMsgCreatePermanentLockedAccount(
|
||||
testAddresses[0], testAddresses[1],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100)),
|
||||
),
|
||||
true,
|
||||
"MsgTypeURL /cosmos.vesting.v1beta1.MsgCreatePermanentLockedAccount not supported",
|
||||
@ -63,7 +64,7 @@ func TestVestingMempoolDecorator_MsgCreateVestingAccount_Unauthorized(t *testing
|
||||
"other messages not affected",
|
||||
banktypes.NewMsgSend(
|
||||
testAddresses[0], testAddresses[1],
|
||||
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
|
||||
sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100)),
|
||||
),
|
||||
false,
|
||||
"",
|
||||
@ -72,14 +73,14 @@ func TestVestingMempoolDecorator_MsgCreateVestingAccount_Unauthorized(t *testing
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tx, err := helpers.GenSignedMockTx(
|
||||
tx, err := sims.GenSignedMockTx(
|
||||
rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
txConfig,
|
||||
[]sdk.Msg{
|
||||
tt.msg,
|
||||
},
|
||||
sdk.NewCoins(),
|
||||
helpers.DefaultGenTxGas,
|
||||
sims.DefaultGenTxGas,
|
||||
"testing-chain-id",
|
||||
[]uint64{0},
|
||||
[]uint64{0},
|
||||
|
769
app/app.go
769
app/app.go
File diff suppressed because it is too large
Load Diff
@ -8,35 +8,54 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
db "github.com/cometbft/cometbft-db"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine"
|
||||
ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint"
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
db "github.com/tendermint/tm-db"
|
||||
)
|
||||
|
||||
func TestNewApp(t *testing.T) {
|
||||
SetSDKConfig()
|
||||
chaincfg.SetSDKConfig()
|
||||
NewApp(
|
||||
log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
|
||||
db.NewMemDB(),
|
||||
DefaultNodeHome,
|
||||
chaincfg.DefaultNodeHome,
|
||||
nil,
|
||||
MakeEncodingConfig(),
|
||||
DefaultOptions,
|
||||
NewBaseApp(
|
||||
log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
|
||||
db.NewMemDB(),
|
||||
MakeEncodingConfig(),
|
||||
baseapp.SetChainID(TestChainId),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func TestExport(t *testing.T) {
|
||||
SetSDKConfig()
|
||||
chaincfg.SetSDKConfig()
|
||||
db := db.NewMemDB()
|
||||
app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, DefaultNodeHome, nil, MakeEncodingConfig(), DefaultOptions)
|
||||
app := NewApp(
|
||||
chaincfg.DefaultNodeHome,
|
||||
nil,
|
||||
MakeEncodingConfig(),
|
||||
DefaultOptions,
|
||||
NewBaseApp(
|
||||
log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
|
||||
db,
|
||||
MakeEncodingConfig(),
|
||||
baseapp.SetChainID(TestChainId),
|
||||
),
|
||||
)
|
||||
|
||||
genesisState := GenesisStateWithSingleValidator(&TestApp{App: *app}, NewDefaultGenesisState())
|
||||
|
||||
@ -45,21 +64,23 @@ func TestExport(t *testing.T) {
|
||||
|
||||
initRequest := abci.RequestInitChain{
|
||||
Time: time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
ChainId: "kavatest_1-1",
|
||||
ChainId: TestChainId,
|
||||
InitialHeight: 1,
|
||||
ConsensusParams: tmtypes.TM2PB.ConsensusParams(tmtypes.DefaultConsensusParams()),
|
||||
ConsensusParams: sims.DefaultConsensusParams,
|
||||
Validators: nil,
|
||||
AppStateBytes: stateBytes,
|
||||
}
|
||||
app.InitChain(initRequest)
|
||||
app.Commit()
|
||||
|
||||
exportedApp, err := app.ExportAppStateAndValidators(false, []string{})
|
||||
exportedApp, err := app.ExportAppStateAndValidators(false, []string{}, []string{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assume each module is exported correctly, so only check modules in genesis are present in export
|
||||
initialModules, err := unmarshalJSONKeys(initRequest.AppStateBytes)
|
||||
require.NoError(t, err)
|
||||
// note ibctm is only registered in the BasicManager and not module manager so can be ignored
|
||||
initialModules = removeIbcTmModule(initialModules)
|
||||
exportedModules, err := unmarshalJSONKeys(exportedApp.AppState)
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, initialModules, exportedModules)
|
||||
@ -143,3 +164,13 @@ func unmarshalJSONKeys(jsonBytes []byte) ([]string, error) {
|
||||
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func removeIbcTmModule(modules []string) []string {
|
||||
var result []string
|
||||
for _, str := range modules {
|
||||
if str != ibctm.ModuleName && str != solomachine.ModuleName {
|
||||
result = append(result, str)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
package app
|
||||
|
||||
import sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
const (
|
||||
// Bech32MainPrefix defines the Bech32 prefix for account addresses
|
||||
Bech32MainPrefix = "kava"
|
||||
// Bech32PrefixAccPub defines the Bech32 prefix of an account's public key
|
||||
Bech32PrefixAccPub = Bech32MainPrefix + "pub"
|
||||
// Bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address
|
||||
Bech32PrefixValAddr = Bech32MainPrefix + "val" + "oper"
|
||||
// Bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key
|
||||
Bech32PrefixValPub = Bech32MainPrefix + "val" + "oper" + "pub"
|
||||
// Bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address
|
||||
Bech32PrefixConsAddr = Bech32MainPrefix + "val" + "cons"
|
||||
// Bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key
|
||||
Bech32PrefixConsPub = Bech32MainPrefix + "val" + "cons" + "pub"
|
||||
|
||||
Bip44CoinType = 459 // see https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
||||
)
|
||||
|
||||
// SetSDKConfig configures the global config with kava app specific parameters.
|
||||
// It does not seal the config to allow modification in tests.
|
||||
func SetSDKConfig() *sdk.Config {
|
||||
config := sdk.GetConfig()
|
||||
SetBech32AddressPrefixes(config)
|
||||
SetBip44CoinType(config)
|
||||
return config
|
||||
}
|
||||
|
||||
// SetBech32AddressPrefixes sets the global prefix to be used when serializing addresses to bech32 strings.
|
||||
func SetBech32AddressPrefixes(config *sdk.Config) {
|
||||
config.SetBech32PrefixForAccount(Bech32MainPrefix, Bech32PrefixAccPub)
|
||||
config.SetBech32PrefixForValidator(Bech32PrefixValAddr, Bech32PrefixValPub)
|
||||
config.SetBech32PrefixForConsensusNode(Bech32PrefixConsAddr, Bech32PrefixConsPub)
|
||||
}
|
||||
|
||||
// SetBip44CoinType sets the global coin type to be used in hierarchical deterministic wallets.
|
||||
func SetBip44CoinType(config *sdk.Config) {
|
||||
config.SetCoinType(Bip44CoinType)
|
||||
}
|
@ -3,7 +3,7 @@ package app
|
||||
import (
|
||||
enccodec "github.com/evmos/ethermint/encoding/codec"
|
||||
|
||||
"github.com/kava-labs/kava/app/params"
|
||||
"github.com/0glabs/0g-chain/app/params"
|
||||
)
|
||||
|
||||
// MakeEncodingConfig creates an EncodingConfig and registers the app's types on it.
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
// ExportAppStateAndValidators export the state of the app for a genesis file
|
||||
func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []string,
|
||||
func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []string, modulesToExport []string,
|
||||
) (servertypes.ExportedApp, error) {
|
||||
// as if they could withdraw from the start of the next block
|
||||
// block time is not available and defaults to Jan 1st, 0001
|
||||
@ -26,7 +26,7 @@ func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []
|
||||
app.prepForZeroHeightGenesis(ctx, jailWhiteList)
|
||||
}
|
||||
|
||||
genState := app.mm.ExportGenesis(ctx, app.appCodec)
|
||||
genState := app.mm.ExportGenesisForModules(ctx, app.appCodec, modulesToExport)
|
||||
newAppState, err := json.MarshalIndent(genState, "", " ")
|
||||
if err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
@ -42,7 +42,7 @@ func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []
|
||||
|
||||
// prepare for fresh start at zero height
|
||||
// NOTE zero height genesis is a temporary feature which will be deprecated
|
||||
// in favour of export at a block height
|
||||
// in favour of export at a block height
|
||||
func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string) {
|
||||
applyWhiteList := false
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
Package params defines the simulation parameters for the Kava app.
|
||||
Package params defines the simulation parameters for the 0gChain app.
|
||||
|
||||
It contains the default weights used for each transaction used on the module's
|
||||
simulation. These weights define the chance for a transaction to be simulated at
|
||||
any gived operation.
|
||||
any given operation.
|
||||
|
||||
You can repace the default values for the weights by providing a params.json
|
||||
You can replace the default values for the weights by providing a params.json
|
||||
file with the weights defined for each of the transaction operations:
|
||||
|
||||
{
|
||||
|
735
app/priority_nonce.go
Normal file
735
app/priority_nonce.go
Normal file
@ -0,0 +1,735 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/huandu/skiplist"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
const MAX_TXS_PRE_SENDER_IN_MEMPOOL int = 48
|
||||
|
||||
var (
|
||||
_ mempool.Mempool = (*PriorityNonceMempool)(nil)
|
||||
_ mempool.Iterator = (*PriorityNonceIterator)(nil)
|
||||
|
||||
errMempoolTxGasPriceTooLow = errors.New("gas price is too low")
|
||||
errMempoolTooManyTxs = errors.New("tx sender has too many txs in mempool")
|
||||
errMempoolIsFull = errors.New("mempool is full")
|
||||
errTxInMempool = errors.New("tx already in mempool")
|
||||
)
|
||||
|
||||
// PriorityNonceMempool is a mempool implementation that stores txs
|
||||
// in a partially ordered set by 2 dimensions: priority, and sender-nonce
|
||||
// (sequence number). Internally it uses one priority ordered skip list and one
|
||||
// skip list per sender ordered by sender-nonce (sequence number). When there
|
||||
// are multiple txs from the same sender, they are not always comparable by
|
||||
// priority to other sender txs and must be partially ordered by both sender-nonce
|
||||
// and priority.
|
||||
type PriorityNonceMempool struct {
|
||||
mtx sync.Mutex
|
||||
priorityIndex *skiplist.SkipList
|
||||
priorityCounts map[int64]int
|
||||
senderIndices map[string]*skiplist.SkipList
|
||||
scores map[txMeta]txMeta
|
||||
onRead func(tx sdk.Tx)
|
||||
txReplacement func(op, np int64, oTx, nTx sdk.Tx) bool
|
||||
maxTx int
|
||||
|
||||
senderTxCntLock sync.RWMutex
|
||||
counterBySender map[string]int
|
||||
txRecord map[txMeta]struct{}
|
||||
|
||||
txReplacedCallback func(ctx context.Context, oldTx, newTx *TxInfo)
|
||||
}
|
||||
|
||||
type PriorityNonceIterator struct {
|
||||
senderCursors map[string]*skiplist.Element
|
||||
nextPriority int64
|
||||
sender string
|
||||
priorityNode *skiplist.Element
|
||||
mempool *PriorityNonceMempool
|
||||
}
|
||||
|
||||
// txMeta stores transaction metadata used in indices
|
||||
type txMeta struct {
|
||||
// nonce is the sender's sequence number
|
||||
nonce uint64
|
||||
// priority is the transaction's priority
|
||||
priority int64
|
||||
// sender is the transaction's sender
|
||||
sender string
|
||||
// weight is the transaction's weight, used as a tiebreaker for transactions with the same priority
|
||||
weight int64
|
||||
// senderElement is a pointer to the transaction's element in the sender index
|
||||
senderElement *skiplist.Element
|
||||
}
|
||||
|
||||
// txMetaLess is a comparator for txKeys that first compares priority, then weight,
|
||||
// then sender, then nonce, uniquely identifying a transaction.
|
||||
//
|
||||
// Note, txMetaLess is used as the comparator in the priority index.
|
||||
func txMetaLess(a, b any) int {
|
||||
keyA := a.(txMeta)
|
||||
keyB := b.(txMeta)
|
||||
res := skiplist.Int64.Compare(keyA.priority, keyB.priority)
|
||||
if res != 0 {
|
||||
return res
|
||||
}
|
||||
|
||||
// Weight is used as a tiebreaker for transactions with the same priority.
|
||||
// Weight is calculated in a single pass in .Select(...) and so will be 0
|
||||
// on .Insert(...).
|
||||
res = skiplist.Int64.Compare(keyA.weight, keyB.weight)
|
||||
if res != 0 {
|
||||
return res
|
||||
}
|
||||
|
||||
// Because weight will be 0 on .Insert(...), we must also compare sender and
|
||||
// nonce to resolve priority collisions. If we didn't then transactions with
|
||||
// the same priority would overwrite each other in the priority index.
|
||||
res = skiplist.String.Compare(keyA.sender, keyB.sender)
|
||||
if res != 0 {
|
||||
return res
|
||||
}
|
||||
|
||||
return skiplist.Uint64.Compare(keyA.nonce, keyB.nonce)
|
||||
}
|
||||
|
||||
type PriorityNonceMempoolOption func(*PriorityNonceMempool)
|
||||
|
||||
// PriorityNonceWithOnRead sets a callback to be called when a tx is read from
|
||||
// the mempool.
|
||||
func PriorityNonceWithOnRead(onRead func(tx sdk.Tx)) PriorityNonceMempoolOption {
|
||||
return func(mp *PriorityNonceMempool) {
|
||||
mp.onRead = onRead
|
||||
}
|
||||
}
|
||||
|
||||
// PriorityNonceWithTxReplacement sets a callback to be called when duplicated
|
||||
// transaction nonce detected during mempool insert. An application can define a
|
||||
// transaction replacement rule based on tx priority or certain transaction fields.
|
||||
func PriorityNonceWithTxReplacement(txReplacementRule func(op, np int64, oTx, nTx sdk.Tx) bool) PriorityNonceMempoolOption {
|
||||
return func(mp *PriorityNonceMempool) {
|
||||
mp.txReplacement = txReplacementRule
|
||||
}
|
||||
}
|
||||
|
||||
// PriorityNonceWithMaxTx sets the maximum number of transactions allowed in the
|
||||
// mempool with the semantics:
|
||||
//
|
||||
// <0: disabled, `Insert` is a no-op
|
||||
// 0: unlimited
|
||||
// >0: maximum number of transactions allowed
|
||||
func PriorityNonceWithMaxTx(maxTx int) PriorityNonceMempoolOption {
|
||||
return func(mp *PriorityNonceMempool) {
|
||||
mp.maxTx = maxTx
|
||||
}
|
||||
}
|
||||
|
||||
func PriorityNonceWithTxReplacedCallback(cb func(ctx context.Context, oldTx, newTx *TxInfo)) PriorityNonceMempoolOption {
|
||||
return func(mp *PriorityNonceMempool) {
|
||||
mp.txReplacedCallback = cb
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultPriorityMempool returns a priorityNonceMempool with no options.
|
||||
func DefaultPriorityMempool() mempool.Mempool {
|
||||
return NewPriorityMempool()
|
||||
}
|
||||
|
||||
// NewPriorityMempool returns the SDK's default mempool implementation which
|
||||
// returns txs in a partial order by 2 dimensions; priority, and sender-nonce.
|
||||
func NewPriorityMempool(opts ...PriorityNonceMempoolOption) *PriorityNonceMempool {
|
||||
mp := &PriorityNonceMempool{
|
||||
priorityIndex: skiplist.New(skiplist.LessThanFunc(txMetaLess)),
|
||||
priorityCounts: make(map[int64]int),
|
||||
senderIndices: make(map[string]*skiplist.SkipList),
|
||||
scores: make(map[txMeta]txMeta),
|
||||
counterBySender: make(map[string]int),
|
||||
txRecord: make(map[txMeta]struct{}),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(mp)
|
||||
}
|
||||
|
||||
return mp
|
||||
}
|
||||
|
||||
// NextSenderTx returns the next transaction for a given sender by nonce order,
|
||||
// i.e. the next valid transaction for the sender. If no such transaction exists,
|
||||
// nil will be returned.
|
||||
func (mp *PriorityNonceMempool) NextSenderTx(sender string) sdk.Tx {
|
||||
senderIndex, ok := mp.senderIndices[sender]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
cursor := senderIndex.Front()
|
||||
return cursor.Value.(sdk.Tx)
|
||||
}
|
||||
|
||||
// Insert attempts to insert a Tx into the app-side mempool in O(log n) time,
|
||||
// returning an error if unsuccessful. Sender and nonce are derived from the
|
||||
// transaction's first signature.
|
||||
//
|
||||
// Transactions are unique by sender and nonce. Inserting a duplicate tx is an
|
||||
// O(log n) no-op.
|
||||
//
|
||||
// Inserting a duplicate tx with a different priority overwrites the existing tx,
|
||||
// changing the total order of the mempool.
|
||||
func (mp *PriorityNonceMempool) Insert(ctx context.Context, tx sdk.Tx) error {
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
// if mp.maxTx > 0 && mp.CountTx() >= mp.maxTx {
|
||||
// return mempool.ErrMempoolTxMaxCapacity
|
||||
// } else
|
||||
if mp.maxTx < 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
sdkContext := sdk.UnwrapSDKContext(ctx)
|
||||
priority := sdkContext.Priority()
|
||||
|
||||
txInfo, err := extractTxInfo(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !mp.canInsert(txInfo.Sender) {
|
||||
return errors.Wrapf(errMempoolTooManyTxs, "[%d@%s]sender has too many txs in mempool", txInfo.Nonce, txInfo.Sender)
|
||||
}
|
||||
|
||||
// init sender index if not exists
|
||||
senderIndex, ok := mp.senderIndices[txInfo.Sender]
|
||||
if !ok {
|
||||
senderIndex = skiplist.New(skiplist.LessThanFunc(func(a, b any) int {
|
||||
return skiplist.Uint64.Compare(b.(txMeta).nonce, a.(txMeta).nonce)
|
||||
}))
|
||||
|
||||
// initialize sender index if not found
|
||||
mp.senderIndices[txInfo.Sender] = senderIndex
|
||||
}
|
||||
|
||||
newKey := txMeta{nonce: txInfo.Nonce, priority: priority, sender: txInfo.Sender}
|
||||
|
||||
// Since mp.priorityIndex is scored by priority, then sender, then nonce, a
|
||||
// changed priority will create a new key, so we must remove the old key and
|
||||
// re-insert it to avoid having the same tx with different priorityIndex indexed
|
||||
// twice in the mempool.
|
||||
//
|
||||
// This O(log n) remove operation is rare and only happens when a tx's priority
|
||||
// changes.
|
||||
|
||||
sk := txMeta{nonce: txInfo.Nonce, sender: txInfo.Sender}
|
||||
if oldScore, txExists := mp.scores[sk]; txExists {
|
||||
if oldScore.priority < priority {
|
||||
oldTx := senderIndex.Get(newKey).Value.(sdk.Tx)
|
||||
return mp.doTxReplace(ctx, newKey, oldScore, oldTx, tx)
|
||||
}
|
||||
return errors.Wrapf(errTxInMempool, "[%d@%s] tx already in mempool", txInfo.Nonce, txInfo.Sender)
|
||||
} else {
|
||||
mempoolSize := mp.priorityIndex.Len()
|
||||
if mempoolSize >= mp.maxTx {
|
||||
lowestPriority := mp.getLowestPriority()
|
||||
// find one to replace
|
||||
if lowestPriority > 0 && priority <= lowestPriority {
|
||||
return errors.Wrapf(errMempoolTxGasPriceTooLow, "[%d@%s]tx with priority %d is too low, current lowest priority is %d", newKey.nonce, newKey.sender, priority, lowestPriority)
|
||||
}
|
||||
|
||||
var maxIndexSize int
|
||||
var lowerPriority int64 = math.MaxInt64
|
||||
var selectedElement *skiplist.Element
|
||||
for sender, index := range mp.senderIndices {
|
||||
indexSize := index.Len()
|
||||
if sender == txInfo.Sender {
|
||||
continue
|
||||
}
|
||||
|
||||
if indexSize > 0 {
|
||||
tail := index.Back()
|
||||
if tail != nil {
|
||||
tailKey := tail.Key().(txMeta)
|
||||
if tailKey.priority < lowerPriority {
|
||||
lowerPriority = tailKey.priority
|
||||
maxIndexSize = indexSize
|
||||
selectedElement = tail
|
||||
} else if tailKey.priority == lowerPriority {
|
||||
if indexSize > maxIndexSize {
|
||||
maxIndexSize = indexSize
|
||||
selectedElement = tail
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if selectedElement != nil {
|
||||
key := selectedElement.Key().(txMeta)
|
||||
replacedTx, _ := mp.doRemove(key, true)
|
||||
|
||||
// insert new tx
|
||||
mp.doInsert(newKey, tx, true)
|
||||
|
||||
if mp.txReplacedCallback != nil && replacedTx != nil {
|
||||
sdkContext.Logger().Debug("txn replaced caused by full of mempool", "old", fmt.Sprintf("%d@%s", key.nonce, key.sender), "new", fmt.Sprintf("%d@%s", newKey.nonce, newKey.sender), "mempoolSize", mempoolSize)
|
||||
mp.txReplacedCallback(ctx,
|
||||
&TxInfo{Sender: key.sender, Nonce: key.nonce, Tx: replacedTx},
|
||||
&TxInfo{Sender: newKey.sender, Nonce: newKey.nonce, Tx: tx},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return errors.Wrapf(errMempoolIsFull, "%d@%s with priority%d", newKey.nonce, newKey.sender, newKey.priority)
|
||||
}
|
||||
} else {
|
||||
mp.doInsert(newKey, tx, true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) doInsert(newKey txMeta, tx sdk.Tx, incrCnt bool) {
|
||||
senderIndex, ok := mp.senderIndices[newKey.sender]
|
||||
if !ok {
|
||||
senderIndex = skiplist.New(skiplist.LessThanFunc(func(a, b any) int {
|
||||
return skiplist.Uint64.Compare(b.(txMeta).nonce, a.(txMeta).nonce)
|
||||
}))
|
||||
|
||||
// initialize sender index if not found
|
||||
mp.senderIndices[newKey.sender] = senderIndex
|
||||
}
|
||||
|
||||
mp.priorityCounts[newKey.priority]++
|
||||
newKey.senderElement = senderIndex.Set(newKey, tx)
|
||||
|
||||
mp.scores[txMeta{nonce: newKey.nonce, sender: newKey.sender}] = txMeta{priority: newKey.priority}
|
||||
mp.priorityIndex.Set(newKey, tx)
|
||||
|
||||
if incrCnt {
|
||||
mp.incrSenderTxCnt(newKey.sender, newKey.nonce)
|
||||
}
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) doRemove(oldKey txMeta, decrCnt bool) (sdk.Tx, error) {
|
||||
scoreKey := txMeta{nonce: oldKey.nonce, sender: oldKey.sender}
|
||||
score, ok := mp.scores[scoreKey]
|
||||
if !ok {
|
||||
return nil, errors.Wrapf(mempool.ErrTxNotFound, "%d@%s not found", oldKey.nonce, oldKey.sender)
|
||||
}
|
||||
tk := txMeta{nonce: oldKey.nonce, priority: score.priority, sender: oldKey.sender, weight: score.weight}
|
||||
|
||||
senderTxs, ok := mp.senderIndices[oldKey.sender]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%d@%s not found", oldKey.nonce, oldKey.sender)
|
||||
}
|
||||
|
||||
mp.priorityIndex.Remove(tk)
|
||||
removedElem := senderTxs.Remove(tk)
|
||||
delete(mp.scores, scoreKey)
|
||||
mp.priorityCounts[score.priority]--
|
||||
|
||||
if decrCnt {
|
||||
mp.decrSenderTxCnt(oldKey.sender, oldKey.nonce)
|
||||
}
|
||||
|
||||
if removedElem == nil {
|
||||
return nil, mempool.ErrTxNotFound
|
||||
}
|
||||
|
||||
return removedElem.Value.(sdk.Tx), nil
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) doTxReplace(ctx context.Context, newMate, oldMate txMeta, oldTx, newTx sdk.Tx) error {
|
||||
if mp.txReplacement != nil && !mp.txReplacement(oldMate.priority, newMate.priority, oldTx, newTx) {
|
||||
return fmt.Errorf(
|
||||
"tx doesn't fit the replacement rule, oldPriority: %v, newPriority: %v, oldTx: %v, newTx: %v",
|
||||
oldMate.priority,
|
||||
newMate.priority,
|
||||
oldTx,
|
||||
newTx,
|
||||
)
|
||||
}
|
||||
|
||||
e := mp.priorityIndex.Remove(txMeta{
|
||||
nonce: newMate.nonce,
|
||||
sender: newMate.sender,
|
||||
priority: oldMate.priority,
|
||||
weight: oldMate.weight,
|
||||
})
|
||||
replacedTx := e.Value.(sdk.Tx)
|
||||
mp.priorityCounts[oldMate.priority]--
|
||||
|
||||
mp.doInsert(newMate, newTx, false)
|
||||
|
||||
if mp.txReplacedCallback != nil && replacedTx != nil {
|
||||
sdkContext := sdk.UnwrapSDKContext(ctx)
|
||||
sdkContext.Logger().Debug("txn update", "txn", fmt.Sprintf("%d@%s", newMate.nonce, newMate.sender), "oldPriority", oldMate.priority, "newPriority", newMate.priority)
|
||||
mp.txReplacedCallback(ctx,
|
||||
&TxInfo{Sender: newMate.sender, Nonce: newMate.nonce, Tx: replacedTx},
|
||||
&TxInfo{Sender: newMate.sender, Nonce: newMate.nonce, Tx: newTx},
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *PriorityNonceIterator) iteratePriority() mempool.Iterator {
|
||||
// beginning of priority iteration
|
||||
if i.priorityNode == nil {
|
||||
i.priorityNode = i.mempool.priorityIndex.Front()
|
||||
} else {
|
||||
i.priorityNode = i.priorityNode.Next()
|
||||
}
|
||||
|
||||
// end of priority iteration
|
||||
if i.priorityNode == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
i.sender = i.priorityNode.Key().(txMeta).sender
|
||||
|
||||
nextPriorityNode := i.priorityNode.Next()
|
||||
if nextPriorityNode != nil {
|
||||
i.nextPriority = nextPriorityNode.Key().(txMeta).priority
|
||||
} else {
|
||||
i.nextPriority = math.MinInt64
|
||||
}
|
||||
|
||||
return i.Next()
|
||||
}
|
||||
|
||||
func (i *PriorityNonceIterator) Next() mempool.Iterator {
|
||||
if i.priorityNode == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cursor, ok := i.senderCursors[i.sender]
|
||||
if !ok {
|
||||
// beginning of sender iteration
|
||||
cursor = i.mempool.senderIndices[i.sender].Front()
|
||||
} else {
|
||||
// middle of sender iteration
|
||||
cursor = cursor.Next()
|
||||
}
|
||||
|
||||
// end of sender iteration
|
||||
if cursor == nil {
|
||||
return i.iteratePriority()
|
||||
}
|
||||
|
||||
key := cursor.Key().(txMeta)
|
||||
|
||||
// We've reached a transaction with a priority lower than the next highest
|
||||
// priority in the pool.
|
||||
if key.priority < i.nextPriority {
|
||||
return i.iteratePriority()
|
||||
} else if key.priority == i.nextPriority && i.priorityNode.Next() != nil {
|
||||
// Weight is incorporated into the priority index key only (not sender index)
|
||||
// so we must fetch it here from the scores map.
|
||||
weight := i.mempool.scores[txMeta{nonce: key.nonce, sender: key.sender}].weight
|
||||
if weight < i.priorityNode.Next().Key().(txMeta).weight {
|
||||
return i.iteratePriority()
|
||||
}
|
||||
}
|
||||
|
||||
i.senderCursors[i.sender] = cursor
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *PriorityNonceIterator) Tx() sdk.Tx {
|
||||
return i.senderCursors[i.sender].Value.(sdk.Tx)
|
||||
}
|
||||
|
||||
// Select returns a set of transactions from the mempool, ordered by priority
|
||||
// and sender-nonce in O(n) time. The passed in list of transactions are ignored.
|
||||
// This is a readonly operation, the mempool is not modified.
|
||||
//
|
||||
// The maxBytes parameter defines the maximum number of bytes of transactions to
|
||||
// return.
|
||||
//
|
||||
// NOTE: It is not safe to use this iterator while removing transactions from
|
||||
// the underlying mempool.
|
||||
func (mp *PriorityNonceMempool) Select(ctx context.Context, txs [][]byte) mempool.Iterator {
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
return mp.doSelect(ctx, txs)
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) SelectBy(ctx context.Context, txs [][]byte, callback func(sdk.Tx) bool) {
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
iter := mp.doSelect(ctx, txs)
|
||||
for iter != nil && callback(iter.Tx()) {
|
||||
iter = iter.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) doSelect(_ context.Context, _ [][]byte) mempool.Iterator {
|
||||
if mp.priorityIndex.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
mp.reorderPriorityTies()
|
||||
|
||||
iterator := &PriorityNonceIterator{
|
||||
mempool: mp,
|
||||
senderCursors: make(map[string]*skiplist.Element),
|
||||
}
|
||||
|
||||
return iterator.iteratePriority()
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) GetSenderUncommittedTxnCount(ctx context.Context, sender string) int {
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
if _, exists := mp.counterBySender[sender]; exists {
|
||||
return mp.counterBySender[sender]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type reorderKey struct {
|
||||
deleteKey txMeta
|
||||
insertKey txMeta
|
||||
tx sdk.Tx
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) reorderPriorityTies() {
|
||||
node := mp.priorityIndex.Front()
|
||||
|
||||
var reordering []reorderKey
|
||||
for node != nil {
|
||||
key := node.Key().(txMeta)
|
||||
if mp.priorityCounts[key.priority] > 1 {
|
||||
newKey := key
|
||||
newKey.weight = senderWeight(key.senderElement)
|
||||
reordering = append(reordering, reorderKey{deleteKey: key, insertKey: newKey, tx: node.Value.(sdk.Tx)})
|
||||
}
|
||||
|
||||
node = node.Next()
|
||||
}
|
||||
|
||||
for _, k := range reordering {
|
||||
mp.priorityIndex.Remove(k.deleteKey)
|
||||
delete(mp.scores, txMeta{nonce: k.deleteKey.nonce, sender: k.deleteKey.sender})
|
||||
mp.priorityIndex.Set(k.insertKey, k.tx)
|
||||
mp.scores[txMeta{nonce: k.insertKey.nonce, sender: k.insertKey.sender}] = k.insertKey
|
||||
}
|
||||
}
|
||||
|
||||
// senderWeight returns the weight of a given tx (t) at senderCursor. Weight is
|
||||
// defined as the first (nonce-wise) same sender tx with a priority not equal to
|
||||
// t. It is used to resolve priority collisions, that is when 2 or more txs from
|
||||
// different senders have the same priority.
|
||||
func senderWeight(senderCursor *skiplist.Element) int64 {
|
||||
if senderCursor == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
weight := senderCursor.Key().(txMeta).priority
|
||||
senderCursor = senderCursor.Next()
|
||||
for senderCursor != nil {
|
||||
p := senderCursor.Key().(txMeta).priority
|
||||
if p != weight {
|
||||
weight = p
|
||||
}
|
||||
|
||||
senderCursor = senderCursor.Next()
|
||||
}
|
||||
|
||||
return weight
|
||||
}
|
||||
|
||||
// CountTx returns the number of transactions in the mempool.
|
||||
func (mp *PriorityNonceMempool) CountTx() int {
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
return mp.priorityIndex.Len()
|
||||
}
|
||||
|
||||
// Remove removes a transaction from the mempool in O(log n) time, returning an
|
||||
// error if unsuccessful.
|
||||
func (mp *PriorityNonceMempool) Remove(tx sdk.Tx) error {
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
txInfo, err := extractTxInfo(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mp.decrSenderTxCnt(txInfo.Sender, txInfo.Nonce)
|
||||
|
||||
scoreKey := txMeta{nonce: txInfo.Nonce, sender: txInfo.Sender}
|
||||
score, ok := mp.scores[scoreKey]
|
||||
if !ok {
|
||||
return mempool.ErrTxNotFound
|
||||
}
|
||||
tk := txMeta{nonce: txInfo.Nonce, priority: score.priority, sender: txInfo.Sender, weight: score.weight}
|
||||
|
||||
senderTxs, ok := mp.senderIndices[txInfo.Sender]
|
||||
if !ok {
|
||||
return fmt.Errorf("sender %s not found", txInfo.Sender)
|
||||
}
|
||||
|
||||
mp.priorityIndex.Remove(tk)
|
||||
senderTxs.Remove(tk)
|
||||
delete(mp.scores, scoreKey)
|
||||
mp.priorityCounts[score.priority]--
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) getLowestPriority() int64 {
|
||||
if mp.priorityIndex.Len() == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
min := int64(math.MaxInt64)
|
||||
for priority, count := range mp.priorityCounts {
|
||||
if count > 0 {
|
||||
if priority < min {
|
||||
min = priority
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return min
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) canInsert(sender string) bool {
|
||||
mp.senderTxCntLock.RLock()
|
||||
defer mp.senderTxCntLock.RUnlock()
|
||||
|
||||
if _, exists := mp.counterBySender[sender]; exists {
|
||||
return mp.counterBySender[sender] < MAX_TXS_PRE_SENDER_IN_MEMPOOL
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) incrSenderTxCnt(sender string, nonce uint64) error {
|
||||
mp.senderTxCntLock.Lock()
|
||||
defer mp.senderTxCntLock.Unlock()
|
||||
|
||||
existsKey := txMeta{nonce: nonce, sender: sender}
|
||||
if _, exists := mp.txRecord[existsKey]; !exists {
|
||||
mp.txRecord[existsKey] = struct{}{}
|
||||
|
||||
if _, exists := mp.counterBySender[sender]; !exists {
|
||||
mp.counterBySender[sender] = 1
|
||||
} else {
|
||||
if mp.counterBySender[sender] < MAX_TXS_PRE_SENDER_IN_MEMPOOL {
|
||||
mp.counterBySender[sender] += 1
|
||||
} else {
|
||||
return fmt.Errorf("tx sender has too many txs in mempool")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *PriorityNonceMempool) decrSenderTxCnt(sender string, nonce uint64) {
|
||||
mp.senderTxCntLock.Lock()
|
||||
defer mp.senderTxCntLock.Unlock()
|
||||
|
||||
existsKey := txMeta{nonce: nonce, sender: sender}
|
||||
if _, exists := mp.txRecord[existsKey]; exists {
|
||||
delete(mp.txRecord, existsKey)
|
||||
|
||||
if _, exists := mp.counterBySender[sender]; exists {
|
||||
if mp.counterBySender[sender] > 1 {
|
||||
mp.counterBySender[sender] -= 1
|
||||
} else {
|
||||
delete(mp.counterBySender, sender)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func IsEmpty(mempool mempool.Mempool) error {
|
||||
mp := mempool.(*PriorityNonceMempool)
|
||||
if mp.priorityIndex.Len() != 0 {
|
||||
return fmt.Errorf("priorityIndex not empty")
|
||||
}
|
||||
|
||||
var countKeys []int64
|
||||
for k := range mp.priorityCounts {
|
||||
countKeys = append(countKeys, k)
|
||||
}
|
||||
|
||||
for _, k := range countKeys {
|
||||
if mp.priorityCounts[k] != 0 {
|
||||
return fmt.Errorf("priorityCounts not zero at %v, got %v", k, mp.priorityCounts[k])
|
||||
}
|
||||
}
|
||||
|
||||
var senderKeys []string
|
||||
for k := range mp.senderIndices {
|
||||
senderKeys = append(senderKeys, k)
|
||||
}
|
||||
|
||||
for _, k := range senderKeys {
|
||||
if mp.senderIndices[k].Len() != 0 {
|
||||
return fmt.Errorf("senderIndex not empty for sender %v", k)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type TxInfo struct {
|
||||
Sender string
|
||||
Nonce uint64
|
||||
Tx sdk.Tx
|
||||
}
|
||||
|
||||
func extractTxInfo(tx sdk.Tx) (*TxInfo, error) {
|
||||
var sender string
|
||||
var nonce uint64
|
||||
|
||||
sigs, err := tx.(signing.SigVerifiableTx).GetSignaturesV2()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(sigs) == 0 {
|
||||
msgs := tx.GetMsgs()
|
||||
if len(msgs) != 1 {
|
||||
return nil, fmt.Errorf("tx must have at least one signer")
|
||||
}
|
||||
msgEthTx, ok := msgs[0].(*evmtypes.MsgEthereumTx)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("tx must have at least one signer")
|
||||
}
|
||||
ethTx := msgEthTx.AsTransaction()
|
||||
signer := gethtypes.NewEIP2930Signer(ethTx.ChainId())
|
||||
ethSender, err := signer.Sender(ethTx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tx must have at least one signer")
|
||||
}
|
||||
sender = sdk.AccAddress(ethSender.Bytes()).String()
|
||||
nonce = ethTx.Nonce()
|
||||
} else {
|
||||
sig := sigs[0]
|
||||
sender = sdk.AccAddress(sig.PubKey.Address()).String()
|
||||
nonce = sig.Sequence
|
||||
}
|
||||
|
||||
return &TxInfo{Sender: sender, Nonce: nonce, Tx: tx}, nil
|
||||
}
|
@ -8,10 +8,6 @@ import (
|
||||
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
earnkeeper "github.com/kava-labs/kava/x/earn/keeper"
|
||||
liquidkeeper "github.com/kava-labs/kava/x/liquid/keeper"
|
||||
liquidtypes "github.com/kava-labs/kava/x/liquid/types"
|
||||
savingskeeper "github.com/kava-labs/kava/x/savings/keeper"
|
||||
)
|
||||
|
||||
var _ govv1.TallyHandler = TallyHandler{}
|
||||
@ -20,23 +16,16 @@ var _ govv1.TallyHandler = TallyHandler{}
|
||||
type TallyHandler struct {
|
||||
gk govkeeper.Keeper
|
||||
stk stakingkeeper.Keeper
|
||||
svk savingskeeper.Keeper
|
||||
ek earnkeeper.Keeper
|
||||
lk liquidkeeper.Keeper
|
||||
bk bankkeeper.Keeper
|
||||
}
|
||||
|
||||
// NewTallyHandler creates a new tally handler.
|
||||
func NewTallyHandler(
|
||||
gk govkeeper.Keeper, stk stakingkeeper.Keeper, svk savingskeeper.Keeper,
|
||||
ek earnkeeper.Keeper, lk liquidkeeper.Keeper, bk bankkeeper.Keeper,
|
||||
gk govkeeper.Keeper, stk stakingkeeper.Keeper, bk bankkeeper.Keeper,
|
||||
) TallyHandler {
|
||||
return TallyHandler{
|
||||
gk: gk,
|
||||
stk: stk,
|
||||
svk: svk,
|
||||
ek: ek,
|
||||
lk: lk,
|
||||
bk: bk,
|
||||
}
|
||||
}
|
||||
@ -105,34 +94,34 @@ func (th TallyHandler) Tally(
|
||||
})
|
||||
|
||||
// get voter bkava and update total voting power and results
|
||||
addrBkava := th.getAddrBkava(ctx, voter).toCoins()
|
||||
for _, coin := range addrBkava {
|
||||
valAddr, err := liquidtypes.ParseLiquidStakingTokenDenom(coin.Denom)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
// addrBkava := th.getAddrBkava(ctx, voter).toCoins()
|
||||
// for _, coin := range addrBkava {
|
||||
// valAddr, err := liquidtypes.ParseLiquidStakingTokenDenom(coin.Denom)
|
||||
// if err != nil {
|
||||
// break
|
||||
// }
|
||||
|
||||
// reduce delegator shares by the amount of voter bkava for the validator
|
||||
valAddrStr := valAddr.String()
|
||||
if val, ok := currValidators[valAddrStr]; ok {
|
||||
val.DelegatorDeductions = val.DelegatorDeductions.Add(sdk.NewDecFromInt(coin.Amount))
|
||||
currValidators[valAddrStr] = val
|
||||
}
|
||||
// // reduce delegator shares by the amount of voter bkava for the validator
|
||||
// valAddrStr := valAddr.String()
|
||||
// if val, ok := currValidators[valAddrStr]; ok {
|
||||
// val.DelegatorDeductions = val.DelegatorDeductions.Add(sdk.NewDecFromInt(coin.Amount))
|
||||
// currValidators[valAddrStr] = val
|
||||
// }
|
||||
|
||||
// votingPower = amount of ukava coin
|
||||
stakedCoins, err := th.lk.GetStakedTokensForDerivatives(ctx, sdk.NewCoins(coin))
|
||||
if err != nil {
|
||||
// error is returned only if the bkava denom is incorrect, which should never happen here.
|
||||
panic(err)
|
||||
}
|
||||
votingPower := sdk.NewDecFromInt(stakedCoins.Amount)
|
||||
// // votingPower = amount of ukava coin
|
||||
// stakedCoins, err := th.lk.GetStakedTokensForDerivatives(ctx, sdk.NewCoins(coin))
|
||||
// if err != nil {
|
||||
// // error is returned only if the bkava denom is incorrect, which should never happen here.
|
||||
// panic(err)
|
||||
// }
|
||||
// votingPower := sdk.NewDecFromInt(stakedCoins.Amount)
|
||||
|
||||
for _, option := range vote.Options {
|
||||
subPower := votingPower.Mul(sdk.MustNewDecFromStr(option.Weight))
|
||||
results[option.Option] = results[option.Option].Add(subPower)
|
||||
}
|
||||
totalVotingPower = totalVotingPower.Add(votingPower)
|
||||
}
|
||||
// for _, option := range vote.Options {
|
||||
// subPower := votingPower.Mul(sdk.MustNewDecFromStr(option.Weight))
|
||||
// results[option.Option] = results[option.Option].Add(subPower)
|
||||
// }
|
||||
// totalVotingPower = totalVotingPower.Add(votingPower)
|
||||
// }
|
||||
|
||||
th.gk.DeleteVote(ctx, vote.ProposalId, voter)
|
||||
return false
|
||||
@ -154,7 +143,7 @@ func (th TallyHandler) Tally(
|
||||
totalVotingPower = totalVotingPower.Add(votingPower)
|
||||
}
|
||||
|
||||
tallyParams := th.gk.GetTallyParams(ctx)
|
||||
tallyParams := th.gk.GetParams(ctx)
|
||||
tallyResults = govv1.NewTallyResultFromMap(results)
|
||||
|
||||
// TODO: Upgrade the spec to cover all of these cases & remove pseudocode.
|
||||
@ -166,7 +155,7 @@ func (th TallyHandler) Tally(
|
||||
// If there is not enough quorum of votes, the proposal fails
|
||||
percentVoting := totalVotingPower.Quo(sdk.NewDecFromInt(th.stk.TotalBondedTokens(ctx)))
|
||||
if percentVoting.LT(sdk.MustNewDecFromStr(tallyParams.Quorum)) {
|
||||
return false, true, tallyResults
|
||||
return false, tallyParams.BurnVoteQuorum, tallyResults
|
||||
}
|
||||
|
||||
// If no one votes (everyone abstains), proposal fails
|
||||
@ -176,7 +165,7 @@ func (th TallyHandler) Tally(
|
||||
|
||||
// If more than 1/3 of voters veto, proposal fails
|
||||
if results[govv1.OptionNoWithVeto].Quo(totalVotingPower).GT(sdk.MustNewDecFromStr(tallyParams.VetoThreshold)) {
|
||||
return false, true, tallyResults
|
||||
return false, tallyParams.BurnVoteVeto, tallyResults
|
||||
}
|
||||
|
||||
// If more than 1/2 of non-abstaining voters vote Yes, proposal passes
|
||||
@ -219,38 +208,38 @@ func (th TallyHandler) getAddrBkava(ctx sdk.Context, addr sdk.AccAddress) bkavaB
|
||||
|
||||
// addBkavaFromWallet adds all addr balances of bkava in x/bank.
|
||||
func (th TallyHandler) addBkavaFromWallet(ctx sdk.Context, addr sdk.AccAddress, bkava bkavaByDenom) {
|
||||
coins := th.bk.GetAllBalances(ctx, addr)
|
||||
for _, coin := range coins {
|
||||
if th.lk.IsDerivativeDenom(ctx, coin.Denom) {
|
||||
bkava.add(coin)
|
||||
}
|
||||
}
|
||||
// coins := th.bk.GetAllBalances(ctx, addr)
|
||||
// for _, coin := range coins {
|
||||
// if th.lk.IsDerivativeDenom(ctx, coin.Denom) {
|
||||
// bkava.add(coin)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// addBkavaFromSavings adds all addr deposits of bkava in x/savings.
|
||||
func (th TallyHandler) addBkavaFromSavings(ctx sdk.Context, addr sdk.AccAddress, bkava bkavaByDenom) {
|
||||
deposit, found := th.svk.GetDeposit(ctx, addr)
|
||||
if !found {
|
||||
return
|
||||
}
|
||||
for _, coin := range deposit.Amount {
|
||||
if th.lk.IsDerivativeDenom(ctx, coin.Denom) {
|
||||
bkava.add(coin)
|
||||
}
|
||||
}
|
||||
// deposit, found := th.svk.GetDeposit(ctx, addr)
|
||||
// if !found {
|
||||
// return
|
||||
// }
|
||||
// for _, coin := range deposit.Amount {
|
||||
// if th.lk.IsDerivativeDenom(ctx, coin.Denom) {
|
||||
// bkava.add(coin)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// addBkavaFromEarn adds all addr deposits of bkava in x/earn.
|
||||
func (th TallyHandler) addBkavaFromEarn(ctx sdk.Context, addr sdk.AccAddress, bkava bkavaByDenom) {
|
||||
shares, found := th.ek.GetVaultAccountShares(ctx, addr)
|
||||
if !found {
|
||||
return
|
||||
}
|
||||
for _, share := range shares {
|
||||
if th.lk.IsDerivativeDenom(ctx, share.Denom) {
|
||||
if coin, err := th.ek.ConvertToAssets(ctx, share); err == nil {
|
||||
bkava.add(coin)
|
||||
}
|
||||
}
|
||||
}
|
||||
// shares, found := th.ek.GetVaultAccountShares(ctx, addr)
|
||||
// if !found {
|
||||
// return
|
||||
// }
|
||||
// for _, share := range shares {
|
||||
// if th.lk.IsDerivativeDenom(ctx, share.Denom) {
|
||||
// if coin, err := th.ek.ConvertToAssets(ctx, share); err == nil {
|
||||
// bkava.add(coin)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
@ -15,10 +16,6 @@ import (
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
earntypes "github.com/kava-labs/kava/x/earn/types"
|
||||
liquidtypes "github.com/kava-labs/kava/x/liquid/types"
|
||||
)
|
||||
|
||||
// d is an alias for sdk.MustNewDecFromStr
|
||||
@ -44,15 +41,13 @@ func (suite *tallyHandlerSuite) SetupTest() {
|
||||
genesisTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
suite.ctx = suite.app.NewContext(false, tmproto.Header{Height: 1, Time: genesisTime})
|
||||
|
||||
suite.staking = stakingHelper{suite.app.GetStakingKeeper()}
|
||||
stakingKeeper := *suite.app.GetStakingKeeper()
|
||||
suite.staking = stakingHelper{stakingKeeper}
|
||||
suite.staking.setBondDenom(suite.ctx, "ukava")
|
||||
|
||||
suite.tallier = NewTallyHandler(
|
||||
suite.app.GetGovKeeper(),
|
||||
suite.app.GetStakingKeeper(),
|
||||
suite.app.GetSavingsKeeper(),
|
||||
suite.app.GetEarnKeeper(),
|
||||
suite.app.GetLiquidKeeper(),
|
||||
stakingKeeper,
|
||||
suite.app.GetBankKeeper(),
|
||||
)
|
||||
}
|
||||
@ -135,7 +130,7 @@ func (suite *tallyHandlerSuite) TestTallyOutcomes() {
|
||||
|
||||
passes, burns, tally := suite.tallier.Tally(suite.ctx, proposal)
|
||||
suite.Falsef(passes, "expected proposal to fail, tally: %v", tally)
|
||||
suite.Truef(burns, "expected desposit to be burned, tally: %v", tally)
|
||||
suite.Truef(burns, "expected deposit to be burned, tally: %v", tally)
|
||||
})
|
||||
suite.Run("VetoedFails", func() {
|
||||
suite.SetupTest()
|
||||
@ -150,7 +145,7 @@ func (suite *tallyHandlerSuite) TestTallyOutcomes() {
|
||||
|
||||
passes, burns, tally := suite.tallier.Tally(suite.ctx, proposal)
|
||||
suite.Falsef(passes, "expected proposal to fail, tally: %v", tally)
|
||||
suite.Truef(burns, "expected desposit to be burned, tally: %v", tally)
|
||||
suite.Truef(burns, "expected deposit to be burned, tally: %v", tally)
|
||||
})
|
||||
suite.Run("UnvetoedAndYesAboveThresholdPasses", func() {
|
||||
suite.SetupTest()
|
||||
@ -167,7 +162,7 @@ func (suite *tallyHandlerSuite) TestTallyOutcomes() {
|
||||
|
||||
passes, burns, tally := suite.tallier.Tally(suite.ctx, proposal)
|
||||
suite.Truef(passes, "expected proposal to pass, tally: %v", tally)
|
||||
suite.Falsef(burns, "expected desposit to not burn, tally: %v", tally)
|
||||
suite.Falsef(burns, "expected deposit to not burn, tally: %v", tally)
|
||||
})
|
||||
suite.Run("UnvetoedAndYesBelowThresholdFails", func() {
|
||||
suite.SetupTest()
|
||||
@ -184,7 +179,7 @@ func (suite *tallyHandlerSuite) TestTallyOutcomes() {
|
||||
|
||||
passes, burns, tally := suite.tallier.Tally(suite.ctx, proposal)
|
||||
suite.Falsef(passes, "expected proposal to pass, tally: %v", tally)
|
||||
suite.Falsef(burns, "expected desposit to not burn, tally: %v", tally)
|
||||
suite.Falsef(burns, "expected deposit to not burn, tally: %v", tally)
|
||||
})
|
||||
suite.Run("NotEnoughStakeFails", func() {
|
||||
suite.SetupTest()
|
||||
@ -196,7 +191,7 @@ func (suite *tallyHandlerSuite) TestTallyOutcomes() {
|
||||
|
||||
passes, burns, tally := suite.tallier.Tally(suite.ctx, proposal)
|
||||
suite.Falsef(passes, "expected proposal to pass, tally: %v", tally)
|
||||
suite.Falsef(burns, "expected desposit to not burn, tally: %v", tally)
|
||||
suite.Falsef(burns, "expected deposit to not burn, tally: %v", tally)
|
||||
})
|
||||
suite.Run("UnvetoedAndAllAbstainedFails", func() {
|
||||
suite.SetupTest()
|
||||
@ -209,17 +204,18 @@ func (suite *tallyHandlerSuite) TestTallyOutcomes() {
|
||||
|
||||
passes, burns, tally := suite.tallier.Tally(suite.ctx, proposal)
|
||||
suite.Falsef(passes, "expected proposal to pass, tally: %v", tally)
|
||||
suite.Falsef(burns, "expected desposit to not burn, tally: %v", tally)
|
||||
suite.Falsef(burns, "expected deposit to not burn, tally: %v", tally)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (suite *tallyHandlerSuite) setTallyParams(quorum, threshold, veto sdk.Dec) {
|
||||
suite.app.GetGovKeeper().SetTallyParams(suite.ctx, govv1.TallyParams{
|
||||
Quorum: quorum.String(),
|
||||
Threshold: threshold.String(),
|
||||
VetoThreshold: veto.String(),
|
||||
})
|
||||
params := suite.app.GetGovKeeper().GetParams(suite.ctx)
|
||||
params.Quorum = quorum.String()
|
||||
params.Threshold = threshold.String()
|
||||
params.VetoThreshold = veto.String()
|
||||
params.BurnVoteQuorum = true
|
||||
suite.app.GetGovKeeper().SetParams(suite.ctx, params)
|
||||
}
|
||||
|
||||
func (suite *tallyHandlerSuite) voteOnProposal(
|
||||
@ -240,7 +236,7 @@ func (suite *tallyHandlerSuite) voteOnProposal(
|
||||
|
||||
func (suite *tallyHandlerSuite) createProposal() govv1.Proposal {
|
||||
gk := suite.app.GetGovKeeper()
|
||||
deposit := gk.GetDepositParams(suite.ctx).MinDeposit
|
||||
deposit := gk.GetParams(suite.ctx).MinDeposit
|
||||
proposer := suite.createAccount(deposit...)
|
||||
|
||||
msg, err := govv1beta1.NewMsgSubmitProposal(
|
||||
@ -250,7 +246,7 @@ func (suite *tallyHandlerSuite) createProposal() govv1.Proposal {
|
||||
)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
msgServerv1 := govkeeper.NewMsgServerImpl(gk)
|
||||
msgServerv1 := govkeeper.NewMsgServerImpl(&gk)
|
||||
|
||||
govAcct := gk.GetGovernanceAccount(suite.ctx).GetAddress()
|
||||
msgServer := govkeeper.NewLegacyMsgServerImpl(govAcct.String(), msgServerv1)
|
||||
@ -269,39 +265,40 @@ func (suite *tallyHandlerSuite) newBondCoin(amount sdkmath.Int) sdk.Coin {
|
||||
}
|
||||
|
||||
func (suite *tallyHandlerSuite) allowBKavaEarnDeposits() {
|
||||
ek := suite.app.GetEarnKeeper()
|
||||
earnParams := ek.GetParams(suite.ctx)
|
||||
// ek := suite.app.GetEarnKeeper()
|
||||
// earnParams := ek.GetParams(suite.ctx)
|
||||
|
||||
vault := earntypes.NewAllowedVault(
|
||||
liquidtypes.DefaultDerivativeDenom,
|
||||
earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS},
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
// vault := earntypes.NewAllowedVault(
|
||||
// liquidtypes.DefaultDerivativeDenom,
|
||||
// earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS},
|
||||
// false,
|
||||
// nil,
|
||||
// )
|
||||
|
||||
earnParams.AllowedVaults = append(earnParams.AllowedVaults, vault)
|
||||
ek.SetParams(suite.ctx, earnParams)
|
||||
// earnParams.AllowedVaults = append(earnParams.AllowedVaults, vault)
|
||||
// ek.SetParams(suite.ctx, earnParams)
|
||||
|
||||
sk := suite.app.GetSavingsKeeper()
|
||||
savingsParams := sk.GetParams(suite.ctx)
|
||||
savingsParams.SupportedDenoms = append(savingsParams.SupportedDenoms, liquidtypes.DefaultDerivativeDenom)
|
||||
sk.SetParams(suite.ctx, savingsParams)
|
||||
// sk := suite.app.GetSavingsKeeper()
|
||||
// savingsParams := sk.GetParams(suite.ctx)
|
||||
// savingsParams.SupportedDenoms = append(savingsParams.SupportedDenoms, liquidtypes.DefaultDerivativeDenom)
|
||||
// sk.SetParams(suite.ctx, savingsParams)
|
||||
}
|
||||
|
||||
func (suite *tallyHandlerSuite) earnDeposit(owner sdk.AccAddress, derivative sdk.Coin) {
|
||||
ek := suite.app.GetEarnKeeper()
|
||||
// ek := suite.app.GetEarnKeeper()
|
||||
|
||||
err := ek.Deposit(suite.ctx, owner, derivative, earntypes.STRATEGY_TYPE_SAVINGS)
|
||||
suite.Require().NoError(err)
|
||||
// err := ek.Deposit(suite.ctx, owner, derivative, earntypes.STRATEGY_TYPE_SAVINGS)
|
||||
// suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (suite *tallyHandlerSuite) mintDerivative(owner sdk.AccAddress, validator sdk.ValAddress, amount sdkmath.Int) sdk.Coin {
|
||||
lk := suite.app.GetLiquidKeeper()
|
||||
// lk := suite.app.GetLiquidKeeper()
|
||||
|
||||
minted, err := lk.MintDerivative(suite.ctx, owner, validator, suite.newBondCoin(amount))
|
||||
suite.Require().NoError(err)
|
||||
// minted, err := lk.MintDerivative(suite.ctx, owner, validator, suite.newBondCoin(amount))
|
||||
// suite.Require().NoError(err)
|
||||
|
||||
return minted
|
||||
// return minted
|
||||
return sdk.NewCoin("ukava", amount)
|
||||
}
|
||||
|
||||
func (suite *tallyHandlerSuite) delegateToNewBondedValidator(delegator sdk.AccAddress, amount sdkmath.Int) stakingtypes.ValidatorI {
|
||||
@ -369,7 +366,7 @@ func (h stakingHelper) createUnbondedValidator(ctx sdk.Context, address sdk.ValA
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgServer := stakingkeeper.NewMsgServerImpl(h.keeper)
|
||||
msgServer := stakingkeeper.NewMsgServerImpl(&h.keeper)
|
||||
_, err = msgServer.CreateValidator(sdk.WrapSDKContext(ctx), msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -389,7 +386,7 @@ func (h stakingHelper) delegate(ctx sdk.Context, delegator sdk.AccAddress, valid
|
||||
h.newBondCoin(ctx, amount),
|
||||
)
|
||||
|
||||
msgServer := stakingkeeper.NewMsgServerImpl(h.keeper)
|
||||
msgServer := stakingkeeper.NewMsgServerImpl(&h.keeper)
|
||||
_, err := msgServer.Delegate(sdk.WrapSDKContext(ctx), msg)
|
||||
if err != nil {
|
||||
return sdk.Dec{}, err
|
||||
|
@ -13,10 +13,10 @@ import (
|
||||
// All methods return the builder so method calls can be chained together.
|
||||
//
|
||||
// Example:
|
||||
// // create a single account genesis state
|
||||
// builder := NewAuthBankGenesisBuilder().WithSimpleAccount(testUserAddress, testCoins)
|
||||
// genesisState := builder.BuildMarshalled()
|
||||
//
|
||||
// // create a single account genesis state
|
||||
// builder := NewAuthBankGenesisBuilder().WithSimpleAccount(testUserAddress, testCoins)
|
||||
// genesisState := builder.BuildMarshalled()
|
||||
type AuthBankGenesisBuilder struct {
|
||||
AuthGenesis authtypes.GenesisState
|
||||
BankGenesis banktypes.GenesisState
|
||||
|
@ -9,6 +9,12 @@ import (
|
||||
"time"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
dasignerskeeper "github.com/0glabs/0g-chain/x/dasigners/v1/keeper"
|
||||
tmdb "github.com/cometbft/cometbft-db"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
tmtypes "github.com/cometbft/cometbft/types"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
@ -35,36 +41,24 @@ import (
|
||||
evmkeeper "github.com/evmos/ethermint/x/evm/keeper"
|
||||
feemarketkeeper "github.com/evmos/ethermint/x/feemarket/keeper"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
tmdb "github.com/tendermint/tm-db"
|
||||
|
||||
auctionkeeper "github.com/kava-labs/kava/x/auction/keeper"
|
||||
bep3keeper "github.com/kava-labs/kava/x/bep3/keeper"
|
||||
cdpkeeper "github.com/kava-labs/kava/x/cdp/keeper"
|
||||
committeekeeper "github.com/kava-labs/kava/x/committee/keeper"
|
||||
communitykeeper "github.com/kava-labs/kava/x/community/keeper"
|
||||
earnkeeper "github.com/kava-labs/kava/x/earn/keeper"
|
||||
evmutilkeeper "github.com/kava-labs/kava/x/evmutil/keeper"
|
||||
hardkeeper "github.com/kava-labs/kava/x/hard/keeper"
|
||||
incentivekeeper "github.com/kava-labs/kava/x/incentive/keeper"
|
||||
issuancekeeper "github.com/kava-labs/kava/x/issuance/keeper"
|
||||
kavadistkeeper "github.com/kava-labs/kava/x/kavadist/keeper"
|
||||
liquidkeeper "github.com/kava-labs/kava/x/liquid/keeper"
|
||||
pricefeedkeeper "github.com/kava-labs/kava/x/pricefeed/keeper"
|
||||
routerkeeper "github.com/kava-labs/kava/x/router/keeper"
|
||||
savingskeeper "github.com/kava-labs/kava/x/savings/keeper"
|
||||
swapkeeper "github.com/kava-labs/kava/x/swap/keeper"
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
bep3keeper "github.com/0glabs/0g-chain/x/bep3/keeper"
|
||||
committeekeeper "github.com/0glabs/0g-chain/x/committee/keeper"
|
||||
evmutilkeeper "github.com/0glabs/0g-chain/x/evmutil/keeper"
|
||||
issuancekeeper "github.com/0glabs/0g-chain/x/issuance/keeper"
|
||||
precisebankkeeper "github.com/0glabs/0g-chain/x/precisebank/keeper"
|
||||
pricefeedkeeper "github.com/0glabs/0g-chain/x/pricefeed/keeper"
|
||||
wrappeda0gibasekeeper "github.com/0glabs/0g-chain/x/wrapped-a0gi-base/keeper"
|
||||
)
|
||||
|
||||
var (
|
||||
emptyTime time.Time
|
||||
testChainID = "kavatest_1-1"
|
||||
defaultInitialHeight int64 = 1
|
||||
)
|
||||
|
||||
const TestChainId = "zgchain_8888-1"
|
||||
|
||||
// TestApp is a simple wrapper around an App. It exposes internal keepers for use in integration tests.
|
||||
// This file also contains test helpers. Ideally they would be in separate package.
|
||||
// Basic Usage:
|
||||
@ -88,7 +82,7 @@ type TestApp struct {
|
||||
//
|
||||
// Note, it also sets the sdk config with the app's address prefix, coin type, etc.
|
||||
func NewTestApp() TestApp {
|
||||
SetSDKConfig()
|
||||
chaincfg.SetSDKConfig()
|
||||
|
||||
return NewTestAppFromSealed()
|
||||
}
|
||||
@ -99,43 +93,45 @@ func NewTestAppFromSealed() TestApp {
|
||||
|
||||
encCfg := MakeEncodingConfig()
|
||||
|
||||
app := NewApp(log.NewNopLogger(), db, DefaultNodeHome, nil, encCfg, DefaultOptions)
|
||||
bApp := NewBaseApp(log.NewNopLogger(), db, encCfg, baseapp.SetChainID(TestChainId))
|
||||
app := NewApp(
|
||||
chaincfg.DefaultNodeHome, nil,
|
||||
encCfg, DefaultOptions, bApp,
|
||||
)
|
||||
return TestApp{App: *app}
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (tApp TestApp) GetAccountKeeper() authkeeper.AccountKeeper { return tApp.accountKeeper }
|
||||
func (tApp TestApp) GetBankKeeper() bankkeeper.Keeper { return tApp.bankKeeper }
|
||||
func (tApp TestApp) GetMintKeeper() mintkeeper.Keeper { return tApp.mintKeeper }
|
||||
func (tApp TestApp) GetStakingKeeper() stakingkeeper.Keeper { return tApp.stakingKeeper }
|
||||
func (tApp TestApp) GetSlashingKeeper() slashingkeeper.Keeper { return tApp.slashingKeeper }
|
||||
func (tApp TestApp) GetDistrKeeper() distkeeper.Keeper { return tApp.distrKeeper }
|
||||
func (tApp TestApp) GetGovKeeper() govkeeper.Keeper { return tApp.govKeeper }
|
||||
func (tApp TestApp) GetCrisisKeeper() crisiskeeper.Keeper { return tApp.crisisKeeper }
|
||||
func (tApp TestApp) GetParamsKeeper() paramskeeper.Keeper { return tApp.paramsKeeper }
|
||||
func (tApp TestApp) GetKavadistKeeper() kavadistkeeper.Keeper { return tApp.kavadistKeeper }
|
||||
func (tApp TestApp) GetAuctionKeeper() auctionkeeper.Keeper { return tApp.auctionKeeper }
|
||||
func (tApp TestApp) GetIssuanceKeeper() issuancekeeper.Keeper { return tApp.issuanceKeeper }
|
||||
func (tApp TestApp) GetBep3Keeper() bep3keeper.Keeper { return tApp.bep3Keeper }
|
||||
func (tApp TestApp) GetPriceFeedKeeper() pricefeedkeeper.Keeper { return tApp.pricefeedKeeper }
|
||||
func (tApp TestApp) GetSwapKeeper() swapkeeper.Keeper { return tApp.swapKeeper }
|
||||
func (tApp TestApp) GetCDPKeeper() cdpkeeper.Keeper { return tApp.cdpKeeper }
|
||||
func (tApp TestApp) GetHardKeeper() hardkeeper.Keeper { return tApp.hardKeeper }
|
||||
func (tApp TestApp) GetCommitteeKeeper() committeekeeper.Keeper { return tApp.committeeKeeper }
|
||||
func (tApp TestApp) GetIncentiveKeeper() incentivekeeper.Keeper { return tApp.incentiveKeeper }
|
||||
func (tApp TestApp) GetEvmutilKeeper() evmutilkeeper.Keeper { return tApp.evmutilKeeper }
|
||||
func (tApp TestApp) GetEvmKeeper() *evmkeeper.Keeper { return tApp.evmKeeper }
|
||||
func (tApp TestApp) GetSavingsKeeper() savingskeeper.Keeper { return tApp.savingsKeeper }
|
||||
func (tApp TestApp) GetFeeMarketKeeper() feemarketkeeper.Keeper { return tApp.feeMarketKeeper }
|
||||
func (tApp TestApp) GetLiquidKeeper() liquidkeeper.Keeper { return tApp.liquidKeeper }
|
||||
func (tApp TestApp) GetEarnKeeper() earnkeeper.Keeper { return tApp.earnKeeper }
|
||||
func (tApp TestApp) GetRouterKeeper() routerkeeper.Keeper { return tApp.routerKeeper }
|
||||
func (tApp TestApp) GetCommunityKeeper() communitykeeper.Keeper { return tApp.communityKeeper }
|
||||
func (tApp TestApp) GetAccountKeeper() authkeeper.AccountKeeper { return tApp.accountKeeper }
|
||||
func (tApp TestApp) GetBankKeeper() bankkeeper.Keeper { return tApp.bankKeeper }
|
||||
func (tApp TestApp) GetMintKeeper() mintkeeper.Keeper { return tApp.mintKeeper }
|
||||
func (tApp TestApp) GetStakingKeeper() *stakingkeeper.Keeper { return tApp.stakingKeeper }
|
||||
func (tApp TestApp) GetSlashingKeeper() slashingkeeper.Keeper { return tApp.slashingKeeper }
|
||||
func (tApp TestApp) GetDistrKeeper() distkeeper.Keeper { return tApp.distrKeeper }
|
||||
func (tApp TestApp) GetGovKeeper() govkeeper.Keeper { return tApp.govKeeper }
|
||||
func (tApp TestApp) GetCrisisKeeper() crisiskeeper.Keeper { return tApp.crisisKeeper }
|
||||
func (tApp TestApp) GetParamsKeeper() paramskeeper.Keeper { return tApp.paramsKeeper }
|
||||
func (tApp TestApp) GetIssuanceKeeper() issuancekeeper.Keeper { return tApp.issuanceKeeper }
|
||||
func (tApp TestApp) GetBep3Keeper() bep3keeper.Keeper { return tApp.bep3Keeper }
|
||||
func (tApp TestApp) GetPriceFeedKeeper() pricefeedkeeper.Keeper { return tApp.pricefeedKeeper }
|
||||
func (tApp TestApp) GetCommitteeKeeper() committeekeeper.Keeper { return tApp.committeeKeeper }
|
||||
func (tApp TestApp) GetEvmutilKeeper() evmutilkeeper.Keeper { return tApp.evmutilKeeper }
|
||||
func (tApp TestApp) GetEvmKeeper() *evmkeeper.Keeper { return tApp.evmKeeper }
|
||||
func (tApp TestApp) GetFeeMarketKeeper() *feemarketkeeper.Keeper { return tApp.feeMarketKeeper }
|
||||
func (tApp TestApp) GetDASignersKeeper() dasignerskeeper.Keeper { return tApp.dasignersKeeper }
|
||||
func (tApp TestApp) GetPrecisebankKeeper() precisebankkeeper.Keeper { return tApp.precisebankKeeper }
|
||||
func (tApp TestApp) GetWrappedA0GIBaseKeeper() wrappeda0gibasekeeper.Keeper {
|
||||
return tApp.wrappeda0gibaseKeeper
|
||||
}
|
||||
|
||||
func (tApp TestApp) GetKVStoreKey(key string) *storetypes.KVStoreKey {
|
||||
return tApp.keys[key]
|
||||
}
|
||||
|
||||
func (tApp TestApp) GetBlockedMaccAddrs() map[string]bool {
|
||||
return tApp.loadBlockedMaccAddrs()
|
||||
}
|
||||
|
||||
// LegacyAmino returns the app's amino codec.
|
||||
func (app *App) LegacyAmino() *codec.LegacyAmino {
|
||||
return app.legacyAmino
|
||||
@ -170,7 +166,7 @@ func GenesisStateWithSingleValidator(
|
||||
balances := []banktypes.Balance{
|
||||
{
|
||||
Address: acc.GetAddress().String(),
|
||||
Coins: sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(100000000000000))),
|
||||
Coins: sdk.NewCoins(chaincfg.MakeCoinForGasDenom(100000000000000)),
|
||||
},
|
||||
}
|
||||
|
||||
@ -233,7 +229,7 @@ func genesisStateWithValSet(
|
||||
}
|
||||
// set validators and delegations
|
||||
currentStakingGenesis := stakingtypes.GetGenesisStateFromAppState(app.appCodec, genesisState)
|
||||
currentStakingGenesis.Params.BondDenom = "ukava"
|
||||
currentStakingGenesis.Params.BondDenom = chaincfg.GasDenom // TODO:
|
||||
|
||||
stakingGenesis := stakingtypes.NewGenesisState(
|
||||
currentStakingGenesis.Params,
|
||||
@ -253,13 +249,13 @@ func genesisStateWithValSet(
|
||||
|
||||
for range delegations {
|
||||
// add delegated tokens to total supply
|
||||
totalSupply = totalSupply.Add(sdk.NewCoin("ukava", bondAmt))
|
||||
totalSupply = totalSupply.Add(chaincfg.MakeCoinForGasDenom(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("ukava", bondAmt)},
|
||||
Coins: sdk.Coins{chaincfg.MakeCoinForGasDenom(bondAmt)},
|
||||
})
|
||||
|
||||
bankGenesis := banktypes.NewGenesisState(
|
||||
@ -267,6 +263,7 @@ func genesisStateWithValSet(
|
||||
balances,
|
||||
totalSupply,
|
||||
currentBankGenesis.DenomMetadata,
|
||||
currentBankGenesis.SendEnabled,
|
||||
)
|
||||
|
||||
// set genesis state
|
||||
@ -280,13 +277,13 @@ func genesisStateWithValSet(
|
||||
// InitializeFromGenesisStates calls InitChain on the app using the provided genesis states.
|
||||
// If any module genesis states are missing, defaults are used.
|
||||
func (tApp TestApp) InitializeFromGenesisStates(genesisStates ...GenesisState) TestApp {
|
||||
return tApp.InitializeFromGenesisStatesWithTimeAndChainIDAndHeight(emptyTime, testChainID, defaultInitialHeight, true, genesisStates...)
|
||||
return tApp.InitializeFromGenesisStatesWithTimeAndChainIDAndHeight(emptyTime, TestChainId, defaultInitialHeight, true, genesisStates...)
|
||||
}
|
||||
|
||||
// InitializeFromGenesisStatesWithTime calls InitChain on the app using the provided genesis states and time.
|
||||
// If any module genesis states are missing, defaults are used.
|
||||
func (tApp TestApp) InitializeFromGenesisStatesWithTime(genTime time.Time, genesisStates ...GenesisState) TestApp {
|
||||
return tApp.InitializeFromGenesisStatesWithTimeAndChainIDAndHeight(genTime, testChainID, defaultInitialHeight, true, genesisStates...)
|
||||
return tApp.InitializeFromGenesisStatesWithTimeAndChainIDAndHeight(genTime, TestChainId, defaultInitialHeight, true, genesisStates...)
|
||||
}
|
||||
|
||||
// InitializeFromGenesisStatesWithTimeAndChainID calls InitChain on the app using the provided genesis states, time, and chain id.
|
||||
@ -343,8 +340,8 @@ func (tApp TestApp) InitializeFromGenesisStatesWithTimeAndChainIDAndHeight(
|
||||
AppStateBytes: stateBytes,
|
||||
ChainId: chainID,
|
||||
// Set consensus params, which is needed by x/feemarket
|
||||
ConsensusParams: &abci.ConsensusParams{
|
||||
Block: &abci.BlockParams{
|
||||
ConsensusParams: &tmproto.ConsensusParams{
|
||||
Block: &tmproto.BlockParams{
|
||||
MaxBytes: 200000,
|
||||
MaxGas: 20000000,
|
||||
},
|
||||
@ -465,21 +462,7 @@ func (tApp TestApp) CreateNewUnbondedValidator(ctx sdk.Context, valAddress sdk.V
|
||||
return err
|
||||
}
|
||||
|
||||
func (tApp TestApp) SetInflation(ctx sdk.Context, value sdk.Dec) {
|
||||
mk := tApp.GetMintKeeper()
|
||||
|
||||
mintParams := mk.GetParams(ctx)
|
||||
mintParams.InflationMax = sdk.ZeroDec()
|
||||
mintParams.InflationMin = sdk.ZeroDec()
|
||||
|
||||
if err := mintParams.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
mk.SetParams(ctx, mintParams)
|
||||
}
|
||||
|
||||
// GeneratePrivKeyAddressPairsFromRand generates (deterministically) a total of n private keys and addresses.
|
||||
// GeneratePrivKeyAddressPairs generates (deterministically) a total of n private keys and addresses.
|
||||
func GeneratePrivKeyAddressPairs(n int) (keys []cryptotypes.PrivKey, addrs []sdk.AccAddress) {
|
||||
r := rand.New(rand.NewSource(12345)) // make the generation deterministic
|
||||
keys = make([]cryptotypes.PrivKey, n)
|
||||
|
@ -1,3 +1,71 @@
|
||||
package app
|
||||
|
||||
func (app App) RegisterUpgradeHandlers() {}
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
wrappeda0gibasetypes "github.com/0glabs/0g-chain/x/wrapped-a0gi-base/types"
|
||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||
)
|
||||
|
||||
const (
|
||||
UpgradeName_Testnet = "v0.5.0"
|
||||
)
|
||||
|
||||
// RegisterUpgradeHandlers registers the upgrade handlers for the app.
|
||||
func (app App) RegisterUpgradeHandlers() {
|
||||
app.upgradeKeeper.SetUpgradeHandler(
|
||||
UpgradeName_Testnet,
|
||||
upgradeHandler(app, UpgradeName_Testnet),
|
||||
)
|
||||
|
||||
upgradeInfo, err := app.upgradeKeeper.ReadUpgradeInfoFromDisk()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
doUpgrade := upgradeInfo.Name == UpgradeName_Testnet
|
||||
|
||||
if doUpgrade && !app.upgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
|
||||
storeUpgrades := storetypes.StoreUpgrades{
|
||||
Added: []string{
|
||||
wrappeda0gibasetypes.ModuleName,
|
||||
},
|
||||
}
|
||||
|
||||
// configure store loader that checks if version == upgradeHeight and applies store upgrades
|
||||
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
|
||||
}
|
||||
}
|
||||
|
||||
// upgradeHandler returns an UpgradeHandler for the given upgrade parameters.
|
||||
func upgradeHandler(
|
||||
app App,
|
||||
name string,
|
||||
) upgradetypes.UpgradeHandler {
|
||||
return func(
|
||||
ctx sdk.Context,
|
||||
plan upgradetypes.Plan,
|
||||
fromVM module.VersionMap,
|
||||
) (module.VersionMap, error) {
|
||||
logger := app.Logger()
|
||||
logger.Info(fmt.Sprintf("running %s upgrade handler", name))
|
||||
|
||||
// Run migrations for all modules and return new consensus version map.
|
||||
versionMap, err := app.mm.RunMigrations(ctx, app.configurator, fromVM)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
app.mintKeeper.InitGenesis(ctx, app.accountKeeper, &minttypes.GenesisState{
|
||||
BondDenom: "ua0gi",
|
||||
})
|
||||
|
||||
logger.Info("completed store migrations")
|
||||
|
||||
return versionMap, nil
|
||||
}
|
||||
}
|
||||
|
1
app/upgrades_test.go
Normal file
1
app/upgrades_test.go
Normal file
@ -0,0 +1 @@
|
||||
package app_test
|
@ -28,9 +28,9 @@ DIRS := $(BUILD_CACHE_DIR) $(BIN_DIR)
|
||||
### Tool Versions ###
|
||||
################################################################################
|
||||
GO_BIN ?= go
|
||||
PROTOC_VERSION ?= v21.9
|
||||
BUF_VERSION ?= v1.9.0
|
||||
PROTOC_GEN_GOCOSMOS_VERSION ?= v0.3.1
|
||||
PROTOC_VERSION ?= v25.1
|
||||
BUF_VERSION ?= v1.28.1
|
||||
PROTOC_GEN_GOCOSMOS_VERSION ?= $(shell $(GO_BIN) list -m -f '{{.Version}}' github.com/cosmos/gogoproto)
|
||||
PROTOC_GEN_GRPC_GATEWAY_VERSION ?= $(shell $(GO_BIN) list -m github.com/grpc-ecosystem/grpc-gateway| sed 's:.* ::')
|
||||
PROTOC_GEN_DOC_VERSION ?= v1.5.1
|
||||
SWAGGER_COMBINE_VERSION ?= v1.4.0
|
||||
@ -68,7 +68,7 @@ $(PROTOC_VERSION_FILE):
|
||||
mkdir -p protoc && cd protoc; \
|
||||
curl -sOL $(PROTOC_DOWNLOAD_URL); \
|
||||
unzip -q $(PROTOC_ARCHIVE_NAME) bin/protoc
|
||||
@cp $(BUILD_CACHE_DIR)/protoc/bin/protoc $(BIN_DIR)/protoc
|
||||
@cp -f $(BUILD_CACHE_DIR)/protoc/bin/protoc $(BIN_DIR)/protoc
|
||||
@rm -rf $(BUILD_CACHE_DIR)/protoc
|
||||
|
||||
PROTOC := $(BIN_DIR)/protoc
|
||||
@ -93,7 +93,7 @@ $(BUF_VERSION_FILE):
|
||||
mkdir -p buf && cd buf; \
|
||||
curl -sOL $(BUF_DOWNLOAD_URL); \
|
||||
tar -xzf $(BUF_ARCHIVE_NAME) buf/bin/buf
|
||||
@cp $(BUILD_CACHE_DIR)/buf/buf/bin/buf $(BIN_DIR)/buf
|
||||
@cp -f $(BUILD_CACHE_DIR)/buf/buf/bin/buf $(BIN_DIR)/buf
|
||||
@rm -rf $(BUILD_CACHE_DIR)/buf
|
||||
|
||||
BUF := $(BIN_DIR)/buf
|
||||
@ -113,8 +113,8 @@ $(PROTOC_GEN_GOCOSMOS_VERSION_FILE):
|
||||
@touch $(PROTOC_GEN_GOCOSMOS_VERSION_FILE)
|
||||
@cd $(BUILD_CACHE_DIR); \
|
||||
mkdir -p protoc-gen-gocosmos && cd protoc-gen-gocosmos; \
|
||||
git clone -q https://github.com/regen-network/cosmos-proto.git; \
|
||||
cd cosmos-proto; \
|
||||
git clone -q https://github.com/cosmos/gogoproto.git; \
|
||||
cd gogoproto; \
|
||||
git checkout -q $(PROTOC_GEN_GOCOSMOS_VERSION); \
|
||||
GOBIN=$(ROOT_DIR)/$(BIN_DIR) $(GO_BIN) install ./protoc-gen-gocosmos
|
||||
@rm -rf $(BUILD_CACHE_DIR)/protoc-gen-gocosmos
|
||||
@ -185,7 +185,7 @@ $(PROTOC_GEN_DOC_VERSION_FILE):
|
||||
mkdir -p protoc-gen-doc && cd protoc-gen-doc; \
|
||||
curl -sOL $(PROTOC_GEN_DOC_DOWNLOAD_URL); \
|
||||
tar -xzf $(PROTOC_GEN_DOC_ARCHIVE_NAME) protoc-gen-doc
|
||||
@cp $(BUILD_CACHE_DIR)/protoc-gen-doc/protoc-gen-doc $(BIN_DIR)/protoc-gen-doc
|
||||
@cp -f $(BUILD_CACHE_DIR)/protoc-gen-doc/protoc-gen-doc $(BIN_DIR)/protoc-gen-doc
|
||||
@rm -rf $(BUILD_CACHE_DIR)/protoc-gen-doc
|
||||
|
||||
PROTOC_GEN_DOC := $(BIN_DIR)/protoc-gen-doc
|
||||
|
45
build/lint.mk
Normal file
45
build/lint.mk
Normal file
@ -0,0 +1,45 @@
|
||||
################################################################################
|
||||
### Required Variables ###
|
||||
################################################################################
|
||||
ifndef DOCKER
|
||||
$(error DOCKER not set)
|
||||
endif
|
||||
|
||||
ifndef BUILD_DIR
|
||||
$(error BUILD_DIR not set)
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
### Lint Settings ###
|
||||
################################################################################
|
||||
|
||||
LINT_FROM_REV ?= $(shell git merge-base origin/master HEAD)
|
||||
|
||||
GOLANGCI_VERSION ?= $(shell cat .golangci-version)
|
||||
GOLANGCI_IMAGE_TAG ?= golangci/golangci-lint:$(GOLANGCI_VERSION)
|
||||
|
||||
GOLANGCI_DIR ?= $(CURDIR)/$(BUILD_DIR)/.golangci-lint
|
||||
|
||||
GOLANGCI_CACHE_DIR ?= $(GOLANGCI_DIR)/$(GOLANGCI_VERSION)-cache
|
||||
GOLANGCI_MOD_CACHE_DIR ?= $(GOLANGCI_DIR)/go-mod
|
||||
|
||||
################################################################################
|
||||
### Lint Target ###
|
||||
################################################################################
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(GOLANGCI_CACHE_DIR) $(GOLANGCI_MOD_CACHE_DIR)
|
||||
@echo "Running lint from rev $(LINT_FROM_REV), use LINT_FROM_REV var to override."
|
||||
$(DOCKER) run -t --rm \
|
||||
-v $(GOLANGCI_CACHE_DIR):/root/.cache \
|
||||
-v $(GOLANGCI_MOD_CACHE_DIR):/go/pkg/mod \
|
||||
-v $(CURDIR):/app \
|
||||
-w /app \
|
||||
$(GOLANGCI_IMAGE_TAG) \
|
||||
golangci-lint run -v --new-from-rev $(LINT_FROM_REV)
|
||||
|
||||
$(GOLANGCI_CACHE_DIR):
|
||||
@mkdir -p $@
|
||||
|
||||
$(GOLANGCI_MOD_CACHE_DIR):
|
||||
@mkdir -p $@
|
@ -14,13 +14,23 @@ PROTOBUF_ANY_DOWNLOAD_URL = https://raw.githubusercontent.com/protocolbuffers/pr
|
||||
#
|
||||
# Proto dependencies under go.mod
|
||||
#
|
||||
GOGO_PATH := $(shell $(GO_BIN) list -m -f '{{.Dir}}' github.com/gogo/protobuf)
|
||||
TENDERMINT_PATH := $(shell $(GO_BIN) list -m -f '{{.Dir}}' github.com/tendermint/tendermint)
|
||||
GOGO_PATH := $(shell $(GO_BIN) list -m -f '{{.Dir}}' github.com/cosmos/gogoproto)
|
||||
TENDERMINT_PATH := $(shell $(GO_BIN) list -m -f '{{.Dir}}' github.com/cometbft/cometbft)
|
||||
COSMOS_PROTO_PATH := $(shell $(GO_BIN) list -m -f '{{.Dir}}' github.com/cosmos/cosmos-proto)
|
||||
COSMOS_SDK_PATH := $(shell $(GO_BIN) list -m -f '{{.Dir}}' github.com/cosmos/cosmos-sdk)
|
||||
IBC_GO_PATH := $(shell $(GO_BIN) list -m -f '{{.Dir}}' github.com/cosmos/ibc-go/v6)
|
||||
IBC_GO_PATH := $(shell $(GO_BIN) list -m -f '{{.Dir}}' github.com/cosmos/ibc-go/v7)
|
||||
ETHERMINT_PATH := $(shell $(GO_BIN) list -m -f '{{.Dir}}' github.com/evmos/ethermint)
|
||||
|
||||
#
|
||||
# ICS23 Proof Proto
|
||||
#
|
||||
ICS23_VERSION := $(shell $(GO_BIN) list -m -f '{{.Version}}' github.com/cosmos/ics23/go)
|
||||
|
||||
ICS23_PROOFS_PROTO_PATH := cosmos/ics23/v1/proofs.proto
|
||||
ICS23_PROOFS_PROTO_LOCAL_PATH := third_party/proto/$(ICS23_PROOFS_PROTO_PATH)
|
||||
|
||||
ICS23_PROOFS_PROTO_DOWNLOAD_URL := https://raw.githubusercontent.com/cosmos/ics23/go/$(ICS23_VERSION)/proto/$(ICS23_PROOFS_PROTO_PATH)
|
||||
|
||||
#
|
||||
# Common target directories
|
||||
#
|
||||
@ -44,18 +54,21 @@ proto-update-deps: check-rsync ## Update all third party proto files
|
||||
@curl -sSL $(PROTOBUF_ANY_DOWNLOAD_URL)/any.proto > $(PROTOBUF_GOOGLE_TYPES)/any.proto
|
||||
|
||||
@mkdir -p client/docs
|
||||
@cp $(COSMOS_SDK_PATH)/client/docs/swagger-ui/swagger.yaml client/docs/cosmos-swagger.yml
|
||||
@cp $(IBC_GO_PATH)/docs/client/swagger-ui/swagger.yaml client/docs/ibc-go-swagger.yml
|
||||
@cp -f $(COSMOS_SDK_PATH)/client/docs/swagger-ui/swagger.yaml client/docs/cosmos-swagger.yml
|
||||
@cp -f $(IBC_GO_PATH)/docs/client/swagger-ui/swagger.yaml client/docs/ibc-go-swagger.yml
|
||||
@cp -f $(ETHERMINT_PATH)/client/docs/swagger-ui/swagger.yaml client/docs/ethermint-swagger.yml
|
||||
|
||||
@mkdir -p $(COSMOS_PROTO_TYPES)
|
||||
@cp $(COSMOS_PROTO_PATH)/proto/cosmos_proto/cosmos.proto $(COSMOS_PROTO_TYPES)/cosmos.proto
|
||||
@cp -f $(COSMOS_PROTO_PATH)/proto/cosmos_proto/cosmos.proto $(COSMOS_PROTO_TYPES)/cosmos.proto
|
||||
|
||||
@mkdir -p $(dir $(ICS23_PROOFS_PROTO_LOCAL_PATH))
|
||||
@curl -sSL $(ICS23_PROOFS_PROTO_DOWNLOAD_URL) > $(ICS23_PROOFS_PROTO_LOCAL_PATH)
|
||||
|
||||
@$(RSYNC_BIN) -r --chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r --include "*.proto" --include='*/' --exclude='*' $(GOGO_PATH)/gogoproto third_party/proto
|
||||
@$(RSYNC_BIN) -r --chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r --include "*.proto" --include='*/' --exclude='*' $(TENDERMINT_PATH)/proto third_party
|
||||
@$(RSYNC_BIN) -r --chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r --include "*.proto" --include='*/' --exclude='*' $(COSMOS_SDK_PATH)/proto third_party
|
||||
@$(RSYNC_BIN) -r --chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r --include "*.proto" --include='*/' --exclude='*' $(IBC_GO_PATH)/proto third_party
|
||||
@$(RSYNC_BIN) -r --chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r --include "*.proto" --include='*/' --exclude='*' $(ETHERMINT_PATH)/proto third_party
|
||||
@cp -f $(IBC_GO_PATH)/third_party/proto/proofs.proto third_party/proto/proofs.proto
|
||||
|
||||
.PHONY: check-proto-deps
|
||||
check-proto-deps: proto-update-deps ## Return error code 1 if proto dependencies are not changed
|
||||
|
@ -1,13 +1,13 @@
|
||||
.PHONY: proto-lint check-proto-lint
|
||||
proto-lint check-proto-lint: install-build-deps
|
||||
@echo "Linting proto file"
|
||||
@$(BUF) lint
|
||||
@$(BUF) lint proto
|
||||
|
||||
.PHONY: proto-gen
|
||||
proto-gen: install-build-deps
|
||||
@echo "Generating go proto files"
|
||||
@$(BUF) generate --template proto/buf.gen.gogo.yaml proto
|
||||
@cp -r out/github.com/kava-labs/kava/* ./
|
||||
@cp -r out/github.com/0glabs/0g-chain/* ./
|
||||
@rm -rf out/github.com
|
||||
|
||||
.PHONY: check-proto-gen
|
||||
|
22
chaincfg/coin.go
Normal file
22
chaincfg/coin.go
Normal file
@ -0,0 +1,22 @@
|
||||
package chaincfg
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var (
|
||||
// Bip44CoinType satisfies EIP84. See https://github.com/ethereum/EIPs/issues/84 for more info.
|
||||
Bip44CoinType uint32 = 459 // TODO: need new coin type for 0g-chain (a0gi)
|
||||
// eth = 60
|
||||
// kava = 459 // see https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
||||
// BIP44HDPath is the default BIP44 HD path used on Ethereum.
|
||||
//BIP44HDPath = ethaccounts.DefaultBaseDerivationPath.String()
|
||||
)
|
||||
|
||||
// TODO: Implement BIP44CoinType and BIP44HDPath
|
||||
// SetBip44CoinType sets the global coin type to be used in hierarchical deterministic wallets.
|
||||
func setBip44CoinType(config *sdk.Config) {
|
||||
config.SetCoinType(Bip44CoinType)
|
||||
//config.SetPurpose(sdk.Purpose) // Shared
|
||||
//config.SetFullFundraiserPath(BIP44HDPath) //nolint: staticcheck
|
||||
}
|
57
chaincfg/coin_helper.go
Normal file
57
chaincfg/coin_helper.go
Normal file
@ -0,0 +1,57 @@
|
||||
package chaincfg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
func toBigInt(amount any) *big.Int {
|
||||
if amount == nil {
|
||||
return big.NewInt(0)
|
||||
}
|
||||
var val *big.Int
|
||||
switch amount.(type) {
|
||||
case int:
|
||||
val = big.NewInt(int64(amount.(int)))
|
||||
case int32:
|
||||
val = big.NewInt(int64(amount.(int32)))
|
||||
case int64:
|
||||
val = big.NewInt(amount.(int64))
|
||||
case string:
|
||||
var ok bool
|
||||
val, ok = new(big.Int).SetString(amount.(string), 0)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("invalid amount string: %s", amount.(string)))
|
||||
}
|
||||
case math.Int:
|
||||
val = amount.(math.Int).BigInt()
|
||||
case *big.Int:
|
||||
val = amount.(*big.Int)
|
||||
case float64:
|
||||
val = decimal.NewFromFloat(amount.(float64)).BigInt()
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid amount type: %T", amount))
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
func MakeCoinForStandardDenom(amount any) sdk.Coin {
|
||||
return makeCoin(StandardDenom, toBigInt(amount))
|
||||
}
|
||||
|
||||
func MakeCoinForGasDenom(amount any) sdk.Coin {
|
||||
return makeCoin(GasDenom, toBigInt(amount))
|
||||
}
|
||||
|
||||
func MakeCoinForEvmDenom(amount any) sdk.Coin {
|
||||
return makeCoin(EvmDenom, toBigInt(amount))
|
||||
}
|
||||
|
||||
func makeCoin(denom string, amount *big.Int) sdk.Coin {
|
||||
return sdk.NewCoin(denom, math.NewIntFromBigInt(amount))
|
||||
}
|
17
chaincfg/config.go
Normal file
17
chaincfg/config.go
Normal file
@ -0,0 +1,17 @@
|
||||
package chaincfg
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
AppName = "0gchaind"
|
||||
EnvPrefix = "0GCHAIN"
|
||||
)
|
||||
|
||||
func SetSDKConfig() *sdk.Config {
|
||||
config := sdk.GetConfig()
|
||||
setBech32Prefixes(config)
|
||||
setBip44CoinType(config)
|
||||
return config
|
||||
}
|
37
chaincfg/denoms.go
Normal file
37
chaincfg/denoms.go
Normal file
@ -0,0 +1,37 @@
|
||||
package chaincfg
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
StandardDenom = "a0gi"
|
||||
|
||||
GasDenom = "ua0gi"
|
||||
|
||||
EvmDenom = "neuron"
|
||||
|
||||
BondDenom = EvmDenom
|
||||
|
||||
GasDenomUnit = 6
|
||||
|
||||
EvmDenomUnit = 18
|
||||
|
||||
GasDenomConversionMultiplier = 1e12
|
||||
EvmDenomConversionMultiplier = 1e18
|
||||
)
|
||||
|
||||
// RegisterDenoms registers the base and gas denominations to the SDK.
|
||||
func RegisterDenoms() {
|
||||
if err := sdk.RegisterDenom(StandardDenom, sdk.OneDec()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := sdk.RegisterDenom(GasDenom, sdk.NewDecWithPrec(1, GasDenomUnit)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := sdk.RegisterDenom(EvmDenom, sdk.NewDecWithPrec(1, EvmDenomUnit)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
80
chaincfg/denoms_test.go
Normal file
80
chaincfg/denoms_test.go
Normal file
@ -0,0 +1,80 @@
|
||||
package chaincfg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRegisterDenoms(t *testing.T) {
|
||||
RegisterDenoms()
|
||||
tests := []struct {
|
||||
name string
|
||||
from sdk.Coin
|
||||
targetDenom string
|
||||
expCoin sdk.Coin
|
||||
expErr error
|
||||
}{
|
||||
{
|
||||
"standard to gas",
|
||||
MakeCoinForStandardDenom(99),
|
||||
GasDenom,
|
||||
MakeCoinForGasDenom(99 * (EvmDenomConversionMultiplier / GasDenomConversionMultiplier)),
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"gas to standard",
|
||||
MakeCoinForGasDenom(5e7),
|
||||
StandardDenom,
|
||||
MakeCoinForStandardDenom(50),
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"standard to base",
|
||||
MakeCoinForStandardDenom(22),
|
||||
EvmDenom,
|
||||
MakeCoinForEvmDenom(22 * EvmDenomConversionMultiplier),
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"base to standard",
|
||||
MakeCoinForEvmDenom("97000000000000000000"),
|
||||
StandardDenom,
|
||||
MakeCoinForStandardDenom(97),
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"gas to base",
|
||||
MakeCoinForGasDenom(33),
|
||||
EvmDenom,
|
||||
MakeCoinForEvmDenom(33 * GasDenomConversionMultiplier),
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"base to gas",
|
||||
MakeCoinForEvmDenom("770000000000000"),
|
||||
GasDenom,
|
||||
MakeCoinForGasDenom(770000000000000 / GasDenomConversionMultiplier),
|
||||
nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ret, err := sdk.ConvertCoin(tt.from, tt.targetDenom)
|
||||
if tt.expErr != nil {
|
||||
if err == nil {
|
||||
t.Errorf("expErr is not nil, but got nil")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expErr is nil, but got %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(t, tt.expCoin, ret)
|
||||
})
|
||||
}
|
||||
}
|
25
chaincfg/homedir.go
Normal file
25
chaincfg/homedir.go
Normal file
@ -0,0 +1,25 @@
|
||||
package chaincfg
|
||||
|
||||
import (
|
||||
stdlog "log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const (
|
||||
HomeDirName = ".0gchain"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultNodeHome default home directories for the application daemon
|
||||
DefaultNodeHome string
|
||||
)
|
||||
|
||||
func init() {
|
||||
userHomeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
stdlog.Printf("Failed to get home dir %v", err)
|
||||
}
|
||||
|
||||
DefaultNodeHome = filepath.Join(userHomeDir, HomeDirName)
|
||||
}
|
44
chaincfg/prefix.go
Normal file
44
chaincfg/prefix.go
Normal file
@ -0,0 +1,44 @@
|
||||
package chaincfg
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
// Bech32Prefix defines the Bech32 prefix used for EthAccounts
|
||||
Bech32Prefix = "0g"
|
||||
|
||||
// PrefixAccount is the prefix for account keys
|
||||
PrefixAccount = "acc"
|
||||
// PrefixValidator is the prefix for validator keys
|
||||
PrefixValidator = "val"
|
||||
// PrefixConsensus is the prefix for consensus keys
|
||||
PrefixConsensus = "cons"
|
||||
// PrefixPublic is the prefix for public keys
|
||||
PrefixPublic = "pub"
|
||||
// PrefixOperator is the prefix for operator keys
|
||||
PrefixOperator = "oper"
|
||||
|
||||
// PrefixAddress is the prefix for addresses
|
||||
PrefixAddress = "addr"
|
||||
|
||||
// Bech32PrefixAccAddr defines the Bech32 prefix of an account's address
|
||||
Bech32PrefixAccAddr = Bech32Prefix
|
||||
// Bech32PrefixAccPub defines the Bech32 prefix of an account's public key
|
||||
Bech32PrefixAccPub = Bech32Prefix + PrefixPublic
|
||||
// Bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address
|
||||
Bech32PrefixValAddr = Bech32Prefix + PrefixValidator + PrefixOperator
|
||||
// Bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key
|
||||
Bech32PrefixValPub = Bech32Prefix + PrefixValidator + PrefixOperator + PrefixPublic
|
||||
// Bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address
|
||||
Bech32PrefixConsAddr = Bech32Prefix + PrefixValidator + PrefixConsensus
|
||||
// Bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key
|
||||
Bech32PrefixConsPub = Bech32Prefix + PrefixValidator + PrefixConsensus + PrefixPublic
|
||||
)
|
||||
|
||||
// setBech32Prefixes sets the global prefixes to be used when serializing addresses and public keys to Bech32 strings.
|
||||
func setBech32Prefixes(config *sdk.Config) {
|
||||
config.SetBech32PrefixForAccount(Bech32PrefixAccAddr, Bech32PrefixAccPub)
|
||||
config.SetBech32PrefixForValidator(Bech32PrefixValAddr, Bech32PrefixValPub)
|
||||
config.SetBech32PrefixForConsensusNode(Bech32PrefixConsAddr, Bech32PrefixConsPub)
|
||||
}
|
2
ci/env/kava-internal-testnet/KAVA.VERSION
vendored
2
ci/env/kava-internal-testnet/KAVA.VERSION
vendored
@ -1 +1 @@
|
||||
a967d2fdda299ec8e1e3b99fb55bd06ecfdb0469
|
||||
6862cde560c70cb82f7908e6cef22ca223465bd2
|
||||
|
128
ci/env/kava-internal-testnet/genesis.json
vendored
128
ci/env/kava-internal-testnet/genesis.json
vendored
@ -22,6 +22,8 @@
|
||||
},
|
||||
"app_hash": "",
|
||||
"app_state": {
|
||||
"06-solomachine": null,
|
||||
"07-tendermint": null,
|
||||
"auction": {
|
||||
"next_auction_id": "1",
|
||||
"params": {
|
||||
@ -505,6 +507,10 @@
|
||||
{
|
||||
"address": "kava1vlpsrmdyuywvaqrv7rx6xga224sqfwz3fyfhwq",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "bnb",
|
||||
"amount": "500000000"
|
||||
},
|
||||
{
|
||||
"denom": "btcb",
|
||||
"amount": "200000000"
|
||||
@ -525,6 +531,10 @@
|
||||
"denom": "erc20/axelar/wbtc",
|
||||
"amount": "1000000000"
|
||||
},
|
||||
{
|
||||
"denom": "erc20/bitgo/wbtc",
|
||||
"amount": "200000000"
|
||||
},
|
||||
{
|
||||
"denom": "erc20/multichain/usdc",
|
||||
"amount": "1000000000000000000"
|
||||
@ -556,12 +566,20 @@
|
||||
{
|
||||
"denom": "usdx",
|
||||
"amount": "103000000000"
|
||||
},
|
||||
{
|
||||
"denom": "xrpb",
|
||||
"amount": "1000000000000000"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"address": "kava1krh7k30pc9rteejpl2zycj0vau58y8c69xkzws",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "bnb",
|
||||
"amount": "100000000000000000"
|
||||
},
|
||||
{
|
||||
"denom": "btcb",
|
||||
"amount": "200000000"
|
||||
@ -582,6 +600,14 @@
|
||||
"denom": "erc20/axelar/wbtc",
|
||||
"amount": "1000000000"
|
||||
},
|
||||
{
|
||||
"denom": "erc20/bitgo/wbtc",
|
||||
"amount": "200000000"
|
||||
},
|
||||
{
|
||||
"denom": "erc20/tether/usdt",
|
||||
"amount": "100000000000"
|
||||
},
|
||||
{
|
||||
"denom": "hard",
|
||||
"amount": "1000000000"
|
||||
@ -597,6 +623,10 @@
|
||||
{
|
||||
"denom": "usdx",
|
||||
"amount": "103000000000"
|
||||
},
|
||||
{
|
||||
"denom": "xrpb",
|
||||
"amount": "103000000000"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -818,6 +848,7 @@
|
||||
"gov_denom": "ukava",
|
||||
"params": {
|
||||
"circuit_breaker": false,
|
||||
"liquidation_block_interval": 500,
|
||||
"collateral_params": [
|
||||
{
|
||||
"denom": "bnb",
|
||||
@ -989,8 +1020,7 @@
|
||||
"check_collateralization_index_count": "10",
|
||||
"conversion_factor": "6"
|
||||
}
|
||||
]
|
||||
,
|
||||
],
|
||||
"debt_auction_lot": "10000000000",
|
||||
"debt_auction_threshold": "100000000000",
|
||||
"debt_param": {
|
||||
@ -1237,7 +1267,15 @@
|
||||
"votes": []
|
||||
},
|
||||
"community": {
|
||||
"params": {}
|
||||
"params": {
|
||||
"upgrade_time_disable_inflation": "2023-11-01T00:00:00Z",
|
||||
"upgrade_time_set_staking_rewards_per_second": "744191",
|
||||
"staking_rewards_per_second": "0"
|
||||
},
|
||||
"staking_rewards_state": {
|
||||
"last_accumulation_time": "0001-01-01T00:00:00Z",
|
||||
"last_truncation_error": "0"
|
||||
}
|
||||
},
|
||||
"crisis": {
|
||||
"constant_fee": {
|
||||
@ -2063,6 +2101,25 @@
|
||||
}
|
||||
],
|
||||
"nested_types": []
|
||||
},
|
||||
{
|
||||
"msg_type_url": "/kava.committee.v1beta1.MsgVote",
|
||||
"msg_value_type_name": "MsgValueCommitteeVote",
|
||||
"value_types": [
|
||||
{
|
||||
"name": "proposal_id",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"name": "voter",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "vote_type",
|
||||
"type": "int32"
|
||||
}
|
||||
],
|
||||
"nested_types": []
|
||||
}
|
||||
],
|
||||
"allow_unprotected_txs": false
|
||||
@ -2225,22 +2282,27 @@
|
||||
"deposits": [],
|
||||
"votes": [],
|
||||
"proposals": [],
|
||||
"deposit_params": {
|
||||
"deposit_params": null,
|
||||
"voting_params": {
|
||||
"voting_period": "604800s"
|
||||
},
|
||||
"tally_params": null,
|
||||
"params": {
|
||||
"min_deposit": [
|
||||
{
|
||||
"denom": "ukava",
|
||||
"amount": "10000000"
|
||||
}
|
||||
],
|
||||
"max_deposit_period": "172800s"
|
||||
},
|
||||
"voting_params": {
|
||||
"voting_period": "600s"
|
||||
},
|
||||
"tally_params": {
|
||||
"max_deposit_period": "172800s",
|
||||
"voting_period": "604800s",
|
||||
"quorum": "0.334000000000000000",
|
||||
"threshold": "0.500000000000000000",
|
||||
"veto_threshold": "0.334000000000000000"
|
||||
"veto_threshold": "0.334000000000000000",
|
||||
"min_initial_deposit_ratio": "0.000000000000000000",
|
||||
"burn_vote_quorum": false,
|
||||
"burn_proposal_deposit_prevote": false,
|
||||
"burn_vote_veto": true
|
||||
}
|
||||
},
|
||||
"hard": {
|
||||
@ -2515,6 +2577,24 @@
|
||||
},
|
||||
"reserve_factor": "0.025000000000000000",
|
||||
"keeper_reward_percentage": "0.020000000000000000"
|
||||
},
|
||||
{
|
||||
"denom": "erc20/bitgo/wbtc",
|
||||
"borrow_limit": {
|
||||
"has_max_limit": true,
|
||||
"maximum_limit": "0.000000000000000000",
|
||||
"loan_to_value": "0.000000000000000000"
|
||||
},
|
||||
"spot_market_id": "btc:usd:30",
|
||||
"conversion_factor": "100000000",
|
||||
"interest_rate_model": {
|
||||
"base_rate_apy": "0.000000000000000000",
|
||||
"base_multiplier": "0.050000000000000000",
|
||||
"kink": "0.800000000000000000",
|
||||
"jump_multiplier": "5.000000000000000000"
|
||||
},
|
||||
"reserve_factor": "0.025000000000000000",
|
||||
"keeper_reward_percentage": "0.020000000000000000"
|
||||
}
|
||||
],
|
||||
"minimum_borrow_usd_value": "10.000000000000000000"
|
||||
@ -2730,6 +2810,18 @@
|
||||
"amount": "787"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"collateral_type": "erc20/bitgo/wbtc",
|
||||
"start": "2022-11-11T15:00:00Z",
|
||||
"end": "2025-11-11T15:00:00Z",
|
||||
"rewards_per_second": [
|
||||
{
|
||||
"denom": "ukava",
|
||||
"amount": "787"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"hard_borrow_reward_periods": [],
|
||||
@ -3166,6 +3258,16 @@
|
||||
}
|
||||
},
|
||||
"params": null,
|
||||
"packetfowardmiddleware": {
|
||||
"params": {
|
||||
"fee_percentage": "0.000000000000000000"
|
||||
},
|
||||
"in_flight_packets": {}
|
||||
},
|
||||
"precisebank": {
|
||||
"balances": [],
|
||||
"remainder": "0"
|
||||
},
|
||||
"pricefeed": {
|
||||
"params": {
|
||||
"markets": [
|
||||
@ -3639,6 +3741,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"router": {},
|
||||
"savings": {
|
||||
"params": {
|
||||
"supported_denoms": [
|
||||
@ -3810,7 +3913,8 @@
|
||||
"params": {
|
||||
"send_enabled": true,
|
||||
"receive_enabled": true
|
||||
}
|
||||
},
|
||||
"total_escrowed": []
|
||||
},
|
||||
"upgrade": {},
|
||||
"validatorvesting": null,
|
||||
|
27
ci/env/kava-protonet/genesis.json
vendored
27
ci/env/kava-protonet/genesis.json
vendored
@ -837,6 +837,7 @@
|
||||
"gov_denom": "ukava",
|
||||
"params": {
|
||||
"circuit_breaker": false,
|
||||
"liquidation_block_interval": 500,
|
||||
"collateral_params": [
|
||||
{
|
||||
"auction_size": "50000000000",
|
||||
@ -2177,6 +2178,23 @@
|
||||
"quorum": "0.334000000000000000",
|
||||
"threshold": "0.500000000000000000",
|
||||
"veto_threshold": "0.334000000000000000"
|
||||
},
|
||||
"params": {
|
||||
"min_deposit": [
|
||||
{
|
||||
"denom": "ukava",
|
||||
"amount": "10000000"
|
||||
}
|
||||
],
|
||||
"max_deposit_period": "172800s",
|
||||
"voting_period": "600s",
|
||||
"quorum": "0.334000000000000000",
|
||||
"threshold": "0.500000000000000000",
|
||||
"veto_threshold": "0.334000000000000000",
|
||||
"min_initial_deposit_ratio": "0.000000000000000000",
|
||||
"burn_vote_quorum": false,
|
||||
"burn_proposal_deposit_prevote": false,
|
||||
"burn_vote_veto": true
|
||||
}
|
||||
},
|
||||
"hard": {
|
||||
@ -2982,6 +3000,15 @@
|
||||
}
|
||||
},
|
||||
"params": null,
|
||||
"packetfowardmiddleware": {
|
||||
"params": {
|
||||
"fee_percentage": "0.000000000000000000"
|
||||
},
|
||||
"in_flight_packets": {}
|
||||
},
|
||||
"precisebank": {
|
||||
"remainder": "0"
|
||||
},
|
||||
"pricefeed": {
|
||||
"params": {
|
||||
"markets": [
|
||||
|
@ -14,9 +14,9 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cometbft/cometbft/crypto/ed25519"
|
||||
tmtypes "github.com/cometbft/cometbft/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
@ -62,36 +62,36 @@ func TestKvCLIKeysAddRecover(t *testing.T) {
|
||||
|
||||
exitSuccess, _, _ = f.KeysAddRecover("test-recover", "dentist task convince chimney quality leave banana trade firm crawl eternal easily")
|
||||
require.True(t, exitSuccess)
|
||||
require.Equal(t, "kava1rsjxn2e4dfl3a2qzuzzjvvgjmmate383g9q4cz", f.KeyAddress("test-recover").String())
|
||||
require.Equal(t, "0g1rsjxn2e4dfl3a2qzuzzjvvgjmmate383g9q4cz", f.KeyAddress("test-recover").String())
|
||||
|
||||
// test old bip44 coin type
|
||||
exitSuccess, _, _ = f.KeysAddRecover("test-recover-legacy", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", "--legacy-hd-path")
|
||||
require.True(t, exitSuccess)
|
||||
require.Equal(t, "kava1qcfdf69js922qrdr4yaww3ax7gjml6pd39p8lj", f.KeyAddress("test-recover-legacy").String())
|
||||
require.Equal(t, "0g1qcfdf69js922qrdr4yaww3ax7gjml6pd39p8lj", f.KeyAddress("test-recover-legacy").String())
|
||||
|
||||
// Cleanup testing directories
|
||||
f.Cleanup()
|
||||
}
|
||||
|
||||
func TestKavaCLIKeysAddRecoverHDPath(t *testing.T) {
|
||||
func TestZgChainCLIKeysAddRecoverHDPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := InitFixtures(t)
|
||||
|
||||
f.KeysAddRecoverHDPath("test-recoverHD1", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", 0, 0)
|
||||
require.Equal(t, "kava1rsjxn2e4dfl3a2qzuzzjvvgjmmate383g9q4cz", f.KeyAddress("test-recoverHD1").String())
|
||||
require.Equal(t, "0g1rsjxn2e4dfl3a2qzuzzjvvgjmmate383g9q4cz", f.KeyAddress("test-recoverHD1").String())
|
||||
|
||||
f.KeysAddRecoverHDPath("test-recoverH2", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", 1, 5)
|
||||
require.Equal(t, "kava1qpj6nstqn0n5gzcsaezspuhulje6msjq5t8cq5", f.KeyAddress("test-recoverH2").String())
|
||||
require.Equal(t, "0g1qpj6nstqn0n5gzcsaezspuhulje6msjq5t8cq5", f.KeyAddress("test-recoverH2").String())
|
||||
|
||||
f.KeysAddRecoverHDPath("test-recoverH3", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", 1, 17)
|
||||
require.Equal(t, "kava1vayfpstgapt7dmv7074kc3ll8xpf0rlzvh4k08", f.KeyAddress("test-recoverH3").String())
|
||||
require.Equal(t, "0g1vayfpstgapt7dmv7074kc3ll8xpf0rlzvh4k08", f.KeyAddress("test-recoverH3").String())
|
||||
|
||||
f.KeysAddRecoverHDPath("test-recoverH4", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", 2, 17)
|
||||
require.Equal(t, "kava1xvsfnksmhr887skcfrm4pe3va54tkmrtw7wyer", f.KeyAddress("test-recoverH4").String())
|
||||
require.Equal(t, "0g1xvsfnksmhr887skcfrm4pe3va54tkmrtw7wyer", f.KeyAddress("test-recoverH4").String())
|
||||
|
||||
// test old bip44 coin type
|
||||
f.KeysAddRecoverHDPath("test-recoverH5", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", 2, 17, "--legacy-hd-path")
|
||||
require.Equal(t, "kava1v9plmhvyhgxk3th9ydacm7j4z357s3nhhmy0tv", f.KeyAddress("test-recoverH5").String())
|
||||
require.Equal(t, "0g1v9plmhvyhgxk3th9ydacm7j4z357s3nhhmy0tv", f.KeyAddress("test-recoverH5").String())
|
||||
|
||||
exitSuccess, _, _ := f.KeysAddRecover("test-recover-fail", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", "--legacy-hd-path --hd-path 44'/459'/0'/0/0")
|
||||
require.False(t, exitSuccess)
|
||||
@ -99,11 +99,11 @@ func TestKavaCLIKeysAddRecoverHDPath(t *testing.T) {
|
||||
// test -hd-path flag
|
||||
exitSuccess, _, _ = f.KeysAddRecover("test-recoverH6", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", "--hd-path 44'/459'/0'/0/0")
|
||||
require.True(t, exitSuccess)
|
||||
require.Equal(t, "kava1rsjxn2e4dfl3a2qzuzzjvvgjmmate383g9q4cz", f.KeyAddress("test-recoverH6").String())
|
||||
require.Equal(t, "0g1rsjxn2e4dfl3a2qzuzzjvvgjmmate383g9q4cz", f.KeyAddress("test-recoverH6").String())
|
||||
|
||||
exitSuccess, _, _ = f.KeysAddRecover("test-recoverH7", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", "--hd-path 44'/459'/2'/0/17")
|
||||
require.True(t, exitSuccess)
|
||||
require.Equal(t, "kava1xvsfnksmhr887skcfrm4pe3va54tkmrtw7wyer", f.KeyAddress("test-recoverH7").String())
|
||||
require.Equal(t, "0g1xvsfnksmhr887skcfrm4pe3va54tkmrtw7wyer", f.KeyAddress("test-recoverH7").String())
|
||||
|
||||
// Cleanup testing directories
|
||||
f.Cleanup()
|
||||
@ -813,7 +813,7 @@ func TestKvCLISubmitCommunityPoolSpendProposal(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKvCLIQueryTxPagination(t *testing.T) {
|
||||
// Skip until https://github.com/tendermint/tendermint/issues/4432 has been
|
||||
// Skip until https://github.com/cometbft/cometbft/issues/4432 has been
|
||||
// resolved and included in a release.
|
||||
t.SkipNow()
|
||||
|
||||
|
@ -13,13 +13,13 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
tmtypes "github.com/cometbft/cometbft/types"
|
||||
|
||||
"cosmossdk.io/simapp"
|
||||
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
@ -28,7 +28,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -65,8 +65,7 @@ var (
|
||||
|
||||
func init() {
|
||||
// set the address prefixes
|
||||
config := sdk.GetConfig()
|
||||
app.SetBech32AddressPrefixes(config)
|
||||
chaincfg.SetSDKConfig()
|
||||
// config.Seal()
|
||||
}
|
||||
|
||||
@ -92,7 +91,7 @@ type Fixtures struct {
|
||||
|
||||
// NewFixtures creates a new instance of Fixtures with many vars set
|
||||
func NewFixtures(t *testing.T) *Fixtures {
|
||||
tmpDir, err := ioutil.TempDir("", "kava_integration_"+t.Name()+"_")
|
||||
tmpDir, err := ioutil.TempDir("", "0gchain_integration_"+t.Name()+"_")
|
||||
require.NoError(t, err)
|
||||
|
||||
servAddr, port, err := server.FreeTCPAddr()
|
||||
@ -201,9 +200,9 @@ func (f *Fixtures) Flags() string {
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
// kavad
|
||||
// 0gchaind
|
||||
|
||||
// UnsafeResetAll is kavad unsafe-reset-all
|
||||
// UnsafeResetAll is 0gchaind unsafe-reset-all
|
||||
func (f *Fixtures) UnsafeResetAll(flags ...string) {
|
||||
cmd := fmt.Sprintf("%s --home=%s unsafe-reset-all", f.KvdBinary, f.KvdHome)
|
||||
executeWrite(f.T, addFlags(cmd, flags))
|
||||
@ -211,7 +210,7 @@ func (f *Fixtures) UnsafeResetAll(flags ...string) {
|
||||
require.NoError(f.T, err)
|
||||
}
|
||||
|
||||
// KvInit is kavad init
|
||||
// KvInit is 0gchaind init
|
||||
// NOTE: KvInit sets the ChainID for the Fixtures instance
|
||||
func (f *Fixtures) KvInit(moniker string, flags ...string) {
|
||||
cmd := fmt.Sprintf("%s init -o --home=%s %s", f.KvdBinary, f.KvdHome, moniker)
|
||||
@ -229,25 +228,25 @@ func (f *Fixtures) KvInit(moniker string, flags ...string) {
|
||||
f.ChainID = chainID
|
||||
}
|
||||
|
||||
// AddGenesisAccount is kavad add-genesis-account
|
||||
// AddGenesisAccount is 0gchaind add-genesis-account
|
||||
func (f *Fixtures) AddGenesisAccount(address sdk.AccAddress, coins sdk.Coins, flags ...string) {
|
||||
cmd := fmt.Sprintf("%s add-genesis-account %s %s --home=%s --keyring-backend=test", f.KvdBinary, address, coins, f.KvdHome)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags))
|
||||
}
|
||||
|
||||
// GenTx is kavad gentx
|
||||
// GenTx is 0gchaind gentx
|
||||
func (f *Fixtures) GenTx(name string, flags ...string) {
|
||||
cmd := fmt.Sprintf("%s gentx --name=%s --home=%s --home-client=%s --keyring-backend=test", f.KvdBinary, name, f.KvdHome, f.KvcliHome)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags))
|
||||
}
|
||||
|
||||
// CollectGenTxs is kavad collect-gentxs
|
||||
// CollectGenTxs is 0gchaind collect-gentxs
|
||||
func (f *Fixtures) CollectGenTxs(flags ...string) {
|
||||
cmd := fmt.Sprintf("%s collect-gentxs --home=%s", f.KvdBinary, f.KvdHome)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags))
|
||||
}
|
||||
|
||||
// GDStart runs kavad start with the appropriate flags and returns a process
|
||||
// GDStart runs 0gchaind start with the appropriate flags and returns a process
|
||||
func (f *Fixtures) GDStart(flags ...string) *tests.Process {
|
||||
cmd := fmt.Sprintf("%s start --home=%s --rpc.laddr=%v --p2p.laddr=%v --pruning=everything", f.KvdBinary, f.KvdHome, f.RPCAddr, f.P2PAddr)
|
||||
proc := tests.GoExecuteTWithStdout(f.T, addFlags(cmd, flags))
|
||||
@ -256,7 +255,7 @@ func (f *Fixtures) GDStart(flags ...string) *tests.Process {
|
||||
return proc
|
||||
}
|
||||
|
||||
// GDTendermint returns the results of kavad tendermint [query]
|
||||
// GDTendermint returns the results of 0gchaind tendermint [query]
|
||||
func (f *Fixtures) GDTendermint(query string) string {
|
||||
cmd := fmt.Sprintf("%s tendermint %s --home=%s", f.KvdBinary, query, f.KvdHome)
|
||||
success, stdout, stderr := executeWriteRetStdStreams(f.T, cmd)
|
||||
@ -265,7 +264,7 @@ func (f *Fixtures) GDTendermint(query string) string {
|
||||
return strings.TrimSpace(stdout)
|
||||
}
|
||||
|
||||
// ValidateGenesis runs kavad validate-genesis
|
||||
// ValidateGenesis runs 0gchaind validate-genesis
|
||||
func (f *Fixtures) ValidateGenesis() {
|
||||
cmd := fmt.Sprintf("%s validate-genesis --home=%s", f.KvdBinary, f.KvdHome)
|
||||
executeWriteCheckErr(f.T, cmd)
|
||||
|
@ -7,7 +7,7 @@
|
||||
},
|
||||
"externalDocs": {
|
||||
"description": "GitHub",
|
||||
"url": "https://github.com/Kava-Labs/kava"
|
||||
"url": "https://github.com/0glabs/0g-chain"
|
||||
},
|
||||
"host": "api.data.kava.io",
|
||||
"schemes": ["https"],
|
||||
@ -182,6 +182,23 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "./out/swagger/kava/precisebank/v1/query.swagger.json",
|
||||
"tags": {
|
||||
"rename": {
|
||||
"Query": "Precisebank"
|
||||
}
|
||||
},
|
||||
"operationIds": {
|
||||
"rename": [
|
||||
{
|
||||
"type": "regex",
|
||||
"from": "(.*)",
|
||||
"to": "Precisebank$1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "./out/swagger/kava/pricefeed/v1beta1/query.swagger.json",
|
||||
"tags": {
|
||||
@ -295,6 +312,30 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "./client/docs/ethermint-swagger.yml",
|
||||
"dereference": {
|
||||
"circular": "ignore"
|
||||
},
|
||||
"tags": {
|
||||
"rename": {
|
||||
"Query": "Ethermint"
|
||||
}
|
||||
},
|
||||
"operationIds": {
|
||||
"rename": [
|
||||
{
|
||||
"type": "regex",
|
||||
"from": "(.*)",
|
||||
"to": "Ethermint$1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"paths": {
|
||||
"exclude": [
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "./client/docs/legacy-swagger.yml",
|
||||
"dereference": {
|
||||
|
File diff suppressed because it is too large
Load Diff
4458
client/docs/ethermint-swagger.yml
Normal file
4458
client/docs/ethermint-swagger.yml
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
381
client/erc20/MintableBurnableERC20.abi
Normal file
381
client/erc20/MintableBurnableERC20.abi
Normal file
@ -0,0 +1,381 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "decimals_",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "previousOwner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnershipTransferred",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "burn",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "subtractedValue",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "decreaseAllowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "addedValue",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "increaseAllowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "mint",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "renounceOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
1
client/erc20/MintableBurnableERC20.bin
Normal file
1
client/erc20/MintableBurnableERC20.bin
Normal file
File diff suppressed because one or more lines are too long
1069
client/erc20/main.go
Normal file
1069
client/erc20/main.go
Normal file
File diff suppressed because one or more lines are too long
74
client/grpc/README.md
Normal file
74
client/grpc/README.md
Normal file
@ -0,0 +1,74 @@
|
||||
# Kava gRPC Client
|
||||
|
||||
The Kava gRPC client is a tool for making gRPC queries on a Kava chain.
|
||||
|
||||
## Features
|
||||
|
||||
- Easy-to-use gRPC client for the Kava chain.
|
||||
- Access all query clients for Cosmos and Kava modules using `client.Query` (e.g., `client.Query.Bank.Balance`).
|
||||
- Utilize utility functions for common queries (e.g., `client.BaseAccount(str)`).
|
||||
|
||||
## Usage
|
||||
|
||||
### Creating a new client
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
kavaGrpc "github.com/0glabs/0g-chain/client/grpc"
|
||||
)
|
||||
grpcUrl := "https://grpc.kava.io:443"
|
||||
client, err := kavaGrpc.NewClient(grpcUrl)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
```
|
||||
|
||||
### Making grpc queries
|
||||
|
||||
Query clients for both Cosmos and Kava modules are available via `client.Query`.
|
||||
|
||||
Example: Query Cosmos module `x/bank` for address balance
|
||||
|
||||
```go
|
||||
import (
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
rsp, err := client.Query.Bank.Balance(context.Background(), &banktypes.QueryBalanceRequest{
|
||||
Address: "kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
|
||||
Denom: "ukava",
|
||||
})
|
||||
```
|
||||
|
||||
Example: Query Kava module `x/evmutil` for params
|
||||
|
||||
```go
|
||||
import (
|
||||
evmutiltypes "github.com/0glabs/0g-chain/x/evmutil/types"
|
||||
)
|
||||
|
||||
rsp, err := client.Query.Evmutil.Params(
|
||||
context.Background(), &evmutiltypes.QueryParamsRequest{},
|
||||
)
|
||||
```
|
||||
|
||||
#### Query Utilities
|
||||
|
||||
Utility functions for common queries are available directly on the client.
|
||||
|
||||
Example: Util query to get a base account
|
||||
|
||||
```go
|
||||
kavaAcc := "kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92"
|
||||
rsp, err := client.BaseAccount(kavaAcc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("account sequence for %s: %d\n", kavaAcc, rsp.Sequence)
|
||||
```
|
||||
|
||||
## Query Tests
|
||||
|
||||
To test queries, a Kava node is required. Therefore, the e2e tests for the gRPC client queries can be found in the `tests/e2e` directory. Tests for new utility queries should be added as e2e tests under the `test/e2e` directory.
|
50
client/grpc/client.go
Normal file
50
client/grpc/client.go
Normal file
@ -0,0 +1,50 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/0glabs/0g-chain/client/grpc/query"
|
||||
"github.com/0glabs/0g-chain/client/grpc/util"
|
||||
)
|
||||
|
||||
// ZgChainGrpcClient enables the usage of kava grpc query clients and query utils
|
||||
type ZgChainGrpcClient struct {
|
||||
config ZgChainGrpcClientConfig
|
||||
|
||||
// Query clients for cosmos and kava modules
|
||||
Query *query.QueryClient
|
||||
|
||||
// Utils for common queries (ie fetch an unpacked BaseAccount)
|
||||
*util.Util
|
||||
}
|
||||
|
||||
// ZgChainGrpcClientConfig is a configuration struct for a ZgChainGrpcClient
|
||||
type ZgChainGrpcClientConfig struct {
|
||||
// note: add future config options here
|
||||
}
|
||||
|
||||
// NewClient creates a new ZgChainGrpcClient via a grpc url
|
||||
func NewClient(grpcUrl string) (*ZgChainGrpcClient, error) {
|
||||
return NewClientWithConfig(grpcUrl, NewDefaultConfig())
|
||||
}
|
||||
|
||||
// NewClientWithConfig creates a new ZgChainGrpcClient via a grpc url and config
|
||||
func NewClientWithConfig(grpcUrl string, config ZgChainGrpcClientConfig) (*ZgChainGrpcClient, error) {
|
||||
if grpcUrl == "" {
|
||||
return nil, errors.New("grpc url cannot be empty")
|
||||
}
|
||||
query, error := query.NewQueryClient(grpcUrl)
|
||||
if error != nil {
|
||||
return nil, error
|
||||
}
|
||||
client := &ZgChainGrpcClient{
|
||||
Query: query,
|
||||
Util: util.NewUtil(query),
|
||||
config: config,
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func NewDefaultConfig() ZgChainGrpcClientConfig {
|
||||
return ZgChainGrpcClientConfig{}
|
||||
}
|
15
client/grpc/client_test.go
Normal file
15
client/grpc/client_test.go
Normal file
@ -0,0 +1,15 @@
|
||||
package grpc_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/0glabs/0g-chain/client/grpc"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewClient_InvalidEndpoint(t *testing.T) {
|
||||
_, err := grpc.NewClient("invalid-url")
|
||||
require.ErrorContains(t, err, "unknown grpc url scheme")
|
||||
_, err = grpc.NewClient("")
|
||||
require.ErrorContains(t, err, "grpc url cannot be empty")
|
||||
}
|
52
client/grpc/query/connection.go
Normal file
52
client/grpc/query/connection.go
Normal file
@ -0,0 +1,52 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
// newGrpcConnection parses a GRPC endpoint and creates a connection to it
|
||||
func newGrpcConnection(ctx context.Context, endpoint string) (*grpc.ClientConn, error) {
|
||||
grpcUrl, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse grpc connection \"%s\": %v", endpoint, err)
|
||||
}
|
||||
|
||||
var creds credentials.TransportCredentials
|
||||
switch grpcUrl.Scheme {
|
||||
case "http":
|
||||
creds = insecure.NewCredentials()
|
||||
case "https":
|
||||
creds = credentials.NewTLS(&tls.Config{})
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown grpc url scheme: %s", grpcUrl.Scheme)
|
||||
}
|
||||
|
||||
// Ensure the encoding config is set up correctly with the query client
|
||||
// otherwise it will produce panics like:
|
||||
// invalid Go type math.Int for field ...
|
||||
encodingConfig := app.MakeEncodingConfig()
|
||||
protoCodec := codec.NewProtoCodec(encodingConfig.InterfaceRegistry)
|
||||
grpcCodec := protoCodec.GRPCCodec()
|
||||
|
||||
secureOpt := grpc.WithTransportCredentials(creds)
|
||||
grpcConn, err := grpc.DialContext(
|
||||
ctx,
|
||||
grpcUrl.Host,
|
||||
secureOpt,
|
||||
grpc.WithDefaultCallOptions(grpc.ForceCodec(grpcCodec)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return grpcConn, nil
|
||||
}
|
7
client/grpc/query/doc.go
Normal file
7
client/grpc/query/doc.go
Normal file
@ -0,0 +1,7 @@
|
||||
/*
|
||||
The query package includes Cosmos and Kava gRPC query clients.
|
||||
|
||||
To ensure that the `QueryClient` stays updated, add new module query clients
|
||||
to the `QueryClient` whenever new modules with grpc queries are added to the Kava app.
|
||||
*/
|
||||
package query
|
108
client/grpc/query/query.go
Normal file
108
client/grpc/query/query.go
Normal file
@ -0,0 +1,108 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
authz "github.com/cosmos/cosmos-sdk/x/authz"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
|
||||
disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
|
||||
govv1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
|
||||
govv1beta1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
|
||||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||
|
||||
ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
|
||||
ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
feemarkettypes "github.com/evmos/ethermint/x/feemarket/types"
|
||||
|
||||
bep3types "github.com/0glabs/0g-chain/x/bep3/types"
|
||||
committeetypes "github.com/0glabs/0g-chain/x/committee/types"
|
||||
evmutiltypes "github.com/0glabs/0g-chain/x/evmutil/types"
|
||||
issuancetypes "github.com/0glabs/0g-chain/x/issuance/types"
|
||||
precisebanktypes "github.com/0glabs/0g-chain/x/precisebank/types"
|
||||
pricefeedtypes "github.com/0glabs/0g-chain/x/pricefeed/types"
|
||||
)
|
||||
|
||||
// QueryClient is a wrapper with all Cosmos and Kava grpc query clients
|
||||
type QueryClient struct {
|
||||
// cosmos-sdk query clients
|
||||
|
||||
Tm tmservice.ServiceClient
|
||||
Tx txtypes.ServiceClient
|
||||
Auth authtypes.QueryClient
|
||||
Authz authz.QueryClient
|
||||
Bank banktypes.QueryClient
|
||||
Distribution disttypes.QueryClient
|
||||
Evidence evidencetypes.QueryClient
|
||||
Gov govv1types.QueryClient
|
||||
GovBeta govv1beta1types.QueryClient
|
||||
Mint minttypes.QueryClient
|
||||
Params paramstypes.QueryClient
|
||||
Slashing slashingtypes.QueryClient
|
||||
Staking stakingtypes.QueryClient
|
||||
Upgrade upgradetypes.QueryClient
|
||||
Consensus consensustypes.QueryClient
|
||||
|
||||
// 3rd party query clients
|
||||
|
||||
Evm evmtypes.QueryClient
|
||||
Feemarket feemarkettypes.QueryClient
|
||||
IbcClient ibcclienttypes.QueryClient
|
||||
IbcTransfer ibctransfertypes.QueryClient
|
||||
|
||||
// kava module query clients
|
||||
|
||||
Bep3 bep3types.QueryClient
|
||||
Committee committeetypes.QueryClient
|
||||
Evmutil evmutiltypes.QueryClient
|
||||
Issuance issuancetypes.QueryClient
|
||||
Pricefeed pricefeedtypes.QueryClient
|
||||
Precisebank precisebanktypes.QueryClient
|
||||
}
|
||||
|
||||
// NewQueryClient creates a new QueryClient and initializes all the module query clients
|
||||
func NewQueryClient(grpcEndpoint string) (*QueryClient, error) {
|
||||
conn, err := newGrpcConnection(context.Background(), grpcEndpoint)
|
||||
if err != nil {
|
||||
return &QueryClient{}, err
|
||||
}
|
||||
client := &QueryClient{
|
||||
Tm: tmservice.NewServiceClient(conn),
|
||||
Tx: txtypes.NewServiceClient(conn),
|
||||
Auth: authtypes.NewQueryClient(conn),
|
||||
Authz: authz.NewQueryClient(conn),
|
||||
Bank: banktypes.NewQueryClient(conn),
|
||||
Distribution: disttypes.NewQueryClient(conn),
|
||||
Evidence: evidencetypes.NewQueryClient(conn),
|
||||
Gov: govv1types.NewQueryClient(conn),
|
||||
GovBeta: govv1beta1types.NewQueryClient(conn),
|
||||
Mint: minttypes.NewQueryClient(conn),
|
||||
Params: paramstypes.NewQueryClient(conn),
|
||||
Slashing: slashingtypes.NewQueryClient(conn),
|
||||
Staking: stakingtypes.NewQueryClient(conn),
|
||||
Upgrade: upgradetypes.NewQueryClient(conn),
|
||||
Consensus: consensustypes.NewQueryClient(conn),
|
||||
|
||||
Evm: evmtypes.NewQueryClient(conn),
|
||||
Feemarket: feemarkettypes.NewQueryClient(conn),
|
||||
IbcClient: ibcclienttypes.NewQueryClient(conn),
|
||||
IbcTransfer: ibctransfertypes.NewQueryClient(conn),
|
||||
|
||||
Bep3: bep3types.NewQueryClient(conn),
|
||||
Committee: committeetypes.NewQueryClient(conn),
|
||||
Evmutil: evmutiltypes.NewQueryClient(conn),
|
||||
Issuance: issuancetypes.NewQueryClient(conn),
|
||||
Pricefeed: pricefeedtypes.NewQueryClient(conn),
|
||||
Precisebank: precisebanktypes.NewQueryClient(conn),
|
||||
}
|
||||
return client, nil
|
||||
}
|
64
client/grpc/query/query_test.go
Normal file
64
client/grpc/query/query_test.go
Normal file
@ -0,0 +1,64 @@
|
||||
package query_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/0glabs/0g-chain/client/grpc/query"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewQueryClient_InvalidGprc(t *testing.T) {
|
||||
t.Run("valid connection", func(t *testing.T) {
|
||||
conn, err := query.NewQueryClient("http://localhost:1234")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, conn)
|
||||
})
|
||||
|
||||
t.Run("non-empty url", func(t *testing.T) {
|
||||
_, err := query.NewQueryClient("")
|
||||
require.ErrorContains(t, err, "unknown grpc url scheme")
|
||||
})
|
||||
|
||||
t.Run("invalid url scheme", func(t *testing.T) {
|
||||
_, err := query.NewQueryClient("ftp://localhost:1234")
|
||||
require.ErrorContains(t, err, "unknown grpc url scheme")
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewQueryClient_ValidClient(t *testing.T) {
|
||||
t.Run("all clients are created", func(t *testing.T) {
|
||||
client, err := query.NewQueryClient("http://localhost:1234")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, client)
|
||||
|
||||
// validate cosmos clients
|
||||
require.NotNil(t, client.Tm)
|
||||
require.NotNil(t, client.Tx)
|
||||
require.NotNil(t, client.Auth)
|
||||
require.NotNil(t, client.Authz)
|
||||
require.NotNil(t, client.Bank)
|
||||
require.NotNil(t, client.Distribution)
|
||||
require.NotNil(t, client.Evidence)
|
||||
require.NotNil(t, client.Gov)
|
||||
require.NotNil(t, client.GovBeta)
|
||||
require.NotNil(t, client.Mint)
|
||||
require.NotNil(t, client.Params)
|
||||
require.NotNil(t, client.Slashing)
|
||||
require.NotNil(t, client.Staking)
|
||||
require.NotNil(t, client.Upgrade)
|
||||
require.NotNil(t, client.Consensus)
|
||||
|
||||
// validate 3rd party clients
|
||||
require.NotNil(t, client.Evm)
|
||||
require.NotNil(t, client.Feemarket)
|
||||
require.NotNil(t, client.IbcClient)
|
||||
require.NotNil(t, client.IbcTransfer)
|
||||
|
||||
// validate kava clients
|
||||
require.NotNil(t, client.Bep3)
|
||||
require.NotNil(t, client.Committee)
|
||||
require.NotNil(t, client.Evmutil)
|
||||
require.NotNil(t, client.Issuance)
|
||||
require.NotNil(t, client.Pricefeed)
|
||||
})
|
||||
}
|
41
client/grpc/util/account.go
Normal file
41
client/grpc/util/account.go
Normal file
@ -0,0 +1,41 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
|
||||
// Account fetches an account via an address and returns the unpacked account
|
||||
func (u *Util) Account(addr string) (authtypes.AccountI, error) {
|
||||
res, err := u.query.Auth.Account(context.Background(), &authtypes.QueryAccountRequest{
|
||||
Address: addr,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch account: %w", err)
|
||||
}
|
||||
|
||||
var acc authtypes.AccountI
|
||||
err = u.encodingConfig.Marshaler.UnpackAny(res.Account, &acc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unpack account: %w", err)
|
||||
}
|
||||
return acc, nil
|
||||
}
|
||||
|
||||
// BaseAccount fetches a base account via an address or returns an error if
|
||||
// the account is not a base account
|
||||
func (u *Util) BaseAccount(addr string) (authtypes.BaseAccount, error) {
|
||||
acc, err := u.Account(addr)
|
||||
if err != nil {
|
||||
return authtypes.BaseAccount{}, err
|
||||
}
|
||||
|
||||
bAcc, ok := acc.(*authtypes.BaseAccount)
|
||||
if !ok {
|
||||
return authtypes.BaseAccount{}, fmt.Errorf("%s is not a base account", addr)
|
||||
}
|
||||
|
||||
return *bAcc, nil
|
||||
}
|
8
client/grpc/util/doc.go
Normal file
8
client/grpc/util/doc.go
Normal file
@ -0,0 +1,8 @@
|
||||
/*
|
||||
The util package contains utility functions for the Kava gRPC client.
|
||||
|
||||
For example, `account.go` includes account-related query helpers.
|
||||
In this file, utilities such as `client.Util.BaseAccount(addr)` is exposed to
|
||||
query an account and return an unpacked `BaseAccount` instance.
|
||||
*/
|
||||
package util
|
32
client/grpc/util/util.go
Normal file
32
client/grpc/util/util.go
Normal file
@ -0,0 +1,32 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/app/params"
|
||||
query "github.com/0glabs/0g-chain/client/grpc/query"
|
||||
)
|
||||
|
||||
// Util contains utility functions for the Kava gRPC client
|
||||
type Util struct {
|
||||
query *query.QueryClient
|
||||
encodingConfig params.EncodingConfig
|
||||
}
|
||||
|
||||
// NewUtil creates a new Util instance
|
||||
func NewUtil(query *query.QueryClient) *Util {
|
||||
return &Util{
|
||||
query: query,
|
||||
encodingConfig: app.MakeEncodingConfig(),
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Util) CtxAtHeight(height int64) context.Context {
|
||||
heightStr := strconv.FormatInt(height, 10)
|
||||
return metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, heightStr)
|
||||
}
|
@ -13,7 +13,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/tendermint/tendermint/types"
|
||||
"github.com/cometbft/cometbft/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
@ -132,7 +132,7 @@ func (br BaseReq) ValidateBasic(w http.ResponseWriter) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ReadRESTReq reads and unmarshals a Request's body to the the BaseReq struct.
|
||||
// ReadRESTReq reads and unmarshals a Request's body to the BaseReq struct.
|
||||
// Writes an error response to ResponseWriter and returns false if errors occurred.
|
||||
func ReadRESTReq(w http.ResponseWriter, r *http.Request, cdc *codec.LegacyAmino, req interface{}) bool {
|
||||
body, err := io.ReadAll(r.Body)
|
||||
|
@ -12,15 +12,15 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
simappparams "cosmossdk.io/simapp/params"
|
||||
"github.com/0glabs/0g-chain/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/kava-labs/kava/client/rest"
|
||||
)
|
||||
|
||||
func TestBaseReq_Sanitize(t *testing.T) {
|
||||
|
@ -1,12 +1,17 @@
|
||||
package cmd
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/Kava-Labs/opendb"
|
||||
cometbftdb "github.com/cometbft/cometbft-db"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
tmtypes "github.com/cometbft/cometbft/types"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
@ -15,24 +20,27 @@ import (
|
||||
snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||
ethermintflags "github.com/evmos/ethermint/server/flags"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
db "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/app/params"
|
||||
metricstypes "github.com/kava-labs/kava/x/metrics/types"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/app/params"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
const (
|
||||
flagMempoolEnableAuth = "mempool.enable-authentication"
|
||||
flagMempoolAuthAddresses = "mempool.authorized-addresses"
|
||||
flagSkipLoadLatest = "skip-load-latest"
|
||||
)
|
||||
|
||||
// appCreator holds functions used by the sdk server to control the kava app.
|
||||
var accountNonceOp app.AccountNonceOp
|
||||
|
||||
// appCreator holds functions used by the sdk server to control the 0g-chain app.
|
||||
// The methods implement types in cosmos-sdk/server/types
|
||||
type appCreator struct {
|
||||
encodingConfig params.EncodingConfig
|
||||
@ -41,7 +49,7 @@ type appCreator struct {
|
||||
// newApp loads config from AppOptions and returns a new app.
|
||||
func (ac appCreator) newApp(
|
||||
logger log.Logger,
|
||||
db db.DB,
|
||||
db cometbftdb.DB,
|
||||
traceStore io.Writer,
|
||||
appOpts servertypes.AppOptions,
|
||||
) servertypes.Application {
|
||||
@ -62,7 +70,7 @@ func (ac appCreator) newApp(
|
||||
|
||||
homeDir := cast.ToString(appOpts.Get(flags.FlagHome))
|
||||
snapshotDir := filepath.Join(homeDir, "data", "snapshots") // TODO can these directory names be imported from somewhere?
|
||||
snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir)
|
||||
snapshotDB, err := opendb.OpenDB(appOpts, snapshotDir, "metadata", server.GetAppDBBackend(appOpts))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -89,19 +97,23 @@ func (ac appCreator) newApp(
|
||||
cast.ToUint32(appOpts.Get(server.FlagStateSyncSnapshotKeepRecent)),
|
||||
)
|
||||
|
||||
return app.NewApp(
|
||||
logger, db, homeDir, traceStore, ac.encodingConfig,
|
||||
app.Options{
|
||||
SkipLoadLatest: false,
|
||||
SkipUpgradeHeights: skipUpgradeHeights,
|
||||
SkipGenesisInvariants: cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants)),
|
||||
InvariantCheckPeriod: cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)),
|
||||
MempoolEnableAuth: mempoolEnableAuth,
|
||||
MempoolAuthAddresses: mempoolAuthAddresses,
|
||||
EVMTrace: cast.ToString(appOpts.Get(ethermintflags.EVMTracer)),
|
||||
EVMMaxGasWanted: cast.ToUint64(appOpts.Get(ethermintflags.EVMMaxTxGasWanted)),
|
||||
TelemetryOptions: metricstypes.TelemetryOptionsFromAppOpts(appOpts),
|
||||
},
|
||||
// Setup chainId
|
||||
chainID := cast.ToString(appOpts.Get(flags.FlagChainID))
|
||||
if len(chainID) == 0 {
|
||||
// fallback to genesis chain-id
|
||||
appGenesis, err := tmtypes.GenesisDocFromFile(filepath.Join(homeDir, "config", "genesis.json"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
chainID = appGenesis.ChainID
|
||||
}
|
||||
|
||||
skipLoadLatest := false
|
||||
if appOpts.Get(flagSkipLoadLatest) != nil {
|
||||
skipLoadLatest = cast.ToBool(appOpts.Get(flagSkipLoadLatest))
|
||||
}
|
||||
|
||||
bApp := app.NewBaseApp(logger, db, ac.encodingConfig,
|
||||
baseapp.SetPruning(pruningOpts),
|
||||
baseapp.SetMinGasPrices(strings.Replace(cast.ToString(appOpts.Get(server.FlagMinGasPrices)), ";", ",", -1)),
|
||||
baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))),
|
||||
@ -114,18 +126,67 @@ func (ac appCreator) newApp(
|
||||
baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(server.FlagIAVLCacheSize))),
|
||||
baseapp.SetIAVLDisableFastNode(cast.ToBool(iavlDisableFastNode)),
|
||||
baseapp.SetIAVLLazyLoading(cast.ToBool(appOpts.Get(server.FlagIAVLLazyLoading))),
|
||||
baseapp.SetChainID(chainID),
|
||||
baseapp.SetTxInfoExtracter(extractTxInfo),
|
||||
)
|
||||
|
||||
mempool := app.NewPriorityMempool(
|
||||
app.PriorityNonceWithMaxTx(fixMempoolSize(appOpts)),
|
||||
app.PriorityNonceWithTxReplacedCallback(func(ctx context.Context, oldTx, newTx *app.TxInfo) {
|
||||
if oldTx.Sender != newTx.Sender {
|
||||
sdkContext := sdk.UnwrapSDKContext(ctx)
|
||||
if accountNonceOp != nil {
|
||||
nonce := accountNonceOp.GetAccountNonce(sdkContext, oldTx.Sender)
|
||||
if nonce > 0 {
|
||||
accountNonceOp.SetAccountNonce(sdkContext, oldTx.Sender, nonce-1)
|
||||
sdkContext.Logger().Debug("rewind the nonce of the account", "account", oldTx.Sender, "from", nonce, "to", nonce-1)
|
||||
} else {
|
||||
sdkContext.Logger().Info("First meeting account", "account", oldTx.Sender)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sdkContext := sdk.UnwrapSDKContext(ctx)
|
||||
sdkContext.Logger().Info("tx replace", "account", oldTx.Sender, "nonce", oldTx.Nonce)
|
||||
}
|
||||
bApp.RegisterMempoolTxReplacedEvent(ctx, oldTx.Tx, newTx.Tx)
|
||||
}),
|
||||
)
|
||||
bApp.SetMempool(mempool)
|
||||
|
||||
bApp.SetTxEncoder(ac.encodingConfig.TxConfig.TxEncoder())
|
||||
abciProposalHandler := app.NewDefaultProposalHandler(mempool, bApp)
|
||||
bApp.SetPrepareProposal(abciProposalHandler.PrepareProposalHandler())
|
||||
|
||||
newApp := app.NewApp(
|
||||
homeDir, traceStore, ac.encodingConfig,
|
||||
app.Options{
|
||||
SkipLoadLatest: skipLoadLatest,
|
||||
SkipUpgradeHeights: skipUpgradeHeights,
|
||||
SkipGenesisInvariants: cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants)),
|
||||
InvariantCheckPeriod: cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)),
|
||||
MempoolEnableAuth: mempoolEnableAuth,
|
||||
MempoolAuthAddresses: mempoolAuthAddresses,
|
||||
EVMTrace: cast.ToString(appOpts.Get(ethermintflags.EVMTracer)),
|
||||
EVMMaxGasWanted: cast.ToUint64(appOpts.Get(ethermintflags.EVMMaxTxGasWanted)),
|
||||
},
|
||||
bApp,
|
||||
)
|
||||
|
||||
accountNonceOp = app.NewAccountNonceOp(newApp)
|
||||
|
||||
return newApp
|
||||
}
|
||||
|
||||
// appExport writes out an app's state to json.
|
||||
func (ac appCreator) appExport(
|
||||
logger log.Logger,
|
||||
db db.DB,
|
||||
db cometbftdb.DB,
|
||||
traceStore io.Writer,
|
||||
height int64,
|
||||
forZeroHeight bool,
|
||||
jailAllowedAddrs []string,
|
||||
appOpts servertypes.AppOptions,
|
||||
modulesToExport []string,
|
||||
) (servertypes.ExportedApp, error) {
|
||||
homePath, ok := appOpts.Get(flags.FlagHome).(string)
|
||||
if !ok || homePath == "" {
|
||||
@ -138,15 +199,17 @@ func (ac appCreator) appExport(
|
||||
|
||||
var tempApp *app.App
|
||||
if height != -1 {
|
||||
tempApp = app.NewApp(logger, db, homePath, traceStore, ac.encodingConfig, options)
|
||||
bApp := app.NewBaseApp(logger, db, ac.encodingConfig)
|
||||
tempApp = app.NewApp(homePath, traceStore, ac.encodingConfig, options, bApp)
|
||||
|
||||
if err := tempApp.LoadHeight(height); err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
}
|
||||
} else {
|
||||
tempApp = app.NewApp(logger, db, homePath, traceStore, ac.encodingConfig, options)
|
||||
bApp := app.NewBaseApp(logger, db, ac.encodingConfig)
|
||||
tempApp = app.NewApp(homePath, traceStore, ac.encodingConfig, options, bApp)
|
||||
}
|
||||
return tempApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs)
|
||||
return tempApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
|
||||
}
|
||||
|
||||
// addStartCmdFlags adds flags to the server start command.
|
||||
@ -166,3 +229,72 @@ func accAddressesFromBech32(addresses ...string) ([]sdk.AccAddress, error) {
|
||||
}
|
||||
return decodedAddresses, nil
|
||||
}
|
||||
|
||||
var ErrMustHaveSigner error = errors.New("tx must have at least one signer")
|
||||
|
||||
func extractTxInfo(ctx sdk.Context, tx sdk.Tx) (*sdk.TxInfo, error) {
|
||||
sigs, err := tx.(signing.SigVerifiableTx).GetSignaturesV2()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sender string
|
||||
var nonce uint64
|
||||
var gasPrice uint64
|
||||
var gasLimit uint64
|
||||
var txType int32
|
||||
|
||||
if len(sigs) == 0 {
|
||||
txType = 1
|
||||
msgs := tx.GetMsgs()
|
||||
if len(msgs) != 1 {
|
||||
return nil, ErrMustHaveSigner
|
||||
}
|
||||
msgEthTx, ok := msgs[0].(*evmtypes.MsgEthereumTx)
|
||||
if !ok {
|
||||
return nil, ErrMustHaveSigner
|
||||
}
|
||||
ethTx := msgEthTx.AsTransaction()
|
||||
signer := gethtypes.NewEIP2930Signer(ethTx.ChainId())
|
||||
ethSender, err := signer.Sender(ethTx)
|
||||
if err != nil {
|
||||
return nil, ErrMustHaveSigner
|
||||
}
|
||||
sender = sdk.AccAddress(ethSender.Bytes()).String()
|
||||
nonce = ethTx.Nonce()
|
||||
gasPrice = ethTx.GasPrice().Uint64()
|
||||
gasLimit = ethTx.Gas()
|
||||
} else {
|
||||
sig := sigs[0]
|
||||
sender = sdk.AccAddress(sig.PubKey.Address()).String()
|
||||
nonce = sig.Sequence
|
||||
}
|
||||
|
||||
return &sdk.TxInfo{
|
||||
SignerAddress: sender,
|
||||
Nonce: nonce,
|
||||
GasLimit: gasLimit,
|
||||
GasPrice: gasPrice,
|
||||
TxType: txType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func fixMempoolSize(appOpts servertypes.AppOptions) int {
|
||||
val1 := appOpts.Get("mempool.size")
|
||||
val2 := appOpts.Get(server.FlagMempoolMaxTxs)
|
||||
|
||||
if val1 != nil && val2 != nil {
|
||||
size1 := cast.ToInt(val1)
|
||||
size2 := cast.ToInt(val2)
|
||||
if size1 != size2 {
|
||||
panic("the value of mempool.size and mempool.max-txs are different")
|
||||
}
|
||||
return size1
|
||||
} else if val1 == nil && val2 == nil {
|
||||
panic("not found mempool size in config")
|
||||
} else if val1 == nil {
|
||||
return cast.ToInt(val2)
|
||||
} else { //if val2 == nil {
|
||||
return cast.ToInt(val1)
|
||||
}
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
package cmd
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
tmtypes "github.com/cometbft/cometbft/types"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
"github.com/spf13/cobra"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/app/params"
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/app/params"
|
||||
)
|
||||
|
||||
func AssertInvariantsCmd(config params.EncodingConfig) *cobra.Command {
|
@ -1,5 +1,5 @@
|
||||
// Sourced from https://github.com/evmos/ethermint/blob/main/cmd/ethermintd/genaccounts.go
|
||||
package cmd
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
53
cmd/0gchaind/iavlviewer/data.go
Normal file
53
cmd/0gchaind/iavlviewer/data.go
Normal file
@ -0,0 +1,53 @@
|
||||
package iavlviewer
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/iavl"
|
||||
ethermintserver "github.com/evmos/ethermint/server"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newDataCmd(opts ethermintserver.StartOptions) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "data <prefix> [version number]",
|
||||
Short: "View all keys, hash, & size of tree.",
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
prefix := args[0]
|
||||
version := 0
|
||||
if len(args) == 2 {
|
||||
var err error
|
||||
version, err = parseVersion(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
tree, err := openPrefixTree(opts, cmd, prefix, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printKeys(tree)
|
||||
hash := tree.Hash()
|
||||
fmt.Printf("Hash: %X\n", hash)
|
||||
fmt.Printf("Size: %X\n", tree.Size())
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func printKeys(tree *iavl.MutableTree) {
|
||||
fmt.Println("Printing all keys with hashed values (to detect diff)")
|
||||
tree.Iterate(func(key []byte, value []byte) bool { //nolint:errcheck
|
||||
printKey := parseWeaveKey(key)
|
||||
digest := sha256.Sum256(value)
|
||||
fmt.Printf(" %s\n %X\n", printKey, digest)
|
||||
return false
|
||||
})
|
||||
}
|
38
cmd/0gchaind/iavlviewer/hash.go
Normal file
38
cmd/0gchaind/iavlviewer/hash.go
Normal file
@ -0,0 +1,38 @@
|
||||
package iavlviewer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
ethermintserver "github.com/evmos/ethermint/server"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newHashCmd(opts ethermintserver.StartOptions) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "hash <prefix> [version number]",
|
||||
Short: "Print the root hash of the iavl tree.",
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
prefix := args[0]
|
||||
version := 0
|
||||
if len(args) == 2 {
|
||||
var err error
|
||||
version, err = parseVersion(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
tree, err := openPrefixTree(opts, cmd, prefix, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Hash: %X\n", tree.Hash())
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user