Upgrade to sdk v0.44.5 and add IBC (#1106)

- Upgrade cosmos-sdk to v0.44.5 from v0.39.2
- Add Legacy Tx Endpoint for backwards compatibility
- Add IBC v1.2.3 Support

Co-authored-by: DracoLi <draco@dracoli.com>
Co-authored-by: drklee3 <derrick@dlee.dev>
Co-authored-by: denalimarsh <denalimarsh@gmail.com>
Co-authored-by: Draco Li <draco@kava.io>
Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com>
Co-authored-by: Kevin Davis <karzak@users.noreply.github.com>
Co-authored-by: Denali Marsh <denali@kava.io>
This commit is contained in:
Ruaridh 2022-01-08 00:39:27 +00:00 committed by GitHub
parent ab299efeaf
commit ffef832d45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
872 changed files with 214643 additions and 452120 deletions

View File

@ -2,7 +2,7 @@ version: 2.1
executors:
golang:
docker:
- image: circleci/golang:1.13
- image: circleci/golang:1.16
commands:
make:
@ -72,7 +72,7 @@ jobs:
export VERSION="$(git describe --tags --long | sed 's/v\(.*\)/\1/')"
export GO111MODULE=on
mkdir -p /tmp/logs /tmp/workspace/profiles
for pkg in $(go list ./... | grep -v 'simulation\|migrate\|contrib' | circleci tests split); do
for pkg in $(go list ./... | grep -v 'simulation\|contrib' | circleci tests split); do
id=$(echo "$pkg" | sed 's|[/.]|_|g')
go test -mod=readonly -timeout 20m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic -tags='ledger test_ledger_mock' "$pkg" | tee "/tmp/logs/$id-$RANDOM.log"
done

116
.clang-format Normal file
View File

@ -0,0 +1,116 @@
---
Language: Proto
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
RawStringFormats:
- Delimiters:
- pb
Language: TextProto
BasedOnStyle: google
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

View File

@ -1,4 +1,4 @@
FROM golang:1.13-alpine AS build-env
FROM golang:1.16-alpine AS build-env
# Set up dependencies
# bash, jq, curl for debugging
@ -6,22 +6,26 @@ FROM golang:1.13-alpine AS build-env
# libc-dev, gcc, linux-headers, eudev-dev are used for cgo and ledger installation
RUN apk add bash git make libc-dev gcc linux-headers eudev-dev jq curl
# Set working directory for the build
WORKDIR /root/kava
# default home directory is /root
# Speed up later builds by caching the dependencies
COPY go.mod .
COPY go.sum .
RUN go mod download
# Add source files
COPY . .
# Install kvd, kvcli
#ENV LEDGER_ENABLED False
RUN make install
# Mount build container cache, persisted between builder invocations
RUN --mount=type=cache,target=/root/.cache/go-build \
make install
# Run kvd by default, omit entrypoint to ease using container with kvcli
CMD ["kvd"]
FROM alpine:3.15
RUN apk add bash jq curl
COPY --from=build-env /go/bin/kava /bin/kava
CMD ["kava"]

146
Makefile
View File

@ -1,8 +1,15 @@
#!/usr/bin/make -f
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//')
TM_PKG_VERSION := $(shell go list -m github.com/tendermint/tendermint | sed 's:.* ::')
COSMOS_PKG_VERSION := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's:.* ::')
COMMIT := $(shell git log -1 --format='%H')
LEDGER_ENABLED ?= true
PROJECT_NAME = kava
DOCKER:=docker
DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf
HTTPS_GIT := https://github.com/Kava-Labs/kava.git
export GO111MODULE = on
# process build tags
@ -45,11 +52,11 @@ 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.ServerName=kvd \
-X github.com/cosmos/cosmos-sdk/version.ClientName=kvcli \
-X github.com/cosmos/cosmos-sdk/version.AppName=kava \
-X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)"
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \
-X github.com/tendermint/tendermint/version.TMCoreSemVer=$(TM_PKG_VERSION)
ifeq ($(WITH_CLEVELDB),yes)
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
@ -64,19 +71,16 @@ all: install
build: go.sum
ifeq ($(OS), Windows_NT)
go build -mod=readonly $(BUILD_FLAGS) -o build/$(shell go env GOOS)/kvd.exe ./cmd/kvd
go build -mod=readonly $(BUILD_FLAGS) -o build/$(shell go env GOOS)/kvcli.exe ./cmd/kvcli
go build -mod=readonly $(BUILD_FLAGS) -o build/$(shell go env GOOS)/kava.exe ./cmd/kava
else
go build -mod=readonly $(BUILD_FLAGS) -o build/$(shell go env GOOS)/kvd ./cmd/kvd
go build -mod=readonly $(BUILD_FLAGS) -o build/$(shell go env GOOS)/kvcli ./cmd/kvcli
go build -mod=readonly $(BUILD_FLAGS) -o build/$(shell go env GOOS)/kava ./cmd/kava
endif
build-linux: go.sum
LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build
install: go.sum
go install -mod=readonly $(BUILD_FLAGS) ./cmd/kvd
go install -mod=readonly $(BUILD_FLAGS) ./cmd/kvcli
go install -mod=readonly $(BUILD_FLAGS) ./cmd/kava
########################################
### Tools & dependencies
@ -133,6 +137,125 @@ localnet-start: build-linux localnet-stop
localnet-stop:
docker-compose down
# Launch a new single validator chain
start:
./contrib/devnet/init-new-chain.sh
kava start
###############################################################################
### Protobuf ###
###############################################################################
protoVer=v0.2
protoImageName=tendermintdev/sdk-proto-gen:$(protoVer)
containerProtoGen=$(PROJECT_NAME)-proto-gen-$(protoVer)
containerProtoGenAny=$(PROJECT_NAME)-proto-gen-any-$(protoVer)
containerProtoGenSwagger=$(PROJECT_NAME)-proto-gen-swagger-$(protoVer)
containerProtoFmt=$(PROJECT_NAME)-proto-fmt-$(protoVer)
proto-all: proto-gen proto-format proto-lint proto-swagger-gen
proto-gen:
@echo "Generating Protobuf files"
@if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGen}$$"; then docker start -a $(containerProtoGen); else docker run --name $(containerProtoGen) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \
sh ./scripts/protocgen.sh; fi
proto-swagger-gen:
@echo "Generating Protobuf Swagger"
@if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGenSwagger}$$"; then docker start -a $(containerProtoGenSwagger); else docker run --name $(containerProtoGenSwagger) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \
sh ./scripts/protoc-swagger-gen.sh; fi
proto-format:
@echo "Formatting Protobuf files"
@if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \
find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -style=file -i {} \; ; fi
proto-lint:
@$(DOCKER_BUF) lint --error-format=json
proto-check-breaking:
@$(DOCKER_BUF) breaking --against $(HTTPS_GIT)#branch=upgrade-v44
TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/$(TM_PKG_VERSION)/proto/tendermint
GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos
COSMOS_PROTO_URL = https://raw.githubusercontent.com/cosmos/cosmos-proto/master
COSMOS_SDK_URL = https://raw.githubusercontent.com/cosmos/cosmos-sdk/$(COSMOS_PKG_VERSION)
COSMOS_SDK_PROTO_URL = https://raw.githubusercontent.com/cosmos/cosmos-sdk/$(COSMOS_PKG_VERSION)/proto/cosmos
COSMOS_SDK_BASE_PROTO_URL = $(COSMOS_SDK_PROTO_URL)/base
GOOGLE_PROTO_URL = https://raw.githubusercontent.com/googleapis/googleapis/master/google/api
PROTOBUF_GOOGLE_URL = https://raw.githubusercontent.com/protocolbuffers/protobuf/master/src/google/protobuf
TM_CRYPTO_TYPES = third_party/proto/tendermint/crypto
TM_ABCI_TYPES = third_party/proto/tendermint/abci
TM_TYPES = third_party/proto/tendermint/types
TM_VERSION = third_party/proto/tendermint/version
TM_LIBS = third_party/proto/tendermint/libs/bits
GOGO_PROTO_TYPES = third_party/proto/gogoproto
COSMOS_PROTO_TYPES = third_party/proto/cosmos_proto
GOOGLE_PROTO_TYPES = third_party/proto/google/api
PROTOBUF_GOOGLE_TYPES = third_party/proto/google/protobuf
SDK_ABCI_TYPES = third_party/proto/cosmos/base/abci/v1beta1
SDK_QUERY_TYPES = third_party/proto/cosmos/base/query/v1beta1
SDK_VESTING_TYPES = third_party/proto/cosmos/vesting/v1beta1
SDK_AUTH_TYPES = third_party/proto/cosmos/auth/v1beta1
SDK_COIN_TYPES = third_party/proto/cosmos/base/v1beta1
proto-update-deps:
mkdir -p $(GOGO_PROTO_TYPES)
curl -sSL $(GOGO_PROTO_URL)/gogoproto/gogo.proto > $(GOGO_PROTO_TYPES)/gogo.proto
mkdir -p $(COSMOS_PROTO_TYPES)
curl -sSL $(COSMOS_PROTO_URL)/cosmos.proto > $(COSMOS_PROTO_TYPES)/cosmos.proto
mkdir -p $(TM_ABCI_TYPES)
curl -sSL $(TM_URL)/abci/types.proto > $(TM_ABCI_TYPES)/types.proto
mkdir -p $(TM_VERSION)
curl -sSL $(TM_URL)/version/types.proto > $(TM_VERSION)/types.proto
mkdir -p $(TM_TYPES)
curl -sSL $(TM_URL)/types/types.proto > $(TM_TYPES)/types.proto
curl -sSL $(TM_URL)/types/evidence.proto > $(TM_TYPES)/evidence.proto
curl -sSL $(TM_URL)/types/params.proto > $(TM_TYPES)/params.proto
curl -sSL $(TM_URL)/types/validator.proto > $(TM_TYPES)/validator.proto
mkdir -p $(TM_CRYPTO_TYPES)
curl -sSL $(TM_URL)/crypto/proof.proto > $(TM_CRYPTO_TYPES)/proof.proto
curl -sSL $(TM_URL)/crypto/keys.proto > $(TM_CRYPTO_TYPES)/keys.proto
mkdir -p $(TM_LIBS)
curl -sSL $(TM_URL)/libs/bits/types.proto > $(TM_LIBS)/types.proto
mkdir -p $(SDK_ABCI_TYPES)
curl -sSL $(COSMOS_SDK_BASE_PROTO_URL)/abci/v1beta1/abci.proto > $(SDK_ABCI_TYPES)/abci.proto
mkdir -p $(SDK_QUERY_TYPES)
curl -sSL $(COSMOS_SDK_BASE_PROTO_URL)/query/v1beta1/pagination.proto > $(SDK_QUERY_TYPES)/pagination.proto
mkdir -p $(SDK_COIN_TYPES)
curl -sSL $(COSMOS_SDK_BASE_PROTO_URL)/v1beta1/coin.proto > $(SDK_COIN_TYPES)/coin.proto
mkdir -p $(SDK_VESTING_TYPES)
curl -sSL $(COSMOS_SDK_PROTO_URL)/vesting/v1beta1/vesting.proto > $(SDK_VESTING_TYPES)/vesting.proto
mkdir -p $(SDK_AUTH_TYPES)
curl -sSL $(COSMOS_SDK_PROTO_URL)/auth/v1beta1/auth.proto > $(SDK_AUTH_TYPES)/auth.proto
mkdir -p $(GOOGLE_PROTO_TYPES)
curl -sSL $(GOOGLE_PROTO_URL)/annotations.proto > $(GOOGLE_PROTO_TYPES)/annotations.proto
curl -sSL $(GOOGLE_PROTO_URL)/http.proto > $(GOOGLE_PROTO_TYPES)/http.proto
curl -sSL $(GOOGLE_PROTO_URL)/httpbody.proto > $(GOOGLE_PROTO_TYPES)/httpbody.proto
mkdir -p $(PROTOBUF_GOOGLE_TYPES)
curl -sSL $(PROTOBUF_GOOGLE_URL)/any.proto > $(PROTOBUF_GOOGLE_TYPES)/any.proto
mkdir -p client/docs
curl -sSL $(COSMOS_SDK_URL)/client/docs/swagger-ui/swagger.yaml > client/docs/cosmos-swagger.yml
.PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps
########################################
### Testing
@ -160,10 +283,7 @@ test-basic: test
@go test ./app -run TestAppStateDeterminism -Enabled -Commit -NumBlocks=5 -BlockSize=200 -Seed 4 -v -timeout 2m
test:
@go test $$(go list ./... | grep -v 'migrate\|contrib')
test-rest:
rest_test/run_all_tests_from_make.sh
@go test $$(go list ./... | grep -v 'contrib')
# Run cli integration tests
# `-p 4` to use 4 cores, `-tags cli_test` to tell go not to ignore the cli package

View File

@ -2,31 +2,61 @@ package ante
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/keeper"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/types"
channelkeeper "github.com/cosmos/ibc-go/modules/core/04-channel/keeper"
ibcante "github.com/cosmos/ibc-go/modules/core/ante"
)
// NewAnteHandler returns an 'AnteHandler' that will run actions before a tx is sent to a module's handler.
func NewAnteHandler(ak keeper.AccountKeeper, supplyKeeper types.SupplyKeeper, sigGasConsumer ante.SignatureVerificationGasConsumer, addressFetchers ...AddressFetcher) sdk.AnteHandler {
func NewAnteHandler(
accountKeeper ante.AccountKeeper,
bankKeeper types.BankKeeper,
feegrantKeeper ante.FeegrantKeeper,
ibcChannelKeeper channelkeeper.Keeper,
signModeHandler authsigning.SignModeHandler, sigGasConsumer ante.SignatureVerificationGasConsumer, addressFetchers ...AddressFetcher) (sdk.AnteHandler, error) {
if accountKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder")
}
if bankKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder")
}
if signModeHandler == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder")
}
if sigGasConsumer == nil {
sigGasConsumer = ante.DefaultSigVerificationGasConsumer
}
decorators := []sdk.AnteDecorator{}
decorators = append(decorators, ante.NewSetUpContextDecorator()) // outermost AnteDecorator. SetUpContext must be called first
decorators = append(decorators,
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
ante.NewRejectExtensionOptionsDecorator(),
)
if len(addressFetchers) > 0 {
decorators = append(decorators, NewAuthenticatedMempoolDecorator(addressFetchers...))
}
decorators = append(decorators,
ante.NewMempoolFeeDecorator(),
NewVestingAccountDecorator(),
ante.NewValidateBasicDecorator(),
ante.NewValidateMemoDecorator(ak),
ante.NewConsumeGasForTxSizeDecorator(ak),
ante.NewSetPubKeyDecorator(ak), // SetPubKeyDecorator must be called before all signature verification decorators
ante.NewValidateSigCountDecorator(ak),
ante.NewDeductFeeDecorator(ak, supplyKeeper),
ante.NewSigGasConsumeDecorator(ak, sigGasConsumer),
ante.NewSigVerificationDecorator(ak),
ante.NewIncrementSequenceDecorator(ak), // innermost AnteDecorator
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(accountKeeper),
ante.NewConsumeGasForTxSizeDecorator(accountKeeper),
ante.NewDeductFeeDecorator(accountKeeper, bankKeeper, feegrantKeeper),
ante.NewSetPubKeyDecorator(accountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators
ante.NewValidateSigCountDecorator(accountKeeper),
ante.NewSigGasConsumeDecorator(accountKeeper, sigGasConsumer),
ante.NewSigVerificationDecorator(accountKeeper, signModeHandler),
ante.NewIncrementSequenceDecorator(accountKeeper), // innermost AnteDecorator
ibcante.NewAnteDecorator(ibcChannelKeeper),
)
return sdk.ChainAnteDecorators(decorators...)
return sdk.ChainAnteDecorators(decorators...), nil
}

View File

@ -4,25 +4,25 @@ import (
"testing"
"time"
"github.com/cosmos/cosmos-sdk/codec"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/log"
tmdb "github.com/tendermint/tm-db"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/x/bep3"
"github.com/kava-labs/kava/x/pricefeed"
bep3types "github.com/kava-labs/kava/x/bep3/types"
pricefeedtypes "github.com/kava-labs/kava/x/pricefeed/types"
)
func TestAppAnteHandler(t *testing.T) {
testPrivKeys, testAddresses := app.GeneratePrivKeyAddressPairs(10)
unauthed := testAddresses[0:2]
unathedKeys := testPrivKeys[0:2]
unauthedKeys := testPrivKeys[0:2]
deputy := testAddresses[2]
deputyKey := testPrivKeys[2]
oracles := testAddresses[3:6]
@ -30,10 +30,15 @@ func TestAppAnteHandler(t *testing.T) {
manual := testAddresses[6:]
manualKeys := testPrivKeys[6:]
db := tmdb.NewMemDB()
encodingConfig := app.MakeEncodingConfig()
tApp := app.TestApp{
App: *app.NewApp(log.NewNopLogger(), db, nil,
app.AppOptions{
App: *app.NewApp(
log.NewNopLogger(),
tmdb.NewMemDB(),
app.DefaultNodeHome,
nil,
encodingConfig,
app.Options{
MempoolEnableAuth: true,
MempoolAuthAddresses: manual,
},
@ -44,24 +49,25 @@ func TestAppAnteHandler(t *testing.T) {
tApp = tApp.InitializeFromGenesisStatesWithTimeAndChainID(
time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC),
chainID,
NewAuthGenStateWithSameCoins(
sdk.NewCoins(sdk.NewInt64Coin("ukava", 1_000_000_000)),
app.NewFundedGenStateWithSameCoins(
tApp.AppCodec(),
sdk.NewCoins(sdk.NewInt64Coin("ukava", 1e9)),
testAddresses,
),
newBep3GenStateMulti(deputy),
newPricefeedGenStateMulti(oracles),
newBep3GenStateMulti(tApp.AppCodec(), deputy),
newPricefeedGenStateMulti(tApp.AppCodec(), oracles),
)
testcases := []struct {
name string
address sdk.AccAddress
privKey crypto.PrivKey
privKey cryptotypes.PrivKey
expectPass bool
}{
{
name: "unauthorized",
address: unauthed[1],
privKey: unathedKeys[1],
privKey: unauthedKeys[1],
expectPass: false,
},
{
@ -86,9 +92,10 @@ func TestAppAnteHandler(t *testing.T) {
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
stdTx := helpers.GenTx(
stdTx, err := helpers.GenTx(
encodingConfig.TxConfig,
[]sdk.Msg{
bank.NewMsgSend(
banktypes.NewMsgSend(
tc.address,
testAddresses[0],
sdk.NewCoins(sdk.NewInt64Coin("ukava", 1_000_000)),
@ -101,7 +108,8 @@ func TestAppAnteHandler(t *testing.T) {
[]uint64{0}, // fixed sequence numbers will cause tests to fail sig verification if the same address is used twice
tc.privKey,
)
txBytes, err := auth.DefaultTxEncoder(tApp.Codec())(stdTx)
require.NoError(t, err)
txBytes, err := encodingConfig.TxConfig.TxEncoder()(stdTx)
require.NoError(t, err)
res := tApp.CheckTx(
@ -120,34 +128,25 @@ func TestAppAnteHandler(t *testing.T) {
}
}
func NewAuthGenStateWithSameCoins(coins sdk.Coins, addresses []sdk.AccAddress) app.GenesisState {
coinsList := make([]sdk.Coins, len(addresses))
for i := range addresses {
coinsList[i] = coins
}
return app.NewAuthGenState(addresses, coinsList)
}
func newPricefeedGenStateMulti(oracles []sdk.AccAddress) app.GenesisState {
pfGenesis := pricefeed.GenesisState{
Params: pricefeed.Params{
Markets: []pricefeed.Market{
func newPricefeedGenStateMulti(cdc codec.JSONCodec, oracles []sdk.AccAddress) app.GenesisState {
pfGenesis := pricefeedtypes.GenesisState{
Params: pricefeedtypes.Params{
Markets: []pricefeedtypes.Market{
{MarketID: "btc:usd", BaseAsset: "btc", QuoteAsset: "usd", Oracles: oracles, Active: true},
{MarketID: "xrp:usd", BaseAsset: "xrp", QuoteAsset: "usd", Oracles: oracles, Active: true},
},
},
}
return app.GenesisState{pricefeed.ModuleName: pricefeed.ModuleCdc.MustMarshalJSON(pfGenesis)}
return app.GenesisState{pricefeedtypes.ModuleName: cdc.MustMarshalJSON(&pfGenesis)}
}
func newBep3GenStateMulti(deputyAddress sdk.AccAddress) app.GenesisState {
bep3Genesis := bep3.GenesisState{
Params: bep3.Params{
AssetParams: bep3.AssetParams{
bep3.AssetParam{
func newBep3GenStateMulti(cdc codec.JSONCodec, deputyAddress sdk.AccAddress) app.GenesisState {
bep3Genesis := bep3types.GenesisState{
Params: bep3types.Params{
AssetParams: bep3types.AssetParams{
bep3types.AssetParam{
Denom: "bnb",
CoinID: 714,
SupplyLimit: bep3.SupplyLimit{
SupplyLimit: bep3types.SupplyLimit{
Limit: sdk.NewInt(350000000000000),
TimeLimited: false,
TimeBasedLimit: sdk.ZeroInt(),
@ -158,45 +157,21 @@ func newBep3GenStateMulti(deputyAddress sdk.AccAddress) app.GenesisState {
FixedFee: sdk.NewInt(1000),
MinSwapAmount: sdk.OneInt(),
MaxSwapAmount: sdk.NewInt(1000000000000),
MinBlockLock: bep3.DefaultMinBlockLock,
MaxBlockLock: bep3.DefaultMaxBlockLock,
},
bep3.AssetParam{
Denom: "inc",
CoinID: 9999,
SupplyLimit: bep3.SupplyLimit{
Limit: sdk.NewInt(100000000000000),
TimeLimited: true,
TimeBasedLimit: sdk.NewInt(50000000000),
TimePeriod: time.Hour,
},
Active: false,
DeputyAddress: deputyAddress,
FixedFee: sdk.NewInt(1000),
MinSwapAmount: sdk.OneInt(),
MaxSwapAmount: sdk.NewInt(100000000000),
MinBlockLock: bep3.DefaultMinBlockLock,
MaxBlockLock: bep3.DefaultMaxBlockLock,
MinBlockLock: bep3types.DefaultMinBlockLock,
MaxBlockLock: bep3types.DefaultMaxBlockLock,
},
},
},
Supplies: bep3.AssetSupplies{
bep3.NewAssetSupply(
Supplies: bep3types.AssetSupplies{
bep3types.NewAssetSupply(
sdk.NewCoin("bnb", sdk.ZeroInt()),
sdk.NewCoin("bnb", sdk.ZeroInt()),
sdk.NewCoin("bnb", sdk.ZeroInt()),
sdk.NewCoin("bnb", sdk.ZeroInt()),
time.Duration(0),
),
bep3.NewAssetSupply(
sdk.NewCoin("inc", sdk.ZeroInt()),
sdk.NewCoin("inc", sdk.ZeroInt()),
sdk.NewCoin("inc", sdk.ZeroInt()),
sdk.NewCoin("inc", sdk.ZeroInt()),
time.Duration(0),
),
},
PreviousBlockTime: bep3.DefaultPreviousBlockTime,
PreviousBlockTime: bep3types.DefaultPreviousBlockTime,
}
return app.GenesisState{bep3.ModuleName: bep3.ModuleCdc.MustMarshalJSON(bep3Genesis)}
return app.GenesisState{bep3types.ModuleName: cdc.MustMarshalJSON(&bep3Genesis)}
}

View File

@ -3,19 +3,14 @@ package ante
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
)
var _ sigVerifiableTx = (*authtypes.StdTx)(nil) // assert StdTx implements SigVerifiableTx
// SigVerifiableTx defines a Tx interface for all signature verification decorators
type sigVerifiableTx interface {
GetSigners() []sdk.AccAddress
}
// AddressFetcher is a type signature for functions used by the AuthenticatedMempoolDecorator to get authorized addresses.
type AddressFetcher func(sdk.Context) []sdk.AccAddress
var _ sdk.AnteDecorator = AuthenticatedMempoolDecorator{}
// AuthenticatedMempoolDecorator blocks all txs from reaching the mempool unless they're signed by one of the authorzed addresses.
// It only runs before entry to mempool (CheckTx), and not in consensus (DeliverTx)
type AuthenticatedMempoolDecorator struct {
@ -31,7 +26,7 @@ func NewAuthenticatedMempoolDecorator(fetchers ...AddressFetcher) AuthenticatedM
func (amd AuthenticatedMempoolDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
// This is only for local mempool purposes, and thus is only run on check tx.
if ctx.IsCheckTx() && !simulate {
sigTx, ok := tx.(sigVerifiableTx)
sigTx, ok := tx.(authsigning.SigVerifiableTx)
if !ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx must be sig verifiable tx")
}

View File

@ -1,17 +1,15 @@
package ante
package ante_test
import (
"math/rand"
"testing"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/kava-labs/kava/x/bep3"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/app/ante"
)
var (
@ -27,21 +25,24 @@ func (mah *MockAnteHandler) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool
return ctx, nil
}
func mockAddressFetcher(addresses ...sdk.AccAddress) AddressFetcher {
func mockAddressFetcher(addresses ...sdk.AccAddress) ante.AddressFetcher {
return func(sdk.Context) []sdk.AccAddress { return addresses }
}
func TestAuthenticatedMempoolDecorator_AnteHandle_NotCheckTx(t *testing.T) {
testPrivKeys, testAddresses := generatePrivKeyAddressPairs(5)
txConfig := app.MakeEncodingConfig().TxConfig
testPrivKeys, testAddresses := app.GeneratePrivKeyAddressPairs(5)
fetcher := mockAddressFetcher(testAddresses[1:]...)
decorator := NewAuthenticatedMempoolDecorator(fetcher)
tx := helpers.GenTx(
decorator := ante.NewAuthenticatedMempoolDecorator(fetcher)
tx, err := helpers.GenTx(
txConfig,
[]sdk.Msg{
bep3.NewMsgClaimAtomicSwap(
banktypes.NewMsgSend(
testAddresses[0],
[]byte{},
[]byte{},
testAddresses[1],
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
),
},
sdk.NewCoins(), // no fee
@ -51,32 +52,36 @@ func TestAuthenticatedMempoolDecorator_AnteHandle_NotCheckTx(t *testing.T) {
[]uint64{0},
testPrivKeys[0], // address is not authorized
)
require.NoError(t, err)
mmd := MockAnteHandler{}
ctx := sdk.Context{}.WithIsCheckTx(false) // run as it would be during block update ('DeliverTx'), not just checking entry to mempool
_, err := decorator.AnteHandle(ctx, tx, false, mmd.AnteHandle)
_, err = decorator.AnteHandle(ctx, tx, false, mmd.AnteHandle)
require.NoError(t, err)
require.True(t, mmd.WasCalled)
}
func TestAuthenticatedMempoolDecorator_AnteHandle_Pass(t *testing.T) {
testPrivKeys, testAddresses := generatePrivKeyAddressPairs(5)
txConfig := app.MakeEncodingConfig().TxConfig
testPrivKeys, testAddresses := app.GeneratePrivKeyAddressPairs(5)
fetcher := mockAddressFetcher(testAddresses[1:]...)
decorator := NewAuthenticatedMempoolDecorator(fetcher)
decorator := ante.NewAuthenticatedMempoolDecorator(fetcher)
tx := helpers.GenTx(
tx, err := helpers.GenTx(
txConfig,
[]sdk.Msg{
bank.NewMsgSend(
banktypes.NewMsgSend(
testAddresses[0],
testAddresses[1],
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
),
bep3.NewMsgClaimAtomicSwap(
banktypes.NewMsgSend(
testAddresses[2],
nil,
nil,
testAddresses[1],
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
),
},
sdk.NewCoins(), // no fee
@ -85,26 +90,30 @@ func TestAuthenticatedMempoolDecorator_AnteHandle_Pass(t *testing.T) {
[]uint64{0, 123},
[]uint64{0, 123},
testPrivKeys[0], // not in list of authorized addresses
testPrivKeys[2],
testPrivKeys[2], // in list of authorized addresses
)
require.NoError(t, err)
mmd := MockAnteHandler{}
ctx := sdk.Context{}.WithIsCheckTx(true)
_, err := decorator.AnteHandle(ctx, tx, false, mmd.AnteHandle)
_, err = decorator.AnteHandle(ctx, tx, false, mmd.AnteHandle)
require.NoError(t, err)
require.True(t, mmd.WasCalled)
}
func TestAuthenticatedMempoolDecorator_AnteHandle_Reject(t *testing.T) {
testPrivKeys, testAddresses := generatePrivKeyAddressPairs(5)
txConfig := app.MakeEncodingConfig().TxConfig
testPrivKeys, testAddresses := app.GeneratePrivKeyAddressPairs(5)
fetcher := mockAddressFetcher(testAddresses[1:]...)
decorator := NewAuthenticatedMempoolDecorator(fetcher)
decorator := ante.NewAuthenticatedMempoolDecorator(fetcher)
tx := helpers.GenTx(
tx, err := helpers.GenTx(
txConfig,
[]sdk.Msg{
bank.NewMsgSend(
banktypes.NewMsgSend(
testAddresses[0],
testAddresses[1],
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
@ -117,28 +126,12 @@ func TestAuthenticatedMempoolDecorator_AnteHandle_Reject(t *testing.T) {
[]uint64{0},
testPrivKeys[0], // not in list of authorized addresses
)
require.NoError(t, err)
mmd := MockAnteHandler{}
ctx := sdk.Context{}.WithIsCheckTx(true)
_, err := decorator.AnteHandle(ctx, tx, false, mmd.AnteHandle)
_, err = decorator.AnteHandle(ctx, tx, false, mmd.AnteHandle)
require.Error(t, err)
require.False(t, mmd.WasCalled)
}
// generatePrivKeyAddressPairsFromRand generates (deterministically) a total of n private keys and addresses.
func generatePrivKeyAddressPairs(n int) (keys []crypto.PrivKey, addrs []sdk.AccAddress) {
r := rand.New(rand.NewSource(12345)) // make the generation deterministic
keys = make([]crypto.PrivKey, n)
addrs = make([]sdk.AccAddress, n)
for i := 0; i < n; i++ {
secret := make([]byte, 32)
_, err := r.Read(secret)
if err != nil {
panic("Could not read randomness")
}
keys[i] = secp256k1.GenPrivKeySecp256k1(secret)
addrs[i] = sdk.AccAddress(keys[i].PubKey().Address())
}
return
}

24
app/ante/vesting.go Normal file
View File

@ -0,0 +1,24 @@
package ante
import (
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"
)
// VestingAccountDecorator blocks MsgCreateVestingAccount from reaching the mempool
type VestingAccountDecorator struct{}
func NewVestingAccountDecorator() VestingAccountDecorator {
return VestingAccountDecorator{}
}
func (vad VestingAccountDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
for _, msg := range tx.GetMsgs() {
if _, ok := msg.(*vesting.MsgCreateVestingAccount); ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "MsgCreateVestingAccount not supported")
}
}
return next(ctx, tx, simulate)
}

45
app/ante/vesting_test.go Normal file
View File

@ -0,0 +1,45 @@
package ante_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
sdk "github.com/cosmos/cosmos-sdk/types"
vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/app/ante"
)
func TestVestingMempoolDecorator_MsgCreateVestingAccount_Unauthorized(t *testing.T) {
txConfig := app.MakeEncodingConfig().TxConfig
testPrivKeys, testAddresses := app.GeneratePrivKeyAddressPairs(5)
decorator := ante.NewVestingAccountDecorator()
tx, err := helpers.GenTx(
txConfig,
[]sdk.Msg{
vesting.NewMsgCreateVestingAccount(
testAddresses[0], testAddresses[1],
sdk.NewCoins(sdk.NewInt64Coin("ukava", 100_000_000)),
time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC).Unix(), false),
},
sdk.NewCoins(),
helpers.DefaultGenTxGas,
"testing-chain-id",
[]uint64{0},
[]uint64{0},
testPrivKeys[0],
)
require.NoError(t, err)
mmd := MockAnteHandler{}
ctx := sdk.Context{}.WithIsCheckTx(true)
_, err = decorator.AnteHandle(ctx, tx, false, mmd.AnteHandle)
require.Error(t, err)
require.Contains(t, err.Error(), "MsgCreateVestingAccount not supported")
}

File diff suppressed because it is too large Load Diff

View File

@ -4,53 +4,59 @@ import (
"os"
"testing"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log"
db "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/codec"
abci "github.com/tendermint/tendermint/abci/types"
)
func TestExport(t *testing.T) {
db := db.NewMemDB()
app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, AppOptions{})
setGenesis(app)
func TestNewApp(t *testing.T) {
// Making a new app object with the db, so that initchain hasn't been called
newApp := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, AppOptions{})
_, _, err := newApp.ExportAppStateAndValidators(false, []string{})
require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
}
// ensure that black listed addresses are properly set in bank keeper
func TestBlackListedAddrs(t *testing.T) {
db := db.NewMemDB()
app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, AppOptions{})
for acc := range mAccPerms {
require.Equal(t, !allowedReceivingModAcc[acc], app.bankKeeper.BlacklistedAddr(app.supplyKeeper.GetModuleAddress(acc)))
}
}
func setGenesis(app *App) error {
genesisState := NewDefaultGenesisState()
stateBytes, err := codec.MarshalJSONIndent(app.cdc, genesisState)
if err != nil {
return err
}
// Initialize the chain
app.InitChain(
abci.RequestInitChain{
Validators: []abci.ValidatorUpdate{},
AppStateBytes: stateBytes,
},
NewApp(
log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
db.NewMemDB(),
DefaultNodeHome,
nil,
MakeEncodingConfig(),
Options{},
)
app.Commit()
return nil
}
// func TestExport(t *testing.T) {
// db := db.NewMemDB()
// app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, AppOptions{})
// setGenesis(app)
// // Making a new app object with the db, so that initchain hasn't been called
// newApp := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, AppOptions{})
// _, _, err := newApp.ExportAppStateAndValidators(false, []string{})
// require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
// }
// // ensure that black listed addresses are properly set in bank keeper
// func TestBlackListedAddrs(t *testing.T) {
// db := db.NewMemDB()
// app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, AppOptions{})
// for acc := range mAccPerms {
// require.Equal(t, !allowedReceivingModAcc[acc], app.bankKeeper.BlacklistedAddr(app.supplyKeeper.GetModuleAddress(acc)))
// }
// }
// func setGenesis(app *App) error {
// genesisState := NewDefaultGenesisState()
// stateBytes, err := codec.MarshalJSONIndent(app.cdc, genesisState)
// if err != nil {
// return err
// }
// // Initialize the chain
// app.InitChain(
// abci.RequestInitChain{
// Validators: []abci.ValidatorUpdate{},
// AppStateBytes: stateBytes,
// },
// )
// app.Commit()
// return nil
// }

41
app/config.go Normal file
View File

@ -0,0 +1,41 @@
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)
}

17
app/encoding.go Normal file
View File

@ -0,0 +1,17 @@
package app
import (
"github.com/cosmos/cosmos-sdk/std"
"github.com/kava-labs/kava/app/params"
)
// MakeEncodingConfig creates an EncodingConfig and registers the app's types on it.
func MakeEncodingConfig() params.EncodingConfig {
encodingConfig := params.MakeEncodingConfig()
std.RegisterLegacyAminoCodec(encodingConfig.Amino)
std.RegisterInterfaces(encodingConfig.InterfaceRegistry)
ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino)
ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry)
return encodingConfig
}

View File

@ -4,33 +4,40 @@ import (
"encoding/json"
"log"
abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/codec"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// ExportAppStateAndValidators export the state of the app for a genesis file
func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []string,
) (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) {
) (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
ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()})
ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
height := app.LastBlockHeight() + 1
if forZeroHeight {
height = 0
app.prepForZeroHeightGenesis(ctx, jailWhiteList)
}
genState := app.mm.ExportGenesis(ctx)
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
genState := app.mm.ExportGenesis(ctx, app.appCodec)
newAppState, err := json.MarshalIndent(genState, "", " ")
if err != nil {
return nil, nil, err
return servertypes.ExportedApp{}, err
}
validators = staking.WriteValidators(ctx, app.stakingKeeper)
return appState, validators, nil
validators, err := staking.WriteValidators(ctx, app.stakingKeeper)
return servertypes.ExportedApp{
AppState: newAppState,
Validators: validators,
Height: height,
ConsensusParams: app.BaseApp.GetConsensusParams(ctx),
}, err
}
// prepare for fresh start at zero height
@ -60,25 +67,24 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string
/* Handle fee distribution state. */
// withdraw all validator commission
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val staking.ValidatorI) (stop bool) {
accumCommission := app.distrKeeper.GetValidatorAccumulatedCommission(ctx, val.GetOperator())
if accumCommission.IsZero() {
return false
}
_, err := app.distrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
if err != nil {
log.Fatal(err)
}
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
_, _ = app.distrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
return false
})
// withdraw all delegator rewards
dels := app.stakingKeeper.GetAllDelegations(ctx)
for _, delegation := range dels {
_, err := app.distrKeeper.WithdrawDelegationRewards(ctx, delegation.DelegatorAddress, delegation.ValidatorAddress)
valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
if err != nil {
log.Fatal(err)
panic(err)
}
delAddr, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
if err != nil {
panic(err)
}
_, _ = app.distrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
}
// clear validator slash events
@ -92,10 +98,9 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string
ctx = ctx.WithBlockHeight(0)
// reinitialize all validators
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val staking.ValidatorI) (stop bool) {
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
scraps := app.distrKeeper.GetValidatorOutstandingRewards(ctx, val.GetOperator())
scraps := app.distrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator())
feePool := app.distrKeeper.GetFeePool(ctx)
feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
app.distrKeeper.SetFeePool(ctx, feePool)
@ -106,8 +111,16 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string
// reinitialize all delegations
for _, del := range dels {
app.distrKeeper.Hooks().BeforeDelegationCreated(ctx, del.DelegatorAddress, del.ValidatorAddress)
app.distrKeeper.Hooks().AfterDelegationModified(ctx, del.DelegatorAddress, del.ValidatorAddress)
valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
if err != nil {
panic(err)
}
delAddr, err := sdk.AccAddressFromBech32(del.DelegatorAddress)
if err != nil {
panic(err)
}
app.distrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr)
app.distrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr)
}
// reset context height
@ -116,7 +129,7 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string
/* Handle staking state. */
// iterate through redelegations, reset creation height
app.stakingKeeper.IterateRedelegations(ctx, func(_ int64, red staking.Redelegation) (stop bool) {
app.stakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) {
for i := range red.Entries {
red.Entries[i].CreationHeight = 0
}
@ -125,7 +138,7 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string
})
// iterate through unbonding delegations, reset creation height
app.stakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd staking.UnbondingDelegation) (stop bool) {
app.stakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) {
for i := range ubd.Entries {
ubd.Entries[i].CreationHeight = 0
}
@ -135,12 +148,12 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string
// Iterate through validators by power descending, reset bond heights, and
// update bond intra-tx counters.
store := ctx.KVStore(app.keys[staking.StoreKey])
iter := sdk.KVStoreReversePrefixIterator(store, staking.ValidatorsKey)
store := ctx.KVStore(app.keys[stakingtypes.StoreKey])
iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
counter := int16(0)
for ; iter.Valid(); iter.Next() {
addr := sdk.ValAddress(iter.Key()[1:])
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
validator, found := app.stakingKeeper.GetValidator(ctx, addr)
if !found {
panic("expected validator, not found")
@ -157,14 +170,17 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string
iter.Close()
_ = app.stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
_, err := app.stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
if err != nil {
log.Fatal(err)
}
/* Handle slashing state. */
// reset start height on signing infos
app.slashingKeeper.IterateValidatorSigningInfos(
ctx,
func(addr sdk.ConsAddress, info slashing.ValidatorSigningInfo) (stop bool) {
func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) {
info.StartHeight = 0
app.slashingKeeper.SetValidatorSigningInfo(ctx, addr, info)
return false

View File

@ -9,5 +9,6 @@ type GenesisState map[string]json.RawMessage
// NewDefaultGenesisState generates the default state for the application.
func NewDefaultGenesisState() GenesisState {
return ModuleBasics.DefaultGenesis()
encCfg := MakeEncodingConfig()
return ModuleBasics.DefaultGenesis(encCfg.Marshaler)
}

View File

@ -0,0 +1,84 @@
package app
import (
"net/http"
"github.com/cosmos/cosmos-sdk/client"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
"github.com/gorilla/mux"
)
// RegisterLegacyTxRoutes registers a legacy tx routes that use amino encoding json
func RegisterLegacyTxRoutes(clientCtx client.Context, r *mux.Router) {
r.HandleFunc("/txs", legacyTxBroadcast(clientCtx)).Methods("POST")
}
// LegacyTxBroadcastRequest represents a broadcast request with an amino json encoded transaction
type LegacyTxBroadcastRequest struct {
Tx legacytx.StdTx `json:"tx"`
Mode string `json:"mode"`
}
var _ codectypes.UnpackInterfacesMessage = LegacyTxBroadcastRequest{}
// UnpackInterfaces implements the UnpackInterfacesMessage interface
func (m LegacyTxBroadcastRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
return m.Tx.UnpackInterfaces(unpacker)
}
func legacyTxBroadcast(clientCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req LegacyTxBroadcastRequest
if !rest.ReadRESTReq(w, r, clientCtx.LegacyAmino, &req) {
return
}
tx := req.Tx
builder := clientCtx.TxConfig.NewTxBuilder()
err := builder.SetMsgs(tx.GetMsgs()...)
if rest.CheckBadRequestError(w, err) {
return
}
builder.SetFeeAmount(tx.GetFee())
builder.SetGasLimit(tx.GetGas())
builder.SetMemo(req.Tx.GetMemo())
builder.SetTimeoutHeight(req.Tx.GetTimeoutHeight())
signatures, err := tx.GetSignaturesV2()
if rest.CheckBadRequestError(w, err) {
return
}
for i, sig := range signatures {
addr := sdk.AccAddress(sig.PubKey.Address())
_, seq, err := clientCtx.AccountRetriever.GetAccountNumberSequence(clientCtx, addr)
if rest.CheckBadRequestError(w, err) {
return
}
signatures[i].Sequence = seq
}
err = builder.SetSignatures(signatures...)
if rest.CheckBadRequestError(w, err) {
return
}
txBytes, err := clientCtx.TxConfig.TxEncoder()(builder.GetTx())
if rest.CheckInternalServerError(w, err) {
return
}
clientCtx = clientCtx.WithBroadcastMode(req.Mode)
res, err := clientCtx.BroadcastTx(txBytes)
if rest.CheckInternalServerError(w, err) {
return
}
rest.PostProcessResponseBare(w, clientCtx, res)
}
}

View File

@ -0,0 +1,194 @@
package app_test
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
"github.com/golang/mock/gomock"
"github.com/kava-labs/kava/app"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/tests/mocks"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/gorilla/mux"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
rpchttp "github.com/tendermint/tendermint/rpc/client/http"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
jsonrpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
tmtypes "github.com/tendermint/tendermint/types"
)
type LegacyTxBroadcastTestSuite struct {
suite.Suite
clientCtx client.Context
restServer *httptest.Server
rpcServer *httptest.Server
ctrl *gomock.Controller
accountRetriever *mocks.MockAccountRetriever
simulateResponse func(jsonrpctypes.RPCRequest) jsonrpctypes.RPCResponse
}
func (suite *LegacyTxBroadcastTestSuite) SetupTest() {
app.SetSDKConfig()
// setup the mock rpc server
suite.rpcServer = rpcTestServer(suite.T(), func(request jsonrpctypes.RPCRequest) jsonrpctypes.RPCResponse {
suite.Require().Equal("broadcast_tx_sync", request.Method)
return suite.simulateResponse(request)
})
// setup client context with rpc client, account retriever mock, codecs, and tx config
rpcClient, err := rpchttp.New(suite.rpcServer.URL, "/websocket")
suite.Require().NoError(err)
suite.ctrl = gomock.NewController(suite.T())
suite.accountRetriever = mocks.NewMockAccountRetriever(suite.ctrl)
encodingConfig := app.MakeEncodingConfig()
suite.clientCtx = client.Context{}.
WithCodec(encodingConfig.Marshaler).
WithTxConfig(encodingConfig.TxConfig).
WithLegacyAmino(encodingConfig.Amino).
WithNodeURI(suite.rpcServer.URL).
WithClient(rpcClient).
WithAccountRetriever(suite.accountRetriever)
// setup rest server
router := mux.NewRouter()
app.RegisterLegacyTxRoutes(suite.clientCtx, router)
suite.restServer = httptest.NewServer(router)
}
func (suite *LegacyTxBroadcastTestSuite) TearDownTest() {
suite.rpcServer.Close()
suite.restServer.Close()
suite.ctrl.Finish()
}
func (suite *LegacyTxBroadcastTestSuite) TestSimulateRequest() {
_, pk, fromAddr := testdata.KeyTestPubAddr()
toAddr, err := sdk.AccAddressFromBech32("kava1mq9qxlhze029lm0frzw2xr6hem8c3k9ts54w0w")
suite.Require().NoError(err)
// build a legacy transaction
msgs := []sdk.Msg{banktypes.NewMsgSend(fromAddr, toAddr, sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))))}
fee := legacytx.NewStdFee(1e6, sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(5e4))))
sigs := []legacytx.StdSignature{legacytx.NewStdSignature(pk, []byte("an amino json signed signature"))}
stdTx := legacytx.NewStdTx(msgs, fee, sigs, "legacy broadcast test")
stdTx.TimeoutHeight = 100000
txReq := app.LegacyTxBroadcastRequest{
Tx: stdTx,
Mode: "sync",
}
// setup mock tendermint jsonrpc handler for BroadcastTx
var broadcastedTx authsigning.Tx
var broadcastedTxHash tmbytes.HexBytes
suite.simulateResponse = func(rpcRequest jsonrpctypes.RPCRequest) jsonrpctypes.RPCResponse {
var params struct {
Tx tmtypes.Tx `json:"tx"`
}
err := json.Unmarshal(rpcRequest.Params, &params)
suite.Require().NoError(err)
decodedTx, err := suite.clientCtx.TxConfig.TxDecoder()(params.Tx)
suite.Require().NoError(err)
wrappedTx, err := suite.clientCtx.TxConfig.WrapTxBuilder(decodedTx)
suite.Require().NoError(err)
broadcastedTx = wrappedTx.GetTx()
broadcastedTxHash = params.Tx.Hash()
resp := &ctypes.ResultBroadcastTx{
Log: "[]",
Hash: broadcastedTxHash,
}
result, err := suite.clientCtx.LegacyAmino.MarshalJSON(resp)
suite.Require().NoError(err)
return jsonrpctypes.RPCResponse{
JSONRPC: rpcRequest.JSONRPC,
ID: rpcRequest.ID,
Result: json.RawMessage(result),
}
}
// mock account sequence retrieval
suite.accountRetriever.EXPECT().
GetAccountNumberSequence(suite.clientCtx, fromAddr).
Return(uint64(100), uint64(101), nil)
// amino encode legacy tx
requestBody, err := suite.clientCtx.LegacyAmino.MarshalJSON(txReq)
suite.Require().NoError(err)
// post transaction to POST /txs
req, err := http.NewRequest("POST", suite.restServer.URL+"/txs", bytes.NewBuffer(requestBody))
suite.Require().NoError(err)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
suite.Require().NoError(err)
defer resp.Body.Close()
// assert broadcasted tx has all information
suite.Equal(msgs, broadcastedTx.GetMsgs())
suite.Equal(fee.Amount, broadcastedTx.GetFee())
suite.Equal(fee.Gas, broadcastedTx.GetGas())
suite.Equal(stdTx.TimeoutHeight, broadcastedTx.GetTimeoutHeight())
suite.Equal(stdTx.Memo, broadcastedTx.GetMemo())
// assert broadcasted tx has correct signature
stdSignatures, err := stdTx.GetSignaturesV2()
suite.Require().NoError(err)
stdSignatures[0].Sequence = uint64(101)
broadcastedSigs, err := broadcastedTx.GetSignaturesV2()
suite.Require().NoError(err)
suite.Equal(stdSignatures, broadcastedSigs)
// decode response body
body, err := ioutil.ReadAll(resp.Body)
suite.Require().NoError(err)
var txResponse sdk.TxResponse
err = suite.clientCtx.LegacyAmino.UnmarshalJSON(body, &txResponse)
suite.Require().NoError(err)
// ensure response is correct
suite.Equal("[]", txResponse.RawLog)
suite.Equal(broadcastedTxHash.String(), txResponse.TxHash)
}
func TestLegacyTxBroadcastTestSuite(t *testing.T) {
suite.Run(t, new(LegacyTxBroadcastTestSuite))
}
func rpcTestServer(
t *testing.T,
rpcHandler func(jsonrpctypes.RPCRequest) jsonrpctypes.RPCResponse,
) *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
require.NoError(t, err)
var request jsonrpctypes.RPCRequest
err = json.Unmarshal(body, &request)
require.NoError(t, err)
response := rpcHandler(request)
b, err := json.Marshal(&response)
require.NoError(t, err)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, _ = w.Write(b)
}))
}

32
app/params/encoding.go Normal file
View File

@ -0,0 +1,32 @@
package params
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
)
// EncodingConfig specifies the concrete encoding types to use for a given app.
// This is provided for compatibility between protobuf and amino implementations.
type EncodingConfig struct {
InterfaceRegistry types.InterfaceRegistry
Marshaler codec.Codec
TxConfig client.TxConfig
Amino *codec.LegacyAmino
}
// MakeEncodingConfig creates a new EncodingConfig.
func MakeEncodingConfig() EncodingConfig {
amino := codec.NewLegacyAmino()
interfaceRegistry := types.NewInterfaceRegistry()
marshaler := codec.NewProtoCodec(interfaceRegistry)
txCfg := tx.NewTxConfig(marshaler, tx.DefaultSignModes)
return EncodingConfig{
InterfaceRegistry: interfaceRegistry,
Marshaler: marshaler,
TxConfig: txCfg,
Amino: amino,
}
}

View File

@ -1,5 +1,7 @@
package params
// TODO this has not been updated for v0.44
// Simulation parameter constants
const (
StakePerAccount = "stake_per_account"

112
app/test_builder.go Normal file
View File

@ -0,0 +1,112 @@
package app
import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
// AuthBankGenesisBuilder is a tool for creating a combined auth and bank genesis state.
// Helper methods create basic accounts types and add them to a default genesis state.
// 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()
//
type AuthBankGenesisBuilder struct {
AuthGenesis authtypes.GenesisState
BankGenesis banktypes.GenesisState
}
// NewAuthBankGenesisBuilder creates a AuthBankGenesisBuilder containing default genesis states.
func NewAuthBankGenesisBuilder() *AuthBankGenesisBuilder {
return &AuthBankGenesisBuilder{
AuthGenesis: *authtypes.DefaultGenesisState(),
BankGenesis: *banktypes.DefaultGenesisState(),
}
}
// BuildMarshalled assembles the final GenesisState and json encodes it into a generic genesis type.
func (builder *AuthBankGenesisBuilder) BuildMarshalled(cdc codec.JSONCodec) GenesisState {
return GenesisState{
authtypes.ModuleName: cdc.MustMarshalJSON(&builder.AuthGenesis),
banktypes.ModuleName: cdc.MustMarshalJSON(&builder.BankGenesis),
}
}
// WithAccounts adds accounts of any type to the genesis state.
func (builder *AuthBankGenesisBuilder) WithAccounts(account ...authtypes.GenesisAccount) *AuthBankGenesisBuilder {
existing, err := authtypes.UnpackAccounts(builder.AuthGenesis.Accounts)
if err != nil {
panic(err)
}
existing = append(existing, account...)
existingPacked, err := authtypes.PackAccounts(existing)
if err != nil {
panic(err)
}
builder.AuthGenesis.Accounts = existingPacked
return builder
}
// WithBalances adds balances to the bank genesis state.
// It does not check the new denom is in the genesis state denom metadata.
func (builder *AuthBankGenesisBuilder) WithBalances(balance ...banktypes.Balance) *AuthBankGenesisBuilder {
builder.BankGenesis.Balances = append(builder.BankGenesis.Balances, balance...)
if !builder.BankGenesis.Supply.Empty() {
for _, b := range balance {
builder.BankGenesis.Supply = builder.BankGenesis.Supply.Add(b.Coins...)
}
}
return builder
}
// WithSimpleAccount adds a standard account to the genesis state.
func (builder *AuthBankGenesisBuilder) WithSimpleAccount(address sdk.AccAddress, balance sdk.Coins) *AuthBankGenesisBuilder {
return builder.
WithAccounts(authtypes.NewBaseAccount(address, nil, 0, 0)).
WithBalances(banktypes.Balance{Address: address.String(), Coins: balance})
}
// WithSimpleModuleAccount adds a module account to the genesis state.
func (builder *AuthBankGenesisBuilder) WithSimpleModuleAccount(moduleName string, balance sdk.Coins, permissions ...string) *AuthBankGenesisBuilder {
account := authtypes.NewEmptyModuleAccount(moduleName, permissions...)
return builder.
WithAccounts(account).
WithBalances(banktypes.Balance{Address: account.Address, Coins: balance})
}
// WithSimplePeriodicVestingAccount adds a periodic vesting account to the genesis state.
func (builder *AuthBankGenesisBuilder) WithSimplePeriodicVestingAccount(address sdk.AccAddress, balance sdk.Coins, periods vestingtypes.Periods, firstPeriodStartTimestamp int64) *AuthBankGenesisBuilder {
vestingAccount := newPeriodicVestingAccount(address, periods, firstPeriodStartTimestamp)
return builder.
WithAccounts(vestingAccount).
WithBalances(banktypes.Balance{Address: address.String(), Coins: balance})
}
// newPeriodicVestingAccount creates a periodic vesting account from a set of vesting periods.
func newPeriodicVestingAccount(address sdk.AccAddress, periods vestingtypes.Periods, firstPeriodStartTimestamp int64) *vestingtypes.PeriodicVestingAccount {
baseAccount := authtypes.NewBaseAccount(address, nil, 0, 0)
originalVesting := sdk.NewCoins()
for _, p := range periods {
originalVesting = originalVesting.Add(p.Amount...)
}
var totalPeriods int64
for _, p := range periods {
totalPeriods += p.Length
}
endTime := firstPeriodStartTimestamp + totalPeriods
baseVestingAccount := vestingtypes.NewBaseVestingAccount(baseAccount, originalVesting, endTime)
return vestingtypes.NewPeriodicVestingAccountRaw(baseVestingAccount, firstPeriodStartTimestamp, periods)
}

View File

@ -1,46 +1,43 @@
package app
import (
"encoding/json"
"math/rand"
"testing"
"time"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
distkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
hardkeeper "github.com/kava-labs/kava/x/hard/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"
tmdb "github.com/tendermint/tm-db"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/crisis"
"github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/supply"
"github.com/cosmos/cosmos-sdk/x/upgrade"
"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/hard"
"github.com/kava-labs/kava/x/incentive"
"github.com/kava-labs/kava/x/issuance"
"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"
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"
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"
pricefeedkeeper "github.com/kava-labs/kava/x/pricefeed/keeper"
swapkeeper "github.com/kava-labs/kava/x/swap/keeper"
)
var (
@ -62,45 +59,56 @@ type TestApp struct {
App
}
// NewTestApp creates a new TestApp
//
// Note, it also sets the sdk config with the app's address prefix, coin type, etc.
func NewTestApp() TestApp {
config := sdk.GetConfig()
SetBech32AddressPrefixes(config)
SetBip44CoinType(config)
SetSDKConfig()
db := tmdb.NewMemDB()
app := NewApp(log.NewNopLogger(), db, nil, AppOptions{})
return TestApp{App: *app}
return NewTestAppFromSealed()
}
// NewTestAppFromSealed creates a TestApp without first setting sdk config.
func NewTestAppFromSealed() TestApp {
db := tmdb.NewMemDB()
app := NewApp(log.NewNopLogger(), db, nil, AppOptions{})
encCfg := MakeEncodingConfig()
app := NewApp(log.NewNopLogger(), db, DefaultNodeHome, nil, encCfg, Options{})
return TestApp{App: *app}
}
// nolint
func (tApp TestApp) GetAccountKeeper() auth.AccountKeeper { return tApp.accountKeeper }
func (tApp TestApp) GetBankKeeper() bank.Keeper { return tApp.bankKeeper }
func (tApp TestApp) GetSupplyKeeper() supply.Keeper { return tApp.supplyKeeper }
func (tApp TestApp) GetStakingKeeper() staking.Keeper { return tApp.stakingKeeper }
func (tApp TestApp) GetSlashingKeeper() slashing.Keeper { return tApp.slashingKeeper }
func (tApp TestApp) GetMintKeeper() mint.Keeper { return tApp.mintKeeper }
func (tApp TestApp) GetDistrKeeper() distribution.Keeper { return tApp.distrKeeper }
func (tApp TestApp) GetGovKeeper() gov.Keeper { return tApp.govKeeper }
func (tApp TestApp) GetCrisisKeeper() crisis.Keeper { return tApp.crisisKeeper }
func (tApp TestApp) GetUpgradeKeeper() upgrade.Keeper { return tApp.upgradeKeeper }
func (tApp TestApp) GetParamsKeeper() params.Keeper { return tApp.paramsKeeper }
func (tApp TestApp) GetVVKeeper() validatorvesting.Keeper { return tApp.vvKeeper }
func (tApp TestApp) GetAuctionKeeper() auction.Keeper { return tApp.auctionKeeper }
func (tApp TestApp) GetCDPKeeper() cdp.Keeper { return tApp.cdpKeeper }
func (tApp TestApp) GetPriceFeedKeeper() pricefeed.Keeper { return tApp.pricefeedKeeper }
func (tApp TestApp) GetBep3Keeper() bep3.Keeper { return tApp.bep3Keeper }
func (tApp TestApp) GetKavadistKeeper() kavadist.Keeper { return tApp.kavadistKeeper }
func (tApp TestApp) GetIncentiveKeeper() incentive.Keeper { return tApp.incentiveKeeper }
func (tApp TestApp) GetHardKeeper() hard.Keeper { return tApp.hardKeeper }
func (tApp TestApp) GetCommitteeKeeper() committee.Keeper { return tApp.committeeKeeper }
func (tApp TestApp) GetIssuanceKeeper() issuance.Keeper { return tApp.issuanceKeeper }
func (tApp TestApp) GetSwapKeeper() swap.Keeper { return tApp.swapKeeper }
func (tApp TestApp) GetAccountKeeper() authkeeper.AccountKeeper { return tApp.accountKeeper }
func (tApp TestApp) GetBankKeeper() bankkeeper.Keeper { return tApp.bankKeeper }
func (tApp TestApp) GetStakingKeeper() stakingkeeper.Keeper { return tApp.stakingKeeper }
func (tApp TestApp) GetSlashingKeeper() slashingkeeper.Keeper { return tApp.slashingKeeper }
func (tApp TestApp) GetMintKeeper() mintkeeper.Keeper { return tApp.mintKeeper }
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 }
// LegacyAmino returns the app's amino codec.
func (app *App) LegacyAmino() *codec.LegacyAmino {
return app.legacyAmino
}
// AppCodec returns the app's app codec.
func (app *App) AppCodec() codec.Codec {
return app.appCodec
}
// InitializeFromGenesisStates calls InitChain on the app using the default genesis state, overwitten with any passed in genesis states
func (tApp TestApp) InitializeFromGenesisStates(genesisStates ...GenesisState) TestApp {
@ -123,7 +131,7 @@ func (tApp TestApp) InitializeFromGenesisStatesWithTimeAndChainID(genTime time.T
}
// Initialize the chain
stateBytes, err := codec.MarshalJSONIndent(tApp.cdc, genesisState)
stateBytes, err := json.Marshal(genesisState)
if err != nil {
panic(err)
}
@ -136,20 +144,43 @@ func (tApp TestApp) InitializeFromGenesisStatesWithTimeAndChainID(genTime time.T
},
)
tApp.Commit()
tApp.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: tApp.LastBlockHeight() + 1, Time: genTime}})
tApp.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: tApp.LastBlockHeight() + 1, Time: genTime}})
return tApp
}
// CheckBalance requires the account address has the expected amount of coins.
func (tApp TestApp) CheckBalance(t *testing.T, ctx sdk.Context, owner sdk.AccAddress, expectedCoins sdk.Coins) {
acc := tApp.GetAccountKeeper().GetAccount(ctx, owner)
require.NotNilf(t, acc, "account with address '%s' doesn't exist", owner)
require.Equal(t, expectedCoins, acc.GetCoins())
coins := tApp.GetBankKeeper().GetAllBalances(ctx, owner)
require.Equal(t, expectedCoins, coins)
}
// GeneratePrivKeyAddressPairsFromRand generates (deterministically) a total of n secp256k1 private keys and addresses.
func GeneratePrivKeyAddressPairs(n int) (keys []crypto.PrivKey, addrs []sdk.AccAddress) {
// FundAccount is a utility function that funds an account by minting and sending the coins to the address.
func (tApp TestApp) FundAccount(ctx sdk.Context, addr sdk.AccAddress, amounts sdk.Coins) error {
if err := tApp.bankKeeper.MintCoins(ctx, minttypes.ModuleName, amounts); err != nil {
return err
}
return tApp.bankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, amounts)
}
// NewQueryServerTestHelper creates a new QueryServiceTestHelper that wraps the provided sdk.Context.
func (tApp TestApp) NewQueryServerTestHelper(ctx sdk.Context) *baseapp.QueryServiceTestHelper {
return baseapp.NewQueryServerTestHelper(ctx, tApp.interfaceRegistry)
}
// FundModuleAccount is a utility function that funds a module account by minting and sending the coins to the address.
func (tApp TestApp) FundModuleAccount(ctx sdk.Context, recipientMod string, amounts sdk.Coins) error {
if err := tApp.bankKeeper.MintCoins(ctx, minttypes.ModuleName, amounts); err != nil {
return err
}
return tApp.bankKeeper.SendCoinsFromModuleToModule(ctx, minttypes.ModuleName, recipientMod, amounts)
}
// GeneratePrivKeyAddressPairsFromRand 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([]crypto.PrivKey, n)
keys = make([]cryptotypes.PrivKey, n)
addrs = make([]sdk.AccAddress, n)
for i := 0; i < n; i++ {
secret := make([]byte, 32)
@ -157,107 +188,39 @@ func GeneratePrivKeyAddressPairs(n int) (keys []crypto.PrivKey, addrs []sdk.AccA
if err != nil {
panic("Could not read randomness")
}
keys[i] = secp256k1.GenPrivKeySecp256k1(secret)
keys[i] = secp256k1.GenPrivKeyFromSecret(secret)
addrs[i] = sdk.AccAddress(keys[i].PubKey().Address())
}
return
}
// Create a new auth genesis state from some addresses and coins. The state is returned marshalled into a map.
func NewAuthGenState(addresses []sdk.AccAddress, coins []sdk.Coins) GenesisState {
// Create GenAccounts
accounts := authexported.GenesisAccounts{}
for i := range addresses {
accounts = append(accounts, auth.NewBaseAccount(addresses[i], coins[i], nil, 0, 0))
// NewFundedGenStateWithSameCoins creates a (auth and bank) genesis state populated with accounts from the given addresses and balance.
func NewFundedGenStateWithSameCoins(cdc codec.JSONCodec, balance sdk.Coins, addresses []sdk.AccAddress) GenesisState {
builder := NewAuthBankGenesisBuilder()
for _, address := range addresses {
builder.WithSimpleAccount(address, balance)
}
// Create the auth genesis state
authGenesis := auth.NewGenesisState(auth.DefaultParams(), accounts)
return GenesisState{auth.ModuleName: auth.ModuleCdc.MustMarshalJSON(authGenesis)}
return builder.BuildMarshalled(cdc)
}
// AuthGenesisBuilder is a tool for creating an auth genesis state.
// Helper methods create basic accounts types and add them to a default genesis state.
// All methods are immutable and return updated copies of the builder.
// The builder inherits from auth.GenesisState, so fields can be accessed directly if a helper method doesn't exist.
//
// Example:
// // create a single account genesis state
// builder := NewAuthGenesisBuilder().WithSimpleAccount(testUserAddress, testCoins)
// genesisState := builder.Build()
//
type AuthGenesisBuilder struct {
auth.GenesisState
}
// NewAuthGenesisBuilder creates a AuthGenesisBuilder containing a default genesis state.
func NewAuthGenesisBuilder() AuthGenesisBuilder {
return AuthGenesisBuilder{
GenesisState: auth.DefaultGenesisState(),
// NewFundedGenStateWithCoins creates a (auth and bank) genesis state populated with accounts from the given addresses and coins.
func NewFundedGenStateWithCoins(cdc codec.JSONCodec, coins []sdk.Coins, addresses []sdk.AccAddress) GenesisState {
builder := NewAuthBankGenesisBuilder()
for i, address := range addresses {
builder.WithSimpleAccount(address, coins[i])
}
return builder.BuildMarshalled(cdc)
}
// Build assembles and returns the final GenesisState
func (builder AuthGenesisBuilder) Build() auth.GenesisState {
return builder.GenesisState
}
// NewFundedGenStateWithSameCoinsWithModuleAccount creates a (auth and bank) genesis state populated with accounts from the given addresses and balance along with an empty module account
func NewFundedGenStateWithSameCoinsWithModuleAccount(cdc codec.JSONCodec, coins sdk.Coins, addresses []sdk.AccAddress, modAcc *authtypes.ModuleAccount) GenesisState {
builder := NewAuthBankGenesisBuilder()
// BuildMarshalled assembles the final GenesisState and json encodes it into a generic genesis type.
func (builder AuthGenesisBuilder) BuildMarshalled() GenesisState {
return GenesisState{
auth.ModuleName: auth.ModuleCdc.MustMarshalJSON(builder.Build()),
}
}
// WithAccounts adds accounts of any type to the genesis state.
func (builder AuthGenesisBuilder) WithAccounts(account ...authexported.GenesisAccount) AuthGenesisBuilder {
builder.Accounts = append(builder.Accounts, account...)
return builder
}
// WithSimpleAccount adds a standard account to the genesis state.
func (builder AuthGenesisBuilder) WithSimpleAccount(address sdk.AccAddress, balance sdk.Coins) AuthGenesisBuilder {
return builder.WithAccounts(auth.NewBaseAccount(address, balance, nil, 0, 0))
}
// WithSimpleModuleAccount adds a module account to the genesis state.
func (builder AuthGenesisBuilder) WithSimpleModuleAccount(moduleName string, balance sdk.Coins, permissions ...string) AuthGenesisBuilder {
account := supply.NewEmptyModuleAccount(moduleName, permissions...)
account.SetCoins(balance)
return builder.WithAccounts(account)
}
// WithSimplePeriodicVestingAccount adds a periodic vesting account to the genesis state.
func (builder AuthGenesisBuilder) WithSimplePeriodicVestingAccount(address sdk.AccAddress, balance sdk.Coins, periods vesting.Periods, firstPeriodStartTimestamp int64) AuthGenesisBuilder {
baseAccount := auth.NewBaseAccount(address, balance, nil, 0, 0)
originalVesting := sdk.NewCoins()
for _, p := range periods {
originalVesting = originalVesting.Add(p.Amount...)
for _, address := range addresses {
builder.WithSimpleAccount(address, coins)
}
var totalPeriods int64
for _, p := range periods {
totalPeriods += p.Length
}
endTime := firstPeriodStartTimestamp + totalPeriods
builder.WithSimpleModuleAccount(modAcc.Address, nil)
baseVestingAccount, err := vesting.NewBaseVestingAccount(baseAccount, originalVesting, endTime)
if err != nil {
panic(err.Error())
}
periodicVestingAccount := vesting.NewPeriodicVestingAccountRaw(baseVestingAccount, firstPeriodStartTimestamp, periods)
return builder.WithAccounts(periodicVestingAccount)
}
// WithEmptyValidatorVestingAccount adds a stub validator vesting account to the genesis state.
func (builder AuthGenesisBuilder) WithEmptyValidatorVestingAccount(address sdk.AccAddress) AuthGenesisBuilder {
// TODO create a validator vesting account builder and remove this method
bacc := auth.NewBaseAccount(address, nil, nil, 0, 0)
bva, err := vesting.NewBaseVestingAccount(bacc, nil, 1)
if err != nil {
panic(err.Error())
}
account := validatorvesting.NewValidatorVestingAccountRaw(bva, 0, nil, sdk.ConsAddress{}, nil, 90)
return builder.WithAccounts(account)
return builder.BuildMarshalled(cdc)
}

4
buf.work.yaml Normal file
View File

@ -0,0 +1,4 @@
version: v1
directories:
- proto
- third_party/proto

2
cli_test/go.mod Normal file
View File

@ -0,0 +1,2 @@
// This file exists to make the go mod tools ignore this directory.
// Without it, go mod will try and download the old sdk v0.39 imports in this directory.

108
client/docs/config.json Normal file
View File

@ -0,0 +1,108 @@
{
"swagger": "2.0",
"info": {
"title": "Kava - gRPC Gateway docs",
"description": "A REST interface for state queries",
"version": "1.0.0"
},
"apis": [
{
"url": "./tmp-swagger-gen/kava/cdp/v1beta1/query.swagger.json",
"tags": {
"rename": {
"Query": "Cdp"
}
},
"operationIds": {
"rename": [
{
"type": "regex",
"from": "(.*)",
"to": "Cdp$1"
}
]
}
},
{
"url": "./tmp-swagger-gen/kava/kavadist/v1beta1/query.swagger.json",
"tags": {
"rename": {
"Query": "KavaDist"
}
},
"operationIds": {
"rename": [
{
"type": "regex",
"from": "(.*)",
"to": "KavaDist$1"
}
]
}
},
{
"url": "./tmp-swagger-gen/kava/bep3/v1beta1/query.swagger.json",
"tags": {
"rename": {
"Query": "Bep3"
}
},
"operationIds": {
"rename": [
{
"type": "regex",
"from": "(.*)",
"to": "Bep3$1"
}
]
}
},
{
"url": "./tmp-swagger-gen/kava/pricefeed/v1beta1/query.swagger.json",
"tags": {
"rename": {
"Query": "Pricefeed"
}
},
"operationIds": {
"rename": [
{
"type": "regex",
"from": "(.*)",
"to": "Pricefeed$1"
}
]
}
},
{
"url": "./tmp-swagger-gen/kava/swap/v1beta1/query.swagger.json",
"tags": {
"rename": {
"Query": "Swap"
}
},
"operationIds": {
"rename": [
{
"type": "regex",
"from": "(.*)",
"to": "Swap$1"
}
]
}
},
{
"url": "./client/docs/cosmos-swagger.yml",
"dereference": {
"circular": "ignore"
},
"paths": {
"exclude": [
"^/cosmos/authz/.*",
"^/cosmos/feegrant/.*"
]
}
}
]
}

39946
client/docs/cosmos-swagger.yml Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

View File

@ -0,0 +1,60 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "swagger.yaml",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
// End Swagger UI call region
window.ui = ui;
};
</script>
</body>
</html>

View File

@ -0,0 +1,75 @@
<!doctype html>
<html lang="en-US">
<head>
<title>Swagger UI: OAuth2 Redirect</title>
</head>
<body>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1);
} else {
qp = location.search.substring(1);
}
arr = qp.split("&");
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value);
}
) : {};
isValid = qp.state === sentState;
if ((
oauth2.auth.schema.get("flow") === "accessCode" ||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
oauth2.auth.schema.get("flow") === "authorization_code"
) && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
});
}
if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
let oauthErrorMsg;
if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
(qp.error_uri ? "More info: "+qp.error_uri : "");
}
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
window.addEventListener('DOMContentLoaded', function () {
run();
});
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

148
cmd/kava/cmd/app.go Normal file
View File

@ -0,0 +1,148 @@
package cmd
import (
"errors"
"fmt"
"io"
"path/filepath"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/server"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/snapshots"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/crisis"
"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"
)
const (
flagMempoolEnableAuth = "mempool.enable-authentication"
flagMempoolAuthAddresses = "mempool.authorized-addresses"
)
// appCreator holds functions used by the sdk server to control the kava app.
// The methods implement types in cosmos-sdk/server/types
type appCreator struct {
encodingConfig params.EncodingConfig
}
// newApp loads config from AppOptions and returns a new app.
func (ac appCreator) newApp(
logger log.Logger,
db db.DB,
traceStore io.Writer,
appOpts servertypes.AppOptions,
) servertypes.Application {
var cache sdk.MultiStorePersistentCache
if cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) {
cache = store.NewCommitKVStoreCacheManager()
}
skipUpgradeHeights := make(map[int64]bool)
for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) {
skipUpgradeHeights[int64(h)] = true
}
pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts)
if err != nil {
panic(err)
}
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)
if err != nil {
panic(err)
}
snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir)
if err != nil {
panic(err)
}
mempoolEnableAuth := cast.ToBool(appOpts.Get(flagMempoolEnableAuth))
mempoolAuthAddresses, err := accAddressesFromBech32(
cast.ToStringSlice(appOpts.Get(flagMempoolAuthAddresses))...,
)
if err != nil {
panic(fmt.Sprintf("could not get authorized address from config: %v", err))
}
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,
},
baseapp.SetPruning(pruningOpts),
baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))),
baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))),
baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(server.FlagHaltTime))),
baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))), // TODO what is this?
baseapp.SetInterBlockCache(cache),
baseapp.SetTrace(cast.ToBool(appOpts.Get(server.FlagTrace))),
baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))),
baseapp.SetSnapshotStore(snapshotStore),
baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(server.FlagStateSyncSnapshotInterval))),
baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(server.FlagStateSyncSnapshotKeepRecent))),
)
}
// appExport writes out an app's state to json.
func (ac appCreator) appExport(
logger log.Logger,
db db.DB,
traceStore io.Writer,
height int64,
forZeroHeight bool,
jailAllowedAddrs []string,
appOpts servertypes.AppOptions,
) (servertypes.ExportedApp, error) {
homePath, ok := appOpts.Get(flags.FlagHome).(string)
if !ok || homePath == "" {
return servertypes.ExportedApp{}, errors.New("application home not set")
}
var tempApp *app.App
if height != -1 {
tempApp = app.NewApp(logger, db, homePath, traceStore, ac.encodingConfig, app.Options{SkipLoadLatest: true, InvariantCheckPeriod: cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod))})
if err := tempApp.LoadHeight(height); err != nil {
return servertypes.ExportedApp{}, err
}
} else {
tempApp = app.NewApp(logger, db, homePath, traceStore, ac.encodingConfig, app.Options{SkipLoadLatest: false, InvariantCheckPeriod: cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod))})
}
return tempApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs)
}
// addStartCmdFlags adds flags to the server start command.
func (ac appCreator) addStartCmdFlags(startCmd *cobra.Command) {
crisis.AddModuleInitFlags(startCmd)
}
// accAddressesFromBech32 converts a slice of bech32 encoded addresses into a slice of address types.
func accAddressesFromBech32(addresses ...string) ([]sdk.AccAddress, error) {
var decodedAddresses []sdk.AccAddress
for _, s := range addresses {
a, err := sdk.AccAddressFromBech32(s)
if err != nil {
return nil, err
}
decodedAddresses = append(decodedAddresses, a)
}
return decodedAddresses, nil
}

36
cmd/kava/cmd/query.go Normal file
View File

@ -0,0 +1,36 @@
package cmd
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/rpc"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
"github.com/spf13/cobra"
"github.com/kava-labs/kava/app"
)
// newQueryCmd creates all the commands for querying blockchain state.
func newQueryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "query",
Aliases: []string{"q"},
Short: "Querying subcommands",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
cmd.AddCommand(
authcmd.GetAccountCmd(),
rpc.ValidatorCommand(),
rpc.BlockCommand(),
authcmd.QueryTxsByEventsCmd(),
authcmd.QueryTxCmd(),
)
app.ModuleBasics.AddQueryCommands(cmd)
cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID")
return cmd
}

97
cmd/kava/cmd/root.go Normal file
View File

@ -0,0 +1,97 @@
package cmd
import (
"os"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/client/debug"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/server"
simdcmd "github.com/cosmos/cosmos-sdk/simapp/simd/cmd"
"github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
"github.com/spf13/cobra"
tmcli "github.com/tendermint/tendermint/libs/cli"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/app/params"
"github.com/kava-labs/kava/migrate"
)
// NewRootCmd creates a new root command for the kava blockchain.
func NewRootCmd() *cobra.Command {
app.SetSDKConfig().Seal()
encodingConfig := app.MakeEncodingConfig()
initClientCtx := client.Context{}.
WithCodec(encodingConfig.Marshaler).
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
WithTxConfig(encodingConfig.TxConfig).
WithLegacyAmino(encodingConfig.Amino).
WithInput(os.Stdin).
WithAccountRetriever(types.AccountRetriever{}).
WithHomeDir(app.DefaultNodeHome).
WithViper("") // TODO this sets the env prefix
rootCmd := &cobra.Command{
Use: "kava",
Short: "Daemon and CLI for the Kava blockchain.",
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
cmd.SetOut(cmd.OutOrStdout())
cmd.SetErr(cmd.ErrOrStderr())
initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())
if err != nil {
return err
}
initClientCtx, err = config.ReadFromClientConfig(initClientCtx)
if err != nil {
return err
}
if err = client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil {
return err
}
return server.InterceptConfigsPreRunHandler(cmd, "", nil)
},
}
addSubCmds(rootCmd, encodingConfig, app.DefaultNodeHome)
return rootCmd
}
// addSubCmds registers all the sub commands used by kava.
func addSubCmds(rootCmd *cobra.Command, encodingConfig params.EncodingConfig, defaultNodeHome string) {
rootCmd.AddCommand(
genutilcli.InitCmd(app.ModuleBasics, defaultNodeHome),
genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, defaultNodeHome),
migrate.MigrateGenesisCmd(),
migrate.AssertInvariantsCmd(encodingConfig),
genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, defaultNodeHome),
genutilcli.ValidateGenesisCmd(app.ModuleBasics),
simdcmd.AddGenesisAccountCmd(defaultNodeHome), // TODO use kava version with vesting accounts
tmcli.NewCompletionCmd(rootCmd, true), // TODO add other shells, drop tmcli dependency, unhide?
// testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}), // TODO add
debug.Cmd(),
config.Cmd(),
)
ac := appCreator{
encodingConfig: encodingConfig,
}
server.AddCommands(rootCmd, defaultNodeHome, ac.newApp, ac.appExport, ac.addStartCmdFlags)
// add keybase, auxiliary RPC, query, and tx child commands
rootCmd.AddCommand(
StatusCommand(),
newQueryCmd(),
newTxCmd(),
keys.Commands(defaultNodeHome),
)
}

132
cmd/kava/cmd/status.go Normal file
View File

@ -0,0 +1,132 @@
package cmd
import (
"context"
"net/http"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/p2p"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/version"
)
// ValidatorInfo is info about the node's validator, same as Tendermint,
// except that we use our own PubKey.
type validatorInfo struct {
Address bytes.HexBytes `json:"address"`
PubKey cryptotypes.PubKey `json:"pub_key"`
VotingPower int64 `json:"voting_power"`
}
// ResultStatus is node's info, same as Tendermint, except that we use our own
// PubKey.
type resultStatus struct {
NodeInfo p2p.DefaultNodeInfo `json:"node_info"`
SyncInfo ctypes.SyncInfo `json:"sync_info"`
ValidatorInfo validatorInfo `json:"validator_info`
}
// StatusCommand returns the command to return the status of the network.
func StatusCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "status",
Short: "Query remote node for status",
RunE: func(cmd *cobra.Command, _ []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
status, err := getNodeStatus(clientCtx)
if err != nil {
return err
}
// `status` has TM pubkeys, we need to convert them to our pubkeys.
pk, err := cryptocodec.FromTmPubKeyInterface(status.ValidatorInfo.PubKey)
if err != nil {
return err
}
statusWithPk := resultStatus{
NodeInfo: status.NodeInfo,
SyncInfo: status.SyncInfo,
ValidatorInfo: validatorInfo{
Address: status.ValidatorInfo.Address,
PubKey: pk,
VotingPower: status.ValidatorInfo.VotingPower,
},
}
output, err := clientCtx.LegacyAmino.MarshalJSON(statusWithPk)
if err != nil {
return err
}
cmd.Println(string(output))
return nil
},
}
cmd.Flags().StringP(flags.FlagNode, "n", "tcp://localhost:26657", "Node to connect to")
return cmd
}
func getNodeStatus(clientCtx client.Context) (*ctypes.ResultStatus, error) {
node, err := clientCtx.GetNode()
if err != nil {
return &ctypes.ResultStatus{}, err
}
return node.Status(context.Background())
}
// NodeInfoResponse defines a response type that contains node status and version
// information.
type NodeInfoResponse struct {
p2p.DefaultNodeInfo `json:"node_info"`
ApplicationVersion version.Info `json:"application_version"`
}
// REST handler for node info
func NodeInfoRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
status, err := getNodeStatus(clientCtx)
if rest.CheckInternalServerError(w, err) {
return
}
resp := NodeInfoResponse{
DefaultNodeInfo: status.NodeInfo,
ApplicationVersion: version.NewInfo(),
}
rest.PostProcessResponseBare(w, clientCtx, resp)
}
}
// SyncingResponse defines a response type that contains node syncing information.
type SyncingResponse struct {
Syncing bool `json:"syncing"`
}
// REST handler for node syncing
func NodeSyncingRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
status, err := getNodeStatus(clientCtx)
if rest.CheckInternalServerError(w, err) {
return
}
rest.PostProcessResponseBare(w, clientCtx, SyncingResponse{Syncing: status.SyncInfo.CatchingUp})
}
}

37
cmd/kava/cmd/tx.go Normal file
View File

@ -0,0 +1,37 @@
package cmd
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
"github.com/spf13/cobra"
"github.com/kava-labs/kava/app"
)
// newTxCmd creates all commands for submitting blockchain transactions.
func newTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "tx",
Short: "Transactions subcommands",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
cmd.AddCommand(
authcmd.GetSignCommand(),
authcmd.GetSignBatchCommand(),
authcmd.GetMultiSignCommand(),
authcmd.GetMultiSignBatchCmd(),
authcmd.GetValidateSignaturesCommand(),
authcmd.GetBroadcastCommand(),
authcmd.GetEncodeCommand(),
authcmd.GetDecodeCommand(),
)
app.ModuleBasics.AddTxCommands(cmd)
cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID")
return cmd
}

25
cmd/kava/main.go Normal file
View File

@ -0,0 +1,25 @@
package main
import (
"os"
"github.com/cosmos/cosmos-sdk/server"
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/cmd/kava/cmd"
)
func main() {
rootCmd := cmd.NewRootCmd()
if err := svrcmd.Execute(rootCmd, app.DefaultNodeHome); err != nil {
switch e := err.(type) {
case server.ErrorCode:
os.Exit(e.Code)
default:
os.Exit(1)
}
}
}

View File

@ -1,112 +0,0 @@
package main
import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/app"
)
/*
NOTE TO FUTURE IMPLEMENTERS
This monkey patches the sdk `keys` command, therefore needs to be reviewed on any sdk updates.
The patch adds support for using kava's legacy bip44 coin type to the cli.
Coin types are used to create a bip44 derivation path, which is used as a mapping from mnemonic to private key.
In cosmos-sdk v0.38.3, all private keys are stored without reference to the mnemonic or bip44 derivation path, except ledger keys.
Ledger keys are just references to a private key on a ledger device. They contain the bip44 derivation path.
To patch the cli, we only need to modify:
- when new ledger references are created
- anything to do with converting a mnemonic to a private key.
These only happen in `kvcli keys add` cmd.
For private key generation, use a --legacy-hd-path flag to enable old coin type.
The current cosmos ledger app (v1.5.3) only supports the legacy coin type. So we only need to ensure ledger reference creation doesn't use the new coin type.
Signing txs:
- with local keys
- the stored the priv key is used to sign, mnemonics or bip44 paths not involved
- with ledger
- the stored bip44 path is used to instruct the ledger which key to sign with
*/
const flagLegacyHDPath = "legacy-hd-path"
const flagHDPath = "hd-path" // this is copied from keys add cmd because it's not exported
// getModifiedKeysCmd returns the standard cosmos-sdk/client/keys cmd but modified to support new and old bip44 coin types supported by kava.
func getModifiedKeysCmd() *cobra.Command {
keysCmd := keys.Commands()
for _, c := range keysCmd.Commands() {
if c.Name() == "add" {
monkeyPatchCmdKeysAdd(c)
}
if c.Name() == "parse" {
monkeyPatchCmdKeysParse(c)
}
}
return keysCmd
}
func monkeyPatchCmdKeysParse(keysParseCmd *cobra.Command) {
// replace the run function with a wrapped version that sets the old coin type in the global config
oldRun := keysParseCmd.RunE
keysParseCmd.RunE = func(cmd *cobra.Command, args []string) error {
sdk.GetConfig().Seal()
return oldRun(cmd, args)
}
}
// monkeyPatchCmdKeysAdd modifies the `keys add` command to use the old bip44 coin type when a flag is passed.
func monkeyPatchCmdKeysAdd(keysAddCmd *cobra.Command) {
// add flag
keysAddCmd.Flags().Bool(flagLegacyHDPath, false, fmt.Sprintf("Use the old bip44 coin type (%d) to derive addresses from mnemonics.", sdk.CoinType))
// replace description
keysAddCmd.Long = fmt.Sprintf(`Derive a new private key and encrypt to disk.
Optionally specify a BIP39 mnemonic, a BIP39 passphrase to further secure the mnemonic,
and BIP44 account/index numbers to derive a specific key. The key will be stored under the given name
and encrypted with the given password.
NOTE: This cli defaults to Kava's BIP44 coin type %d. Use the --%s flag to use the old one (%d).
The flag --recover allows one to recover a key from a seed passphrase.
If run with --dry-run, a key would be generated (or recovered) but not stored to the
local keystore.
Use the --pubkey flag to add arbitrary public keys to the keystore for constructing
multisig transactions.
You can add a multisig key by passing the list of key names you want the public
key to be composed of to the --multisig flag and the minimum number of signatures
required through --multisig-threshold. The keys are sorted by address, unless
the flag --nosort is set.
`, app.Bip44CoinType, flagLegacyHDPath, sdk.CoinType)
// replace the run function with a wrapped version that sets the old coin type in the global config
oldRun := keysAddCmd.RunE
keysAddCmd.RunE = func(cmd *cobra.Command, args []string) error {
if !viper.GetBool(flagLegacyHDPath) && viper.GetBool(flags.FlagUseLedger) {
return fmt.Errorf("cosmos ledger app only supports legacy bip44 coin type, must use --%s flag when adding ledger key", flagLegacyHDPath)
}
if viper.GetBool(flagLegacyHDPath) && viper.IsSet(flagHDPath) {
return fmt.Errorf("cannot use a custom hd path (--%s) and legacy bip44 coin type (--%s) at the same time", flagHDPath, flagLegacyHDPath)
}
if viper.GetBool(flagLegacyHDPath) {
preExistingCoinType := sdk.GetConfig().GetCoinType()
sdk.GetConfig().SetCoinType(sdk.CoinType) // set old coin type
err := oldRun(cmd, args)
sdk.GetConfig().SetCoinType(preExistingCoinType) // revert to pre-existing coin type
return err
}
return oldRun(cmd, args)
}
}

View File

@ -1,171 +0,0 @@
package main
import (
"fmt"
"os"
"path"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/lcd"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
"github.com/cosmos/cosmos-sdk/x/bank"
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/migrate/rest_v0_3"
)
func main() {
// Configure cobra to sort commands
cobra.EnableCommandSorting = false
// Instantiate the codec for the command line application
cdc := app.MakeCodec()
// Set the global config
// config is not sealed as the cli supports two coin types for legacy reasons.
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
app.SetBip44CoinType(config)
// TODO: setup keybase, viper object, etc. to be passed into
// the below functions and eliminate global vars, like we do
// with the cdc
rootCmd := &cobra.Command{
Use: "kvcli",
Short: "Command line interface for interacting with kvd",
}
// Add --chain-id to persistent flags and mark it required
rootCmd.PersistentFlags().String(flags.FlagChainID, "", "Chain ID of tendermint node")
rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error {
return initConfig(rootCmd)
}
// Construct Root Command
rootCmd.AddCommand(
rpc.StatusCommand(),
client.ConfigCmd(app.DefaultCLIHome),
queryCmd(cdc),
txCmd(cdc),
flags.LineBreak,
lcd.ServeCommand(cdc, registerRoutes),
flags.LineBreak,
getModifiedKeysCmd(),
flags.LineBreak,
version.Cmd,
flags.NewCompletionCmd(rootCmd, true),
)
// Add flags and prefix all env exposed with KA
executor := cli.PrepareMainCmd(rootCmd, "KA", app.DefaultCLIHome)
err := executor.Execute()
if err != nil {
fmt.Printf("Failed executing CLI command: %s, exiting...\n", err)
os.Exit(1)
}
}
func queryCmd(cdc *codec.Codec) *cobra.Command {
queryCmd := &cobra.Command{
Use: "query",
Aliases: []string{"q"},
Short: "Querying subcommands",
}
queryCmd.AddCommand(
authcmd.GetAccountCmd(cdc),
flags.LineBreak,
rpc.ValidatorCommand(cdc),
rpc.BlockCommand(),
authcmd.QueryTxsByEventsCmd(cdc),
authcmd.QueryTxCmd(cdc),
flags.LineBreak,
)
// add modules' query commands
app.ModuleBasics.AddQueryCommands(queryCmd, cdc)
return queryCmd
}
func txCmd(cdc *codec.Codec) *cobra.Command {
txCmd := &cobra.Command{
Use: "tx",
Short: "Transactions subcommands",
}
txCmd.AddCommand(
bankcmd.SendTxCmd(cdc),
flags.LineBreak,
authcmd.GetSignCommand(cdc),
authcmd.GetMultiSignCommand(cdc),
flags.LineBreak,
authcmd.GetBroadcastCommand(cdc),
authcmd.GetEncodeCommand(cdc),
authcmd.GetDecodeCommand(cdc),
flags.LineBreak,
)
// add modules' tx commands
app.ModuleBasics.AddTxCommands(txCmd, cdc)
// remove auth and bank commands as they're mounted under the root tx command
var cmdsToRemove []*cobra.Command
for _, cmd := range txCmd.Commands() {
if cmd.Use == auth.ModuleName || cmd.Use == bank.ModuleName {
cmdsToRemove = append(cmdsToRemove, cmd)
}
}
txCmd.RemoveCommand(cmdsToRemove...)
return txCmd
}
// registerRoutes registers the routes from the different modules for the LCD.
func registerRoutes(rs *lcd.RestServer) {
client.RegisterRoutes(rs.CliCtx, rs.Mux)
authrest.RegisterTxRoutes(rs.CliCtx, rs.Mux)
app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux)
app.RegisterSimulateRoutes(rs.CliCtx, rs.Mux)
// register legacy endpoints compatible with v0.3.x of kava
rest_v0_3.RegisterRoutes(rs.CliCtx, rs.Mux)
}
// initConfig reads in and sets options from a config file (if one exists)
func initConfig(cmd *cobra.Command) error {
home, err := cmd.PersistentFlags().GetString(cli.HomeFlag)
if err != nil {
return err
}
cfgFile := path.Join(home, "config", "config.toml")
if _, err := os.Stat(cfgFile); err == nil {
viper.SetConfigFile(cfgFile)
if err := viper.ReadInConfig(); err != nil {
return err
}
}
if err := viper.BindPFlag(flags.FlagChainID, cmd.PersistentFlags().Lookup(flags.FlagChainID)); err != nil {
return err
}
if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil {
return err
}
return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag))
}

View File

@ -1,234 +0,0 @@
package main
import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/genutil"
validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
)
const (
flagClientHome = "home-client"
flagVestingStart = "vesting-start-time"
flagVestingEnd = "vesting-end-time"
flagVestingAmt = "vesting-amount"
flagVestingPeriodsFile = "vesting-periods-file"
flagValidatorVestingFile = "validator-vesting-file"
)
// AddGenesisAccountCmd returns an add-genesis-account cobra Command.
func AddGenesisAccountCmd(
ctx *server.Context, cdc *codec.Codec, defaultNodeHome, defaultClientHome string,
) *cobra.Command {
cmd := &cobra.Command{
Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]",
Short: "Add a genesis account to genesis.json",
Long: strings.TrimSpace(
fmt.Sprintf(`Add a genesis account to genesis.json. The provided account must specify
the account address or key name and a list of initial coins. If a key name is given,
the address will be looked up in the local Keybase. The list of initial tokens must
contain valid denominations. Accounts may optionally be supplied with vesting parameters.
If the account is a periodic or validator vesting account, vesting periods must be supplied
via a JSON file using the 'vesting-periods-file' flag or 'validator-vesting-file' flag,
respectively.
Example:
%s add-genesis-account <account-name> <amount> --vesting-amount <amount> --vesting-end-time <unix-timestamp> --vesting-start-time <unix-timestamp> --vesting-periods <path/to/vesting.json>`, version.ClientName),
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(cli.HomeFlag))
addr, err := sdk.AccAddressFromBech32(args[0])
inBuf := bufio.NewReader(cmd.InOrStdin())
if err != nil {
// attempt to lookup address from Keybase if no address was provided
kb, err := keys.NewKeyring(
sdk.KeyringServiceName(),
viper.GetString(flags.FlagKeyringBackend),
viper.GetString(flagClientHome),
inBuf,
)
if err != nil {
return err
}
info, err := kb.Get(args[0])
if err != nil {
return fmt.Errorf("failed to get address from Keybase: %w", err)
}
addr = info.GetAddress()
}
coins, err := sdk.ParseCoins(args[1])
if err != nil {
return fmt.Errorf("failed to parse coins: %w", err)
}
vestingStart := viper.GetInt64(flagVestingStart)
vestingEnd := viper.GetInt64(flagVestingEnd)
vestingAmt, err := sdk.ParseCoins(viper.GetString(flagVestingAmt))
if err != nil {
return fmt.Errorf("failed to parse vesting amount: %w", err)
}
vestingPeriodsFile := viper.GetString(flagVestingPeriodsFile)
validatorVestingFile := viper.GetString(flagValidatorVestingFile)
if vestingPeriodsFile != "" && validatorVestingFile != "" {
return errors.New("Cannot specify both vesting-periods-file and validator-vesting-file")
}
// create concrete account type based on input parameters
var genAccount authexported.GenesisAccount
baseAccount := auth.NewBaseAccount(addr, coins.Sort(), nil, 0, 0)
if !vestingAmt.IsZero() {
baseVestingAccount, err := vesting.NewBaseVestingAccount(
baseAccount, vestingAmt.Sort(), vestingEnd,
)
if err != nil {
return fmt.Errorf("Failed to create base vesting account: %w", err)
}
switch {
case vestingPeriodsFile != "":
vestingPeriodsJSON, err := ParsePeriodicVestingJSON(cdc, vestingPeriodsFile)
if err != nil {
return fmt.Errorf("failed to parse periodic vesting account json file: %w", err)
}
genAccount = vesting.NewPeriodicVestingAccountRaw(baseVestingAccount, vestingStart, vestingPeriodsJSON.Periods)
case validatorVestingFile != "":
validatorVestingJSON, err := ParseValidatorVestingJSON(cdc, validatorVestingFile)
if err != nil {
return fmt.Errorf("failed to parse validator vesting account json file: %w", err)
}
consAddr, err := sdk.ConsAddressFromHex(validatorVestingJSON.ValidatorAddress)
if err != nil {
return fmt.Errorf("failed to convert validator address to bytes: %w", err)
}
genAccount = validatorvesting.NewValidatorVestingAccountRaw(baseVestingAccount, vestingStart, validatorVestingJSON.Periods, consAddr, validatorVestingJSON.ReturnAddress, validatorVestingJSON.SigningThreshold)
case vestingStart != 0 && vestingEnd != 0:
genAccount = vesting.NewContinuousVestingAccountRaw(baseVestingAccount, vestingStart)
case vestingEnd != 0:
genAccount = vesting.NewDelayedVestingAccountRaw(baseVestingAccount)
default:
return errors.New("invalid vesting parameters; must supply start and end time or end time")
}
} else {
genAccount = baseAccount
}
if err := genAccount.Validate(); err != nil {
return fmt.Errorf("failed to validate new genesis account: %w", err)
}
genFile := config.GenesisFile()
appState, genDoc, err := genutil.GenesisStateFromGenFile(cdc, genFile)
if err != nil {
return fmt.Errorf("failed to unmarshal genesis state: %w", err)
}
authGenState := auth.GetGenesisStateFromAppState(cdc, appState)
if authGenState.Accounts.Contains(addr) {
return fmt.Errorf("cannot add account at existing address %s", addr)
}
// Add the new account to the set of genesis accounts and sanitize the
// accounts afterwards.
authGenState.Accounts = append(authGenState.Accounts, genAccount)
authGenState.Accounts = auth.SanitizeGenesisAccounts(authGenState.Accounts)
authGenStateBz, err := cdc.MarshalJSON(authGenState)
if err != nil {
return fmt.Errorf("failed to marshal auth genesis state: %w", err)
}
appState[auth.ModuleName] = authGenStateBz
appStateJSON, err := cdc.MarshalJSON(appState)
if err != nil {
return fmt.Errorf("failed to marshal application genesis state: %w", err)
}
genDoc.AppState = appStateJSON
return genutil.ExportGenesisFile(genDoc, genFile)
},
}
cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
cmd.Flags().String(flagClientHome, defaultClientHome, "client's home directory")
cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts")
cmd.Flags().Uint64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
cmd.Flags().Uint64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
cmd.Flags().String(flagVestingPeriodsFile, "", "path to file where periodic vesting schedule is specified")
cmd.Flags().String(flagValidatorVestingFile, "", "path to file where validator vesting schedule is specified")
return cmd
}
// ValidatorVestingJSON input json for validator-vesting-file flag
type ValidatorVestingJSON struct {
Periods vesting.Periods `json:"periods" yaml:"periods"`
ValidatorAddress string `json:"validator_address" yaml:"validator_address"`
SigningThreshold int64 `json:"signing_threshold" yaml:"signing_threshold"`
ReturnAddress sdk.AccAddress `json:"return_address,omitempty" yaml:"return_address,omitempty"`
}
// PeriodicVestingJSON input json for vesting-periods-file flag
type PeriodicVestingJSON struct {
Periods vesting.Periods `json:"periods" yaml:"periods"`
}
// ParsePeriodicVestingJSON reads and parses ParsePeriodicVestingJSON from the file
func ParsePeriodicVestingJSON(cdc *codec.Codec, inputFile string) (PeriodicVestingJSON, error) {
periodsInput := PeriodicVestingJSON{}
content, err := ioutil.ReadFile(inputFile)
if err != nil {
return periodsInput, err
}
if err := cdc.UnmarshalJSON(content, &periodsInput); err != nil {
return periodsInput, err
}
return periodsInput, nil
}
// ParseValidatorVestingJSON reads and parses ParseValidatorVestingJSON from the file
func ParseValidatorVestingJSON(cdc *codec.Codec, inputFile string) (ValidatorVestingJSON, error) {
validatorVestingInput := ValidatorVestingJSON{}
content, err := ioutil.ReadFile(inputFile)
if err != nil {
return validatorVestingInput, err
}
if err := cdc.UnmarshalJSON(content, &validatorVestingInput); err != nil {
return validatorVestingInput, err
}
return validatorVestingInput, nil
}

View File

@ -1,177 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"io"
"github.com/spf13/cobra"
"github.com/spf13/viper"
dbm "github.com/tendermint/tm-db"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/migrate"
)
// kvd custom flags
const (
flagInvCheckPeriod = "inv-check-period"
flagMempoolEnableAuth = "mempool.enable-authentication"
flagMempoolAuthAddresses = "mempool.authorized-addresses"
)
var invCheckPeriod uint
func main() {
cdc := app.MakeCodec()
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
app.SetBip44CoinType(config)
config.Seal()
ctx := server.NewDefaultContext()
cobra.EnableCommandSorting = false
rootCmd := &cobra.Command{
Use: "kvd",
Short: "Kava Daemon (server)",
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
}
rootCmd.AddCommand(
genutilcli.InitCmd(ctx, cdc, app.ModuleBasics, app.DefaultNodeHome),
genutilcli.CollectGenTxsCmd(ctx, cdc, auth.GenesisAccountIterator{}, app.DefaultNodeHome),
migrate.MigrateGenesisCmd(ctx, cdc),
migrate.AssertInvariantsCmd(ctx, cdc),
genutilcli.GenTxCmd(
ctx,
cdc,
app.ModuleBasics,
staking.AppModuleBasic{},
auth.GenesisAccountIterator{},
app.DefaultNodeHome,
app.DefaultCLIHome),
genutilcli.ValidateGenesisCmd(ctx, cdc, app.ModuleBasics),
AddGenesisAccountCmd(ctx, cdc, app.DefaultNodeHome, app.DefaultCLIHome),
testnetCmd(ctx, cdc, app.ModuleBasics, auth.GenesisAccountIterator{}),
flags.NewCompletionCmd(rootCmd, true),
)
server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)
// prepare and add flags
executor := cli.PrepareBaseCmd(rootCmd, "KA", app.DefaultNodeHome)
rootCmd.PersistentFlags().UintVar(&invCheckPeriod, flagInvCheckPeriod,
0, "Assert registered invariants every N blocks")
startCmd, _, err := rootCmd.Find([]string{"start"})
if err != nil {
panic(fmt.Sprintf("could not find 'start' command on root command: %s", err))
}
startCmd.Flags().Bool(flagMempoolEnableAuth, false, "Configure the mempool to only accept transactions from authorized addresses")
err = viper.BindPFlag(flagMempoolEnableAuth, startCmd.Flags().Lookup(flagMempoolEnableAuth))
if err != nil {
panic(fmt.Sprintf("failed to bind flag: %s", err))
}
startCmd.Flags().StringSlice(flagMempoolAuthAddresses, []string{}, "Additional addresses to accept transactions from when the mempool is running in authorized mode (comma separated kava addresses)")
err = viper.BindPFlag(flagMempoolAuthAddresses, startCmd.Flags().Lookup(flagMempoolAuthAddresses))
if err != nil {
panic(fmt.Sprintf("failed to bind flag: %s", err))
}
// run main command
err = executor.Execute()
if err != nil {
panic(err)
}
}
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application {
var cache sdk.MultiStorePersistentCache
if viper.GetBool(server.FlagInterBlockCache) {
cache = store.NewCommitKVStoreCacheManager()
}
skipUpgradeHeights := make(map[int64]bool)
for _, h := range viper.GetIntSlice(server.FlagUnsafeSkipUpgrades) {
skipUpgradeHeights[int64(h)] = true
}
pruningOpts, err := server.GetPruningOptionsFromFlags()
if err != nil {
panic(err)
}
mempoolEnableAuth := viper.GetBool(flagMempoolEnableAuth)
mempoolAuthAddresses, err := accAddressesFromBech32(viper.GetStringSlice(flagMempoolAuthAddresses)...)
if err != nil {
panic(fmt.Sprintf("could not get authorized address from config: %v", err))
}
return app.NewApp(
logger, db, traceStore,
app.AppOptions{
SkipLoadLatest: false,
SkipUpgradeHeights: skipUpgradeHeights,
InvariantCheckPeriod: invCheckPeriod,
MempoolEnableAuth: mempoolEnableAuth,
MempoolAuthAddresses: mempoolAuthAddresses,
},
baseapp.SetPruning(pruningOpts),
baseapp.SetMinGasPrices(viper.GetString(server.FlagMinGasPrices)),
baseapp.SetHaltHeight(viper.GetUint64(server.FlagHaltHeight)),
baseapp.SetHaltTime(viper.GetUint64(server.FlagHaltTime)),
baseapp.SetInterBlockCache(cache),
)
}
func exportAppStateAndTMValidators(
logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailWhiteList []string,
) (json.RawMessage, []tmtypes.GenesisValidator, error) {
if height != -1 {
opts := app.AppOptions{
SkipLoadLatest: true,
InvariantCheckPeriod: uint(1),
}
tempApp := app.NewApp(logger, db, traceStore, opts)
err := tempApp.LoadHeight(height)
if err != nil {
return nil, nil, err
}
return tempApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
}
opts := app.AppOptions{
SkipLoadLatest: false,
InvariantCheckPeriod: uint(1),
}
tempApp := app.NewApp(logger, db, traceStore, opts)
return tempApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
}
func accAddressesFromBech32(addresses ...string) ([]sdk.AccAddress, error) {
var decodedAddresses []sdk.AccAddress
for _, s := range addresses {
a, err := sdk.AccAddressFromBech32(s)
if err != nil {
return nil, err
}
decodedAddresses = append(decodedAddresses, a)
}
return decodedAddresses, nil
}

View File

@ -1,376 +0,0 @@
package main
// DONTCOVER
import (
"bufio"
"encoding/json"
"fmt"
"net"
"os"
"path/filepath"
"github.com/cosmos/cosmos-sdk/client/flags"
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"
srvconfig "github.com/cosmos/cosmos-sdk/server/config"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/spf13/cobra"
"github.com/spf13/viper"
tmconfig "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
tmos "github.com/tendermint/tendermint/libs/os"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
)
var (
flagNodeDirPrefix = "node-dir-prefix"
flagNumValidators = "v"
flagOutputDir = "output-dir"
flagNodeDaemonHome = "node-daemon-home"
flagNodeCLIHome = "node-cli-home"
flagStartingIPAddress = "starting-ip-address"
)
func testnetCmd(
ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, genAccIterator genutiltypes.GenesisAccountsIterator,
) *cobra.Command {
cmd := &cobra.Command{
Use: "testnet",
Short: "Initialize files for a local kava testnet",
Long: `testnet will create "v" number of directories and populate each with
necessary files (private validator, genesis, config, etc.).
Note, strict routability for addresses is turned off in the config file.
Example:
$ kvd testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2
`,
RunE: func(cmd *cobra.Command, _ []string) error {
config := ctx.Config
outputDir := viper.GetString(flagOutputDir)
chainID := viper.GetString(flags.FlagChainID)
minGasPrices := viper.GetString(server.FlagMinGasPrices)
nodeDirPrefix := viper.GetString(flagNodeDirPrefix)
nodeDaemonHome := viper.GetString(flagNodeDaemonHome)
nodeCLIHome := viper.GetString(flagNodeCLIHome)
startingIPAddress := viper.GetString(flagStartingIPAddress)
numValidators := viper.GetInt(flagNumValidators)
return InitTestnet(
cmd, config, cdc, mbm, genAccIterator, outputDir, chainID,
minGasPrices, nodeDirPrefix, nodeDaemonHome, nodeCLIHome, startingIPAddress, numValidators,
)
},
}
cmd.Flags().Int(flagNumValidators, 4,
"Number of validators to initialize the testnet with")
cmd.Flags().StringP(flagOutputDir, "o", "./kavatestnet",
"Directory to store initialization data for the testnet")
cmd.Flags().String(flagNodeDirPrefix, "node",
"Prefix the directory name for each node with (node results in node0, node1, ...)")
cmd.Flags().String(flagNodeDaemonHome, "kvd",
"Home directory of the node's daemon configuration")
cmd.Flags().String(flagNodeCLIHome, "kvcli",
"Home directory of the node's cli configuration")
cmd.Flags().String(flagStartingIPAddress, "192.168.0.1",
"Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
cmd.Flags().String(
flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(
server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom),
"Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
return cmd
}
const nodeDirPerm = 0755
// Initialize the testnet
func InitTestnet(
cmd *cobra.Command, config *tmconfig.Config, cdc *codec.Codec,
mbm module.BasicManager, genAccIterator genutiltypes.GenesisAccountsIterator,
outputDir, chainID, minGasPrices, nodeDirPrefix, nodeDaemonHome,
nodeCLIHome, startingIPAddress string, numValidators int,
) error {
if chainID == "" {
chainID = "chain-" + tmrand.NewRand().Str(6)
}
monikers := make([]string, numValidators)
nodeIDs := make([]string, numValidators)
valPubKeys := make([]crypto.PubKey, numValidators)
kavaConfig := srvconfig.DefaultConfig()
kavaConfig.MinGasPrices = minGasPrices
//nolint:prealloc
var (
genAccounts []authexported.GenesisAccount
genFiles []string
)
inBuf := bufio.NewReader(cmd.InOrStdin())
// generate private keys, node IDs, and initial transactions
for i := 0; i < numValidators; i++ {
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)
clientDir := filepath.Join(outputDir, nodeDirName, nodeCLIHome)
gentxsDir := filepath.Join(outputDir, "gentxs")
config.SetRoot(nodeDir)
config.RPC.ListenAddress = "tcp://0.0.0.0:26657"
if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil {
_ = os.RemoveAll(outputDir)
return err
}
if err := os.MkdirAll(clientDir, nodeDirPerm); err != nil {
_ = os.RemoveAll(outputDir)
return err
}
monikers = append(monikers, nodeDirName)
config.Moniker = nodeDirName
ip, err := getIP(i, startingIPAddress)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}
nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(config)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
genFiles = append(genFiles, config.GenesisFile())
kb, err := keys.NewKeyring(
sdk.KeyringServiceName(),
viper.GetString(flags.FlagKeyringBackend),
clientDir,
inBuf,
)
keyPass := clientkeys.DefaultKeyPass
addr, secret, err := server.GenerateSaveCoinKey(kb, nodeDirName, keyPass, true)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}
info := map[string]string{"secret": secret}
cliPrint, err := json.Marshal(info)
if err != nil {
return err
}
// save private key seed words
if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), clientDir, cliPrint); err != nil {
return err
}
accTokens := sdk.TokensFromConsensusPower(1000)
accStakingTokens := sdk.TokensFromConsensusPower(500)
coins := sdk.Coins{
sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), accTokens),
sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens),
}
genAccounts = append(genAccounts, auth.NewBaseAccount(addr, coins.Sort(), nil, 0, 0))
valTokens := sdk.TokensFromConsensusPower(100)
msg := staking.NewMsgCreateValidator(
sdk.ValAddress(addr),
valPubKeys[i],
sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
staking.NewDescription(nodeDirName, "", "", "", ""),
staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
sdk.OneInt(),
)
tx := auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{}, memo)
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithChainID(chainID).WithMemo(memo).WithKeybase(kb)
signedTx, err := txBldr.SignStdTx(nodeDirName, clientkeys.DefaultKeyPass, tx, false)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}
txBytes, err := cdc.MarshalJSON(signedTx)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}
// gather gentxs folder
if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBytes); err != nil {
_ = os.RemoveAll(outputDir)
return err
}
appConfigFilePath := filepath.Join(nodeDir, "config/app.toml")
srvconfig.WriteConfigFile(appConfigFilePath, kavaConfig)
}
if err := initGenFiles(cdc, mbm, chainID, genAccounts, genFiles, numValidators); err != nil {
return err
}
err := collectGenFiles(
cdc, config, chainID, monikers, nodeIDs, valPubKeys, numValidators,
outputDir, nodeDirPrefix, nodeDaemonHome, genAccIterator,
)
if err != nil {
return err
}
cmd.PrintErrf("Successfully initialized %d node directories\n", numValidators)
return nil
}
func initGenFiles(
cdc *codec.Codec, mbm module.BasicManager, chainID string,
genAccounts []authexported.GenesisAccount, genFiles []string, numValidators int,
) error {
appGenState := mbm.DefaultGenesis()
// set the accounts in the genesis state
authDataBz := appGenState[auth.ModuleName]
var authGenState auth.GenesisState
cdc.MustUnmarshalJSON(authDataBz, &authGenState)
authGenState.Accounts = genAccounts
appGenState[auth.ModuleName] = cdc.MustMarshalJSON(authGenState)
appGenStateJSON, err := codec.MarshalJSONIndent(cdc, appGenState)
if err != nil {
return err
}
genDoc := types.GenesisDoc{
ChainID: chainID,
AppState: appGenStateJSON,
Validators: nil,
}
// generate empty genesis files for each validator and save
for i := 0; i < numValidators; i++ {
if err := genDoc.SaveAs(genFiles[i]); err != nil {
return err
}
}
return nil
}
func collectGenFiles(
cdc *codec.Codec, config *tmconfig.Config, chainID string,
monikers, nodeIDs []string, valPubKeys []crypto.PubKey,
numValidators int, outputDir, nodeDirPrefix, nodeDaemonHome string,
genAccIterator genutiltypes.GenesisAccountsIterator,
) error {
var appState json.RawMessage
genTime := tmtime.Now()
for i := 0; i < numValidators; i++ {
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)
gentxsDir := filepath.Join(outputDir, "gentxs")
moniker := monikers[i]
config.Moniker = nodeDirName
config.SetRoot(nodeDir)
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
initCfg := genutil.NewInitConfig(chainID, gentxsDir, moniker, nodeID, valPubKey)
genDoc, err := types.GenesisDocFromFile(config.GenesisFile())
if err != nil {
return err
}
nodeAppState, err := genutil.GenAppStateFromConfig(cdc, config, initCfg, *genDoc, genAccIterator)
if err != nil {
return err
}
if appState == nil {
// set the canonical application state (they should not differ)
appState = nodeAppState
}
genFile := config.GenesisFile()
// overwrite each validator's genesis file to have a canonical genesis time
if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil {
return err
}
}
return nil
}
func getIP(i int, startingIPAddr string) (ip string, err error) {
if len(startingIPAddr) == 0 {
ip, err = server.ExternalIP()
if err != nil {
return "", err
}
return ip, nil
}
return calculateIP(startingIPAddr, i)
}
func calculateIP(ip string, i int) (string, error) {
ipv4 := net.ParseIP(ip).To4()
if ipv4 == nil {
return "", fmt.Errorf("%v: non ipv4 address", ip)
}
for j := 0; j < i; j++ {
ipv4[3]++
}
return ipv4.String(), nil
}
func writeFile(name string, dir string, contents []byte) error {
writePath := filepath.Join(dir)
file := filepath.Join(writePath, name)
err := tmos.EnsureDir(writePath, 0700)
if err != nil {
return err
}
err = tmos.WriteFile(file, contents, 0600)
if err != nil {
return err
}
return nil
}

View File

@ -1,427 +0,0 @@
{
"genesis_time": "2020-04-23T16:32:31.393515Z",
"chain_id": "testing",
"consensus_params": {
"block": {
"max_bytes": "22020096",
"max_gas": "-1",
"time_iota_ms": "1000"
},
"evidence": {
"max_age_num_blocks": "100000",
"max_age_duration": "172800000000000"
},
"validator": {
"pub_key_types": [
"ed25519"
]
}
},
"app_hash": "",
"app_state": {
"auction": {
"auctions": [],
"next_auction_id": "1",
"params": {
"bid_duration": "600000000000",
"increment_collateral": "0.010000000000000000",
"increment_debt": "0.010000000000000000",
"increment_surplus": "0.010000000000000000",
"max_auction_duration": "172800000000000"
}
},
"auth": {
"accounts": [],
"params": {
"max_memo_characters": "256",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
}
},
"bank": {
"send_enabled": true
},
"bep3": {
"assets_supplies": [],
"atomic_swaps": [],
"params": {
"bnb_deputy_address": "kava1r4v2zdhdalfj2ydazallqvrus9fkphmglhn6u6",
"bnb_deputy_fixed_fee": "1000",
"min_amount": "0",
"max_amount": "1000000000000",
"min_block_lock": "220",
"max_block_lock": "270",
"supported_assets": [
{
"active": true,
"coin_id": "714",
"denom": "bnb",
"limit": "350000000000000"
}
]
}
},
"cdp": {
"cdps": [],
"debt_denom": "debt",
"deposits": [],
"gov_denom": "ukava",
"params": {
"circuit_breaker": false,
"collateral_params": [
{
"auction_size": "50000000000",
"conversion_factor": "8",
"debt_limit": {
"amount": "2000000000000",
"denom": "usdx"
},
"denom": "bnb",
"liquidation_penalty": "0.05",
"liquidation_ratio": "1.5",
"spot_market_id": "bnb:usd",
"liquidation_market_id": "bnb:usd:30",
"prefix": 1,
"stability_fee": "1.0000000007829977"
}
],
"debt_auction_threshold": "10000000000",
"debt_auction_lot": "10000000000",
"debt_param": {
"conversion_factor": "6",
"debt_floor": "10000000",
"debt_limit": [
{
"amount": "2000000000000",
"denom": "usdx"
}
],
"denom": "usdx",
"reference_asset": "usd",
"savings_rate": "0.95"
},
"global_debt_limit": {
"amount": "2000000000000",
"denom": "usdx"
},
"savings_distribution_frequency": "120000000000",
"surplus_auction_threshold": "1000000000",
"surplus_auction_lot": "10000000000"
},
"previous_block_time": "1970-01-01T00:00:00Z",
"previous_distribution_time": "1970-01-01T00:00:00Z",
"starting_cdp_id": "1"
},
"committee": {
"next_proposal_id": "1",
"committees": [
{
"id": "0",
"description": "This committee is for adjusting parameters of the cdp system.",
"members": [
"kava109fpwjvq6un86tw8f8emav2l0e0dha924scrj9"
],
"permissions": [
{
"type": "kava/SubParamChangePermission",
"value": {
"allowed_params": [
{
"subspace": "cdp",
"key": "GlobalDebtLimit"
},
{
"subspace": "cdp",
"key": "SurplusThreshold"
},
{
"subspace": "cdp",
"key": "DebtThreshold"
},
{
"subspace": "cdp",
"key": "DistributionFrequency"
},
{
"subspace": "cdp",
"key": "CircuitBreaker"
},
{
"subspace": "cdp",
"key": "CollateralParams"
},
{
"subspace": "cdp",
"key": "DebtParam"
},
{
"subspace": "auction",
"key": "BidDuration"
},
{
"subspace": "auction",
"key": "IncrementSurplus"
},
{
"subspace": "auction",
"key": "IncrementDebt"
},
{
"subspace": "auction",
"key": "IncrementCollateral"
},
{
"subspace": "bep3",
"key": "BnbDeputyAddress"
},
{
"subspace": "bep3",
"key": "BnbDeputyFixedFee"
},
{
"subspace": "bep3",
"key": "MinAmount"
},
{
"subspace": "bep3",
"key": "MaxAmount"
},
{
"subspace": "bep3",
"key": "SupportedAssets"
},
{
"subspace": "pricefeed",
"key": "Markets"
},
{
"subspace": "incentive",
"key": "Active"
},
{
"subspace": "kavadist",
"key": "Active"
}
],
"allowed_collateral_params": [
{
"denom": "bnb",
"liquidation_ratio": false,
"debt_limit": true,
"stability_fee": true,
"auction_size": true,
"liquidation_penalty": false,
"prefix": false,
"market_id": false,
"conversion_factor": false
}
],
"allowed_debt_param": {
"denom": false,
"reference_asset": false,
"conversion_factor": false,
"debt_floor": false,
"savings_rate": true
},
"allowed_asset_params": [
{
"denom": "bnb",
"coin_id": false,
"limit": true,
"active": true
}
],
"allowed_markets": [
{
"market_id": "bnb:usd",
"base_asset": false,
"quote_asset": false,
"oracles": false,
"active": true
}
]
}
}
],
"vote_threshold": "0.750000000000000000",
"proposal_duration": "604800000000000"
}
],
"proposals": [],
"votes": []
},
"crisis": {
"constant_fee": {
"amount": "1333000000",
"denom": "ukava"
}
},
"distribution": {
"delegator_starting_infos": [],
"delegator_withdraw_infos": [],
"fee_pool": {
"community_pool": []
},
"outstanding_rewards": [],
"params": {
"base_proposer_reward": "0.010000000000000000",
"bonus_proposer_reward": "0.040000000000000000",
"community_tax": "0.000000000000000000",
"withdraw_addr_enabled": true
},
"previous_proposer": "",
"validator_accumulated_commissions": [],
"validator_current_rewards": [],
"validator_historical_rewards": [],
"validator_slash_events": []
},
"evidence": {
"evidence": [],
"params": {
"max_evidence_age": "120000000000"
}
},
"genutil": {
"gentxs": []
},
"gov": {
"deposit_params": {
"max_deposit_period": "600000000000",
"min_deposit": [
{
"amount": "200000000",
"denom": "ukava"
}
]
},
"deposits": null,
"proposals": null,
"starting_proposal_id": "1",
"tally_params": {
"quorum": "0.334000000000000000",
"threshold": "0.500000000000000000",
"veto": "0.334000000000000000"
},
"votes": null,
"voting_params": {
"voting_period": "600000000000"
}
},
"incentive": {
"params": {
"active": true,
"rewards": [
{
"active": true,
"denom": "bnb",
"available_rewards": {
"amount": "50000000000",
"denom": "ukava"
},
"duration": "36288000000000000",
"time_lock": "1892160000000000000",
"claim_duration": "36288000000000000"
}
]
},
"previous_block_time": "1970-01-01T00:00:00Z"
},
"kavadist": {
"params": {
"active": true,
"periods": [
{
"end": "2021-03-28T15:20:00Z",
"inflation": "1.000000003022265980",
"start": "2020-03-28T15:20:00Z"
}
]
},
"previous_block_time": "1970-01-01T00:00:00Z"
},
"mint": {
"minter": {
"annual_provisions": "0.000000000000000000",
"inflation": "0.020000000000000000"
},
"params": {
"blocks_per_year": "6311520",
"goal_bonded": "0.670000000000000000",
"inflation_max": "0.130000000000000000",
"inflation_min": "0.010000000000000000",
"inflation_rate_change": "0.130000000000000000",
"mint_denom": "ukava"
}
},
"params": null,
"pricefeed": {
"params": {
"markets": [
{
"active": true,
"base_asset": "bnb",
"market_id": "bnb:usd",
"oracles": [
"kava1nyqy04x3ecpcuss3llmyu4fc2v4ma99h8vffjz",
"kava1znuktqgtjr8g85tetu2wt9wd33gstqr7pad92h"
],
"quote_asset": "usd"
},
{
"active": true,
"base_asset": "bnb",
"market_id": "bnb:usd:30",
"oracles": [
"kava1nyqy04x3ecpcuss3llmyu4fc2v4ma99h8vffjz",
"kava1znuktqgtjr8g85tetu2wt9wd33gstqr7pad92h"
],
"quote_asset": "usd"
}
]
},
"posted_prices": [
{
"expiry": "2021-06-20T00:00:00Z",
"market_id": "bnb:usd",
"oracle_address": "kava1znuktqgtjr8g85tetu2wt9wd33gstqr7pad92h",
"price": "15.929061184"
}
]
},
"slashing": {
"missed_blocks": {},
"params": {
"downtime_jail_duration": "600000000000",
"min_signed_per_window": "0.010000000000000000",
"signed_blocks_window": "1000",
"slash_fraction_double_sign": "0.050000000000000000",
"slash_fraction_downtime": "0.000100000000000000"
},
"signing_infos": {}
},
"staking": {
"delegations": null,
"exported": false,
"last_total_power": "0",
"last_validator_powers": null,
"params": {
"bond_denom": "ukava",
"historical_entries": 0,
"max_entries": 7,
"max_validators": 100,
"unbonding_time": "3600000000000"
},
"redelegations": null,
"unbonding_delegations": null,
"validators": null
},
"supply": {
"supply": []
},
"validatorvesting": {
"previous_block_time": "1970-01-01T00:00:00Z"
}
}
}

View File

@ -1,352 +0,0 @@
{
"genesis_time": "2020-03-07T18:27:07.837213082Z",
"chain_id": "testing",
"consensus_params": {
"block": {
"max_bytes": "22020096",
"max_gas": "-1",
"time_iota_ms": "1000"
},
"evidence": {
"max_age": "100000"
},
"validator": {
"pub_key_types": [
"ed25519"
]
}
},
"app_hash": "",
"app_state": {
"cdp": {
"cdps": [],
"debt_denom": "debt",
"deposits": [],
"gov_denom": "ukava",
"previous_distribution_time": "1970-01-01T00:00:00Z",
"params": {
"circuit_breaker": false,
"collateral_params": [
{
"auction_size": "5000000000",
"conversion_factor": "6",
"debt_limit": [
{
"amount": "10000000",
"denom": "usdx"
}
],
"denom": "xrp",
"liquidation_penalty": "0.05",
"liquidation_ratio": "2.0",
"market_id": "xrp:usd",
"prefix": 0,
"stability_fee": "1.000000001547126"
},
{
"auction_size": "10000000",
"conversion_factor": "8",
"debt_limit": [
{
"amount": "10000000",
"denom": "usdx"
}
],
"denom": "btc",
"liquidation_penalty": "0.05",
"liquidation_ratio": "1.5",
"market_id": "btc:usd",
"prefix": 1,
"stability_fee": "1.0000000007829977"
}
],
"debt_auction_threshold": "1000000000",
"debt_params": [
{
"conversion_factor": "6",
"debt_floor": "10000000",
"debt_limit": [
{
"amount": "2000000000000",
"denom": "usdx"
}
],
"denom": "usdx",
"reference_asset": "usd",
"savings_rate": "0.95"
}
],
"global_debt_limit": [
{
"amount": "2000000000000",
"denom": "usdx"
}
],
"savings_distribution_frequency": "120000000000",
"surplus_auction_threshold": "1000000000"
},
"previous_block_time": "1970-01-01T00:00:00Z",
"starting_cdp_id": "1"
},
"bank": {
"send_enabled": true
},
"params": null,
"bep3": {
"params": {
"bnb_deputy_address": "kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj",
"min_block_lock": "80",
"max_block_lock": "600",
"supported_assets": [
{
"denom": "ukava",
"coin_id": "459",
"limit": "1",
"active": false
}
]
},
"atomic_swaps": [],
"assets_supplies": []
},
"pricefeed": {
"params": {
"markets": [
{
"active": true,
"base_asset": "xrp",
"market_id": "xrp:usd",
"oracles": [
"kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"kava1xq4cspcgl9thzmn6lkvd6dlx28wsr63zw4mlmf"
],
"quote_asset": "usd"
},
{
"active": true,
"base_asset": "btc",
"market_id": "btc:usd",
"oracles": [
"kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw"
],
"quote_asset": "usd"
}
]
},
"posted_prices": [
{
"expiry": "2050-01-01T00:00:00Z",
"market_id": "btc:usd",
"oracle_address": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"price": "8700.0"
},
{
"expiry": "2050-01-01T00:00:00Z",
"market_id": "xrp:usd",
"oracle_address": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"price": "0.25"
}
]
},
"gov": {
"starting_proposal_id": "1",
"deposits": null,
"votes": null,
"proposals": null,
"deposit_params": {
"min_deposit": [
{
"denom": "ukava",
"amount": "10000000"
}
],
"max_deposit_period": "172800000000000"
},
"voting_params": {
"voting_period": "172800000000000"
},
"tally_params": {
"quorum": "0.334000000000000000",
"threshold": "0.500000000000000000",
"veto": "0.334000000000000000"
}
},
"staking": {
"params": {
"unbonding_time": "1814400000000000",
"max_validators": 100,
"max_entries": 7,
"bond_denom": "ukava"
},
"last_total_power": "0",
"last_validator_powers": null,
"validators": null,
"delegations": null,
"unbonding_delegations": null,
"redelegations": null,
"exported": false
},
"mint": {
"minter": {
"inflation": "0.130000000000000000",
"annual_provisions": "0.000000000000000000"
},
"params": {
"mint_denom": "ukava",
"inflation_rate_change": "0.130000000000000000",
"inflation_max": "0.200000000000000000",
"inflation_min": "0.070000000000000000",
"goal_bonded": "0.670000000000000000",
"blocks_per_year": "6311520"
}
},
"auth": {
"params": {
"max_memo_characters": "256",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000"
},
"accounts": [
{
"type": "cosmos-sdk/Account",
"value": {
"address": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"coins": [
{
"denom": "ukava",
"amount": "1000000000000"
},
{
"denom": "btc",
"amount": "10000000000"
},
{
"denom": "xrp",
"amount": "1000000000000"
}
],
"public_key": null,
"account_number": "0",
"sequence": "0"
}
},
{
"type": "cosmos-sdk/Account",
"value": {
"address": "kava19dp7luf32mlqnw6mhpgk0g37ule7wm2g8gck8a",
"coins": [
{
"denom": "ukava",
"amount": "1000000000000"
}
],
"public_key": null,
"account_number": "0",
"sequence": "0"
}
}
]
},
"auction": {
"next_auction_id": "1",
"params": {
"max_auction_duration": "172800000000000",
"bid_duration": "3600000000000"
},
"auctions": []
},
"validatorvesting": {
"previous_block_time": "1970-01-01T00:00:00Z"
},
"supply": {
"supply": []
},
"crisis": {
"constant_fee": {
"denom": "ukava",
"amount": "1000"
}
},
"distribution": {
"fee_pool": {
"community_pool": []
},
"community_tax": "0.020000000000000000",
"base_proposer_reward": "0.010000000000000000",
"bonus_proposer_reward": "0.040000000000000000",
"withdraw_addr_enabled": true,
"delegator_withdraw_infos": [],
"previous_proposer": "",
"outstanding_rewards": [],
"validator_accumulated_commissions": [],
"validator_historical_rewards": [],
"validator_current_rewards": [],
"delegator_starting_infos": [],
"validator_slash_events": []
},
"genutil": {
"gentxs": [
{
"type": "cosmos-sdk/StdTx",
"value": {
"msg": [
{
"type": "cosmos-sdk/MsgCreateValidator",
"value": {
"description": {
"moniker": "kava-tester",
"identity": "",
"website": "",
"security_contact": "",
"details": ""
},
"commission": {
"rate": "0.100000000000000000",
"max_rate": "0.200000000000000000",
"max_change_rate": "0.010000000000000000"
},
"min_self_delegation": "1",
"delegator_address": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"validator_address": "kavavaloper15qdefkmwswysgg4qxgqpqr35k3m49pkx8yhpte",
"pubkey": "kavavalconspub1zcjduepq3qyhcxfpa0u2efeu3htuxjz0248khl2cqfcm8jz2n0dr2e2a6tuqqafg2g",
"value": {
"denom": "ukava",
"amount": "10000000000"
}
}
}
],
"fee": {
"amount": [],
"gas": "200000"
},
"signatures": [
{
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "Az740XKIPCJtnZLmJfktTfhsEStEJE3n2iRVyJ3wko43"
},
"signature": "ZIzw2qsaJzsNuROW1JYYH1ZOA3jrc4ZCHvrCxirWNlEZqIvnyC42nBQLIPQ+d+PIcpldLVy0KAkb8NBXj9G0nQ=="
}
],
"memo": "6fff8e9b327f0811e7a25c1419781167f82ec7b3@172.31.40.66:26656"
}
}
]
},
"slashing": {
"params": {
"max_evidence_age": "120000000000",
"signed_blocks_window": "100",
"min_signed_per_window": "0.500000000000000000",
"downtime_jail_duration": "600000000000",
"slash_fraction_double_sign": "0.050000000000000000",
"slash_fraction_downtime": "0.010000000000000000"
},
"signing_infos": {},
"missed_blocks": {}
}
}
}

View File

@ -0,0 +1,46 @@
#! /bin/bash
set -e
validatorMnemonic="equip town gesture square tomorrow volume nephew minute witness beef rich gadget actress egg sing secret pole winter alarm law today check violin uncover"
# kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
faucetMnemonic="crash sort dwarf disease change advice attract clump avoid mobile clump right junior axis book fresh mask tube front require until face effort vault"
# kava1adkm6svtzjsxxvg7g6rshg6kj9qwej8gwqadqd
DATA=~/.kava
# remove any old state and config
rm -rf $DATA
BINARY=kava
# Create new data directory, overwriting any that alread existed
chainID="kava-localnet"
$BINARY init validator --chain-id $chainID
# hacky enable of rest api
sed -in-place='' 's/enable = false/enable = true/g' $DATA/config/app.toml
# avoid having to use password for keys
$BINARY config keyring-backend test
# Create validator keys and add account to genesis
validatorKeyName="validator"
printf "$validatorMnemonic\n" | $BINARY keys add $validatorKeyName --recover
$BINARY add-genesis-account $validatorKeyName 2000000000ukava,100000000000bnb
# Create faucet keys and add account to genesis
faucetKeyName="faucet"
printf "$faucetMnemonic\n" | $BINARY keys add $faucetKeyName --recover
$BINARY add-genesis-account $faucetKeyName 1000000000ukava,100000000000bnb
# Create a delegation tx for the validator and add to genesis
$BINARY gentx $validatorKeyName 1000000000ukava --keyring-backend test --chain-id $chainID
$BINARY collect-gentxs
# Replace stake with ukava
sed -in-place='' 's/stake/ukava/g' $DATA/config/genesis.json
# Zero out the total supply so it gets recalculated during InitGenesis
jq '.app_state.bank.supply = []' $DATA/config/genesis.json|sponge $DATA/config/genesis.json

View File

@ -1,352 +0,0 @@
{
"genesis_time": "2020-03-07T18:27:07.837213082Z",
"chain_id": "testing",
"consensus_params": {
"block": {
"max_bytes": "22020096",
"max_gas": "-1",
"time_iota_ms": "1000"
},
"evidence": {
"max_age": "100000"
},
"validator": {
"pub_key_types": [
"ed25519"
]
}
},
"app_hash": "",
"app_state": {
"cdp": {
"cdps": [],
"debt_denom": "debt",
"deposits": [],
"gov_denom": "ukava",
"previous_distribution_time": "1970-01-01T00:00:00Z",
"params": {
"circuit_breaker": false,
"collateral_params": [
{
"auction_size": "5000000000",
"conversion_factor": "6",
"debt_limit": [
{
"amount": "10000000",
"denom": "usdx"
}
],
"denom": "xrp",
"liquidation_penalty": "0.05",
"liquidation_ratio": "2.0",
"market_id": "xrp:usd",
"prefix": 0,
"stability_fee": "1.000000001547126"
},
{
"auction_size": "10000000",
"conversion_factor": "8",
"debt_limit": [
{
"amount": "10000000",
"denom": "usdx"
}
],
"denom": "btc",
"liquidation_penalty": "0.05",
"liquidation_ratio": "1.5",
"market_id": "btc:usd",
"prefix": 1,
"stability_fee": "1.0000000007829977"
}
],
"debt_auction_threshold": "1000000000",
"debt_params": [
{
"conversion_factor": "6",
"debt_floor": "10000000",
"debt_limit": [
{
"amount": "2000000000000",
"denom": "usdx"
}
],
"denom": "usdx",
"reference_asset": "usd",
"savings_rate": "0.95"
}
],
"global_debt_limit": [
{
"amount": "2000000000000",
"denom": "usdx"
}
],
"savings_distribution_frequency": "120000000000",
"surplus_auction_threshold": "1000000000"
},
"previous_block_time": "1970-01-01T00:00:00Z",
"starting_cdp_id": "1"
},
"bank": {
"send_enabled": true
},
"params": null,
"bep3": {
"params": {
"bnb_deputy_address": "kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj",
"min_block_lock": "80",
"max_block_lock": "600",
"supported_assets": [
{
"denom": "ukava",
"coin_id": "459",
"limit": "1",
"active": false
}
]
},
"atomic_swaps": [],
"assets_supplies": []
},
"pricefeed": {
"params": {
"markets": [
{
"active": true,
"base_asset": "xrp",
"market_id": "xrp:usd",
"oracles": [
"kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"kava1xq4cspcgl9thzmn6lkvd6dlx28wsr63zw4mlmf"
],
"quote_asset": "usd"
},
{
"active": true,
"base_asset": "btc",
"market_id": "btc:usd",
"oracles": [
"kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw"
],
"quote_asset": "usd"
}
]
},
"posted_prices": [
{
"expiry": "2050-01-01T00:00:00Z",
"market_id": "btc:usd",
"oracle_address": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"price": "8700.0"
},
{
"expiry": "2050-01-01T00:00:00Z",
"market_id": "xrp:usd",
"oracle_address": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"price": "0.25"
}
]
},
"gov": {
"starting_proposal_id": "1",
"deposits": null,
"votes": null,
"proposals": null,
"deposit_params": {
"min_deposit": [
{
"denom": "ukava",
"amount": "10000000"
}
],
"max_deposit_period": "172800000000000"
},
"voting_params": {
"voting_period": "172800000000000"
},
"tally_params": {
"quorum": "0.334000000000000000",
"threshold": "0.500000000000000000",
"veto": "0.334000000000000000"
}
},
"staking": {
"params": {
"unbonding_time": "1814400000000000",
"max_validators": 100,
"max_entries": 7,
"bond_denom": "ukava"
},
"last_total_power": "0",
"last_validator_powers": null,
"validators": null,
"delegations": null,
"unbonding_delegations": null,
"redelegations": null,
"exported": false
},
"mint": {
"minter": {
"inflation": "0.130000000000000000",
"annual_provisions": "0.000000000000000000"
},
"params": {
"mint_denom": "ukava",
"inflation_rate_change": "0.130000000000000000",
"inflation_max": "0.200000000000000000",
"inflation_min": "0.070000000000000000",
"goal_bonded": "0.670000000000000000",
"blocks_per_year": "6311520"
}
},
"auth": {
"params": {
"max_memo_characters": "256",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000"
},
"accounts": [
{
"type": "cosmos-sdk/Account",
"value": {
"address": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"coins": [
{
"denom": "ukava",
"amount": "1000000000000"
},
{
"denom": "btc",
"amount": "10000000000"
},
{
"denom": "xrp",
"amount": "1000000000000"
}
],
"public_key": null,
"account_number": "0",
"sequence": "0"
}
},
{
"type": "cosmos-sdk/Account",
"value": {
"address": "kava19dp7luf32mlqnw6mhpgk0g37ule7wm2g8gck8a",
"coins": [
{
"denom": "ukava",
"amount": "1000000000000"
}
],
"public_key": null,
"account_number": "0",
"sequence": "0"
}
}
]
},
"auction": {
"next_auction_id": "1",
"params": {
"max_auction_duration": "172800000000000",
"bid_duration": "3600000000000"
},
"auctions": []
},
"validatorvesting": {
"previous_block_time": "1970-01-01T00:00:00Z"
},
"supply": {
"supply": []
},
"crisis": {
"constant_fee": {
"denom": "ukava",
"amount": "1000"
}
},
"distribution": {
"fee_pool": {
"community_pool": []
},
"community_tax": "0.020000000000000000",
"base_proposer_reward": "0.010000000000000000",
"bonus_proposer_reward": "0.040000000000000000",
"withdraw_addr_enabled": true,
"delegator_withdraw_infos": [],
"previous_proposer": "",
"outstanding_rewards": [],
"validator_accumulated_commissions": [],
"validator_historical_rewards": [],
"validator_current_rewards": [],
"delegator_starting_infos": [],
"validator_slash_events": []
},
"genutil": {
"gentxs": [
{
"type": "cosmos-sdk/StdTx",
"value": {
"msg": [
{
"type": "cosmos-sdk/MsgCreateValidator",
"value": {
"description": {
"moniker": "kava-tester",
"identity": "",
"website": "",
"security_contact": "",
"details": ""
},
"commission": {
"rate": "0.100000000000000000",
"max_rate": "0.200000000000000000",
"max_change_rate": "0.010000000000000000"
},
"min_self_delegation": "1",
"delegator_address": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"validator_address": "kavavaloper15qdefkmwswysgg4qxgqpqr35k3m49pkx8yhpte",
"pubkey": "kavavalconspub1zcjduepq3qyhcxfpa0u2efeu3htuxjz0248khl2cqfcm8jz2n0dr2e2a6tuqqafg2g",
"value": {
"denom": "ukava",
"amount": "10000000000"
}
}
}
],
"fee": {
"amount": [],
"gas": "200000"
},
"signatures": [
{
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "Az740XKIPCJtnZLmJfktTfhsEStEJE3n2iRVyJ3wko43"
},
"signature": "ZIzw2qsaJzsNuROW1JYYH1ZOA3jrc4ZCHvrCxirWNlEZqIvnyC42nBQLIPQ+d+PIcpldLVy0KAkb8NBXj9G0nQ=="
}
],
"memo": "6fff8e9b327f0811e7a25c1419781167f82ec7b3@172.31.40.66:26656"
}
}
]
},
"slashing": {
"params": {
"max_evidence_age": "120000000000",
"signed_blocks_window": "100",
"min_signed_per_window": "0.500000000000000000",
"downtime_jail_duration": "600000000000",
"slash_fraction_double_sign": "0.050000000000000000",
"slash_fraction_downtime": "0.010000000000000000"
},
"signing_infos": {},
"missed_blocks": {}
}
}
}

5441
docs/core/proto-docs.md Normal file

File diff suppressed because it is too large Load Diff

105
docs/protodoc-markdown.tmpl Normal file
View File

@ -0,0 +1,105 @@
<!-- This file is auto-generated. Please do not modify it yourself. -->
# Protobuf Documentation
<a name="top"></a>
## Table of Contents
{{range .Files}}
{{$file_name := .Name}}- [{{.Name}}](#{{.Name}})
{{- if .Messages }}
{{range .Messages}} - [{{.LongName}}](#{{.FullName}})
{{end}}
{{- end -}}
{{- if .Enums }}
{{range .Enums}} - [{{.LongName}}](#{{.FullName}})
{{end}}
{{- end -}}
{{- if .Extensions }}
{{range .Extensions}} - [File-level Extensions](#{{$file_name}}-extensions)
{{end}}
{{- end -}}
{{- if .Services }}
{{range .Services}} - [{{.Name}}](#{{.FullName}})
{{end}}
{{- end -}}
{{end}}
- [Scalar Value Types](#scalar-value-types)
{{range .Files}}
{{$file_name := .Name}}
<a name="{{.Name}}"></a>
<p align="right"><a href="#top">Top</a></p>
## {{.Name}}
{{.Description}}
{{range .Messages}}
<a name="{{.FullName}}"></a>
### {{.LongName}}
{{.Description}}
{{if .HasFields}}
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
{{range .Fields -}}
| `{{.Name}}` | [{{.LongType}}](#{{.FullType}}) | {{.Label}} | {{if (index .Options "deprecated"|default false)}}**Deprecated.** {{end}}{{nobr .Description}}{{if .DefaultValue}} Default: {{.DefaultValue}}{{end}} |
{{end}}
{{end}}
{{if .HasExtensions}}
| Extension | Type | Base | Number | Description |
| --------- | ---- | ---- | ------ | ----------- |
{{range .Extensions -}}
| `{{.Name}}` | {{.LongType}} | {{.ContainingLongType}} | {{.Number}} | {{nobr .Description}}{{if .DefaultValue}} Default: {{.DefaultValue}}{{end}} |
{{end}}
{{end}}
{{end}} <!-- end messages -->
{{range .Enums}}
<a name="{{.FullName}}"></a>
### {{.LongName}}
{{.Description}}
| Name | Number | Description |
| ---- | ------ | ----------- |
{{range .Values -}}
| {{.Name}} | {{.Number}} | {{nobr .Description}} |
{{end}}
{{end}} <!-- end enums -->
{{if .HasExtensions}}
<a name="{{$file_name}}-extensions"></a>
### File-level Extensions
| Extension | Type | Base | Number | Description |
| --------- | ---- | ---- | ------ | ----------- |
{{range .Extensions -}}
| `{{.Name}}` | {{.LongType}} | {{.ContainingLongType}} | {{.Number}} | {{nobr .Description}}{{if .DefaultValue}} Default: `{{.DefaultValue}}`{{end}} |
{{end}}
{{end}} <!-- end HasExtensions -->
{{range .Services}}
<a name="{{.FullName}}"></a>
### {{.Name}}
{{.Description}}
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
{{range .Methods -}}
| `{{.Name}}` | [{{.RequestLongType}}](#{{.RequestFullType}}){{if .RequestStreaming}} stream{{end}} | [{{.ResponseLongType}}](#{{.ResponseFullType}}){{if .ResponseStreaming}} stream{{end}} | {{nobr .Description}} | {{with (index .Options "google.api.http")}}{{range .Rules}}{{.Method}}|{{.Pattern}}{{end}}{{end}}|
{{end}}
{{end}} <!-- end services -->
{{end}}
## Scalar Value Types
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- |
{{range .Scalars -}}
| <a name="{{.ProtoType}}" /> {{.ProtoType}} | {{.Notes}} | {{.CppType}} | {{.JavaType}} | {{.PythonType}} | {{.GoType}} | {{.CSharp}} | {{.PhpType}} | {{.RubyType}} |
{{end}}

39
go.mod
View File

@ -1,18 +1,33 @@
module github.com/kava-labs/kava
go 1.13
go 1.16
require (
github.com/cosmos/cosmos-sdk v0.39.2
github.com/gorilla/mux v1.7.4
github.com/spf13/cobra v1.0.0
github.com/spf13/viper v1.6.3
github.com/stretchr/testify v1.6.1
github.com/tendermint/go-amino v0.15.1
github.com/tendermint/tendermint v0.33.9
github.com/tendermint/tm-db v0.5.1
gopkg.in/yaml.v2 v2.3.0
github.com/cosmos/cosmos-proto v0.0.0-20211020182451-c7ca7198c2f8
github.com/cosmos/cosmos-sdk v0.44.5
github.com/cosmos/ibc-go v1.2.3
github.com/gogo/protobuf v1.3.3
github.com/golang/mock v1.6.0
github.com/golang/protobuf v1.5.2
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/spf13/cast v1.3.1
github.com/spf13/cobra v1.2.1
github.com/stretchr/testify v1.7.0
github.com/tendermint/tendermint v0.34.14
github.com/tendermint/tm-db v0.6.4
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83
google.golang.org/grpc v1.42.0
google.golang.org/protobuf v1.27.1
sigs.k8s.io/yaml v1.1.0
)
// patch bech32 decoding to enable larger string lengths
replace github.com/btcsuite/btcutil => github.com/kava-labs/btcutil v0.0.0-20200522184203-886d33430f06
replace (
github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
github.com/tendermint/tendermint => github.com/tendermint/tendermint v0.34.14
google.golang.org/grpc => google.golang.org/grpc v1.33.2
)
// See https://github.com/cosmos/cosmos-sdk/pull/10401, https://github.com/cosmos/cosmos-sdk/commit/0592ba6158cd0bf49d894be1cef4faeec59e8320
replace github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0

951
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,45 @@
package migrate
import (
"encoding/json"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/spf13/cobra"
tmjson "github.com/tendermint/tendermint/libs/json"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/migrate/v0_15"
"github.com/kava-labs/kava/app/params"
"github.com/kava-labs/kava/migrate/v0_16"
)
// MigrateGenesisCmd returns a command to execute genesis state migration.
func MigrateGenesisCmd(_ *server.Context, cdc *codec.Codec) *cobra.Command {
func MigrateGenesisCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "migrate [genesis-file]",
Short: "Migrate genesis file from kava v0.14 to v0.15",
Long: "Migrate the source genesis into the current version, sorts it, and print to STDOUT.",
Example: fmt.Sprintf(`%s migrate /path/to/genesis.json`, version.ServerName),
Short: "Migrate genesis from v0.15 to v0.16",
Long: "Migrate the source genesis into v0.16 and print to STDOUT.",
Example: fmt.Sprintf(`%s migrate /path/to/genesis.json`, version.AppName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
importGenesis := args[0]
genDoc, err := tmtypes.GenesisDocFromFile(importGenesis)
oldGenDoc, err := tmtypes.GenesisDocFromFile(importGenesis)
if err != nil {
return fmt.Errorf("failed to read genesis document from file %s: %w", importGenesis, err)
}
newGenDoc := v0_15.Migrate(*genDoc)
newGenDoc, err := v0_16.Migrate(oldGenDoc, clientCtx)
if err != nil {
return fmt.Errorf("failed to run migration: %w", err)
}
bz, err := cdc.MarshalJSONIndent(newGenDoc, "", " ")
bz, err := tmjson.Marshal(newGenDoc)
if err != nil {
return fmt.Errorf("failed to marshal genesis doc: %w", err)
}
@ -51,28 +57,26 @@ func MigrateGenesisCmd(_ *server.Context, cdc *codec.Codec) *cobra.Command {
return cmd
}
func AssertInvariantsCmd(_ *server.Context, cdc *codec.Codec) *cobra.Command {
func AssertInvariantsCmd(config params.EncodingConfig) *cobra.Command {
cmd := &cobra.Command{
Use: "assert-invariants [genesis-file]",
Short: "Validates that the input genesis file is valid and invariants pass",
Long: "Reads the input genesis file into a genesis document, checks that the state is valid and asserts that all invariants pass.",
Example: fmt.Sprintf(`%s assert-invariants /path/to/genesis.json`, version.ServerName),
Example: fmt.Sprintf(`%s assert-invariants /path/to/genesis.json`, version.AppName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
importGenesis := args[0]
genDoc, err := tmtypes.GenesisDocFromFile(importGenesis)
genDoc, err := validateGenDoc(importGenesis)
if err != nil {
return fmt.Errorf("failed to read genesis document from file %s: %w", importGenesis, err)
}
tApp := app.NewTestAppFromSealed()
var newAppState genutil.AppMap
cdc := app.MakeCodec()
err = cdc.UnmarshalJSON(genDoc.AppState, &newAppState)
if err != nil {
return fmt.Errorf("failed to marchal app state from genesis doc: %s: %w", importGenesis, err)
var newAppState genutiltypes.AppMap
if err := json.Unmarshal(genDoc.AppState, &newAppState); err != nil {
return fmt.Errorf("failed to marshal app state from genesis doc: %s: %w", importGenesis, err)
}
err = app.ModuleBasics.ValidateGenesis(newAppState)
err = app.ModuleBasics.ValidateGenesis(config.Marshaler, config.TxConfig, newAppState)
if err != nil {
return fmt.Errorf("genesis doc did not pass validate genesis: %s: %w", importGenesis, err)
}
@ -85,3 +89,19 @@ func AssertInvariantsCmd(_ *server.Context, cdc *codec.Codec) *cobra.Command {
return cmd
}
// validateGenDoc reads a genesis file and validates that it is a correct
// Tendermint GenesisDoc. This function does not do any cosmos-related
// validation.
func validateGenDoc(importGenesisFile string) (*tmtypes.GenesisDoc, error) {
genDoc, err := tmtypes.GenesisDocFromFile(importGenesisFile)
if err != nil {
return nil, fmt.Errorf("%s. Make sure that"+
" you have correctly migrated all Tendermint consensus params, please see the"+
" chain migration guide at https://docs.cosmos.network/master/migrations/chain-upgrade-guide-040.html for more info",
err.Error(),
)
}
return genDoc, nil
}

31
migrate/cmd_test.go Normal file
View File

@ -0,0 +1,31 @@
package migrate_test
import (
"context"
"path/filepath"
"testing"
"github.com/cosmos/cosmos-sdk/client"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/migrate"
"github.com/stretchr/testify/require"
)
func TestMigrateGenesisCmd_V16_Success(t *testing.T) {
ctx := newCmdContext()
cmd := migrate.MigrateGenesisCmd()
file := filepath.Join("v0_16", "testdata", "genesis-v15.json")
cmd.SetArgs([]string{file})
err := cmd.ExecuteContext(ctx)
require.NoError(t, err)
}
func newCmdContext() context.Context {
config := app.MakeEncodingConfig()
clientCtx := client.Context{}.
WithCodec(config.Marshaler).
WithLegacyAmino(config.Amino)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
return ctx
}

View File

@ -1,407 +0,0 @@
package rest_v0_3
import (
"fmt"
"net/http"
"strings"
"github.com/gorilla/mux"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/auth"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/auth/types"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/cosmos/cosmos-sdk/x/supply"
v18de63auth "github.com/kava-labs/kava/migrate/v0_8/sdk/auth/v18de63"
v18de63supply "github.com/kava-labs/kava/migrate/v0_8/sdk/supply/v18de63"
v18de63sdk "github.com/kava-labs/kava/migrate/v0_8/sdk/types"
v032tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32"
v032tendermintrpc "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32/rpccore"
valvesting "github.com/kava-labs/kava/x/validator-vesting"
v0_3valvesting "github.com/kava-labs/kava/x/validator-vesting/legacy/v0_3"
)
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
s := r.PathPrefix("/v0_3").Subrouter()
s.HandleFunc("/node_info", rpc.NodeInfoRequestHandlerFn(cliCtx)).Methods("GET")
s.HandleFunc("/auth/accounts/{address}", QueryAccountRequestHandlerFn(cliCtx)).Methods("GET")
s.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(cliCtx)).Methods("GET")
// r.HandleFunc("/txs", QueryTxsRequestHandlerFn(cliCtx)).Methods("GET") // TODO does trust wallet query txs?
s.HandleFunc("/txs", authrest.BroadcastTxRequest(cliCtx)).Methods("POST")
s.HandleFunc("/blocks/latest", LatestBlockRequestHandlerFn(cliCtx)).Methods("GET")
// These endpoints are unchanged between cosmos v18de63 and v0.38.4, but can't import private methods so copy and pasting handler methods.
// Get all delegations from a delegator
s.HandleFunc(
"/staking/delegators/{delegatorAddr}/delegations",
delegatorDelegationsHandlerFn(cliCtx),
).Methods("GET")
// Get all unbonding delegations from a delegator
s.HandleFunc(
"/staking/delegators/{delegatorAddr}/unbonding_delegations",
delegatorUnbondingDelegationsHandlerFn(cliCtx),
).Methods("GET")
// Get the total rewards balance from all delegations
s.HandleFunc(
"/distribution/delegators/{delegatorAddr}/rewards",
delegatorRewardsHandlerFn(cliCtx, disttypes.ModuleName),
).Methods("GET")
}
// REST handler to get the latest block
func LatestBlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
output, err := getBlock(cliCtx, nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
rest.PostProcessResponseBare(w, cliCtx, output)
}
}
func getBlock(cliCtx context.CLIContext, height *int64) ([]byte, error) {
// get the node
node, err := cliCtx.GetNode()
if err != nil {
return nil, err
}
res, err := node.Block(height)
if err != nil {
return nil, err
}
// Convert block to old type
header := v032tendermint.Header{
Version: v032tendermint.Consensus{
Block: v032tendermint.Protocol(res.Block.Header.Version.Block),
App: v032tendermint.Protocol(res.Block.Header.Version.App),
},
ChainID: res.Block.Header.ChainID,
Height: res.Block.Header.Height,
Time: res.Block.Header.Time,
NumTxs: 0, // trust wallet doesn't use this field
TotalTxs: 0, // trust wallet doesn't use this field
LastBlockID: res.Block.Header.LastBlockID,
LastCommitHash: res.Block.Header.LastCommitHash,
DataHash: res.Block.Header.DataHash,
ValidatorsHash: res.Block.Header.ValidatorsHash,
NextValidatorsHash: res.Block.Header.NextValidatorsHash,
ConsensusHash: res.Block.Header.ConsensusHash,
AppHash: res.Block.Header.AppHash,
LastResultsHash: res.Block.Header.LastResultsHash,
EvidenceHash: res.Block.Header.EvidenceHash,
ProposerAddress: res.Block.Header.ProposerAddress,
}
block := v032tendermint.Block{
Header: header,
Data: res.Block.Data,
Evidence: res.Block.Evidence,
LastCommit: nil, // trust wallet doesn't need to access commit info
}
blockMeta := v032tendermint.BlockMeta{
BlockID: res.BlockID,
Header: header,
}
oldResponse := v032tendermintrpc.ResultBlock{
Block: &block,
BlockMeta: &blockMeta,
}
return codec.Cdc.MarshalJSON(oldResponse)
}
// QueryAccountRequestHandlerFn handle auth/accounts queries
// This function is identical to v0.8 except the queried account is cast to the v0.3 account type so it marshals in the old format.
func QueryAccountRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bech32addr := vars["address"]
addr, err := sdk.AccAddressFromBech32(bech32addr)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
accGetter := types.NewAccountRetriever(cliCtx)
account, height, err := accGetter.GetAccountWithHeight(addr)
// convert v0.8 account type into old v0.3 account type so that it json marshals into the v0.3 format
oldAccount := rollbackAccountType(account)
// use old codec with old account interface registered
cliCtx = cliCtx.WithCodec(makeCodecV03())
if err != nil {
if err := accGetter.EnsureExists(addr); err != nil {
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, v18de63auth.BaseAccount{})
return
}
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, oldAccount)
}
}
// QueryTxRequestHandlerFn implements a REST handler that queries a transaction
// by hash in a committed block.
func QueryTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
hashHexStr := vars["hash"]
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
output, err := utils.QueryTx(cliCtx, hashHexStr)
if err != nil {
if strings.Contains(err.Error(), hashHexStr) {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
return
}
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
// convert v0.8 TxResponse to a v0.3 Tx Response
oldOutput := rollbackTxResponseType(output)
if oldOutput.Empty() {
rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr))
}
rest.PostProcessResponseBare(w, cliCtx, oldOutput)
}
}
func rollbackTxResponseType(response sdk.TxResponse) v18de63sdk.TxResponse {
events := sdk.StringEvents{}
for _, msgLog := range response.Logs {
events = append(events, msgLog.Events...)
}
return v18de63sdk.TxResponse{
Height: response.Height,
TxHash: response.TxHash,
Codespace: response.Codespace,
Code: response.Code,
Data: response.Data,
RawLog: response.RawLog,
Logs: nil, // trust wallet doesn't use logs, so leaving them out
Info: response.Info,
GasWanted: response.GasWanted,
GasUsed: response.GasUsed,
Tx: response.Tx,
Timestamp: response.Timestamp,
Events: events,
}
}
func makeCodecV03() *codec.Codec {
v0_3Codec := codec.New()
codec.RegisterCrypto(v0_3Codec)
v18de63auth.RegisterCodec(v0_3Codec)
v18de63auth.RegisterCodecVesting(v0_3Codec)
v18de63supply.RegisterCodec(v0_3Codec)
v0_3valvesting.RegisterCodec(v0_3Codec)
return v0_3Codec
}
func rollbackAccountType(newAccount authexported.Account) v18de63auth.Account {
switch acc := newAccount.(type) {
case *auth.BaseAccount:
return v18de63auth.BaseAccount(*acc)
case *vestingtypes.PeriodicVestingAccount:
ba := v18de63auth.BaseAccount(*(acc.BaseVestingAccount.BaseAccount))
bva := v18de63auth.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.BaseVestingAccount.DelegatedVesting,
EndTime: acc.BaseVestingAccount.EndTime,
}
var newPeriods v18de63auth.Periods
for _, p := range acc.VestingPeriods {
newPeriods = append(newPeriods, v18de63auth.Period(p))
}
pva := v18de63auth.PeriodicVestingAccount{
BaseVestingAccount: &bva,
StartTime: acc.StartTime,
VestingPeriods: newPeriods,
}
return pva
case *valvesting.ValidatorVestingAccount:
ba := v18de63auth.BaseAccount(*(acc.PeriodicVestingAccount.BaseVestingAccount.BaseAccount))
bva := v18de63auth.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.PeriodicVestingAccount.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.PeriodicVestingAccount.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.PeriodicVestingAccount.BaseVestingAccount.DelegatedVesting,
EndTime: acc.PeriodicVestingAccount.BaseVestingAccount.EndTime,
}
var newPeriods v18de63auth.Periods
for _, p := range acc.PeriodicVestingAccount.VestingPeriods {
newPeriods = append(newPeriods, v18de63auth.Period(p))
}
pva := v18de63auth.PeriodicVestingAccount{
BaseVestingAccount: &bva,
StartTime: acc.PeriodicVestingAccount.StartTime,
VestingPeriods: newPeriods,
}
var newVestingProgress []v0_3valvesting.VestingProgress
for _, p := range acc.VestingPeriodProgress {
newVestingProgress = append(newVestingProgress, v0_3valvesting.VestingProgress(p))
}
vva := v0_3valvesting.ValidatorVestingAccount{
PeriodicVestingAccount: &pva,
ValidatorAddress: acc.ValidatorAddress,
ReturnAddress: acc.ReturnAddress,
SigningThreshold: acc.SigningThreshold,
CurrentPeriodProgress: v0_3valvesting.CurrentPeriodProgress(acc.CurrentPeriodProgress),
VestingPeriodProgress: newVestingProgress,
DebtAfterFailedVesting: acc.DebtAfterFailedVesting,
}
return vva
case supply.ModuleAccount:
ba := v18de63auth.BaseAccount(*(acc.BaseAccount))
ma := v18de63supply.ModuleAccount{
BaseAccount: &ba,
Name: acc.Name,
Permissions: acc.Permissions,
}
return ma
case nil:
return acc
default:
panic(fmt.Errorf("unrecognized account type %+v", acc))
}
}
// staking handler funcs
// HTTP request handler to query a delegator delegations
func delegatorDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return queryDelegator(cliCtx, fmt.Sprintf("custom/%s/%s", stakingtypes.QuerierRoute, stakingtypes.QueryDelegatorDelegations))
}
// HTTP request handler to query a delegator unbonding delegations
func delegatorUnbondingDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return queryDelegator(cliCtx, "custom/staking/delegatorUnbondingDelegations")
}
func queryDelegator(cliCtx context.CLIContext, endpoint string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bech32delegator := vars["delegatorAddr"]
delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
params := stakingtypes.NewQueryDelegatorParams(delegatorAddr)
bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
res, height, err := cliCtx.QueryWithData(endpoint, bz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}
// distribution handler funcs
// HTTP request handler to query the total rewards balance from all delegations
func delegatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
delegatorAddr, ok := checkDelegatorAddressVar(w, r)
if !ok {
return
}
params := disttypes.NewQueryDelegatorParams(delegatorAddr)
bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal params: %s", err))
return
}
route := fmt.Sprintf("custom/%s/%s", queryRoute, disttypes.QueryDelegatorTotalRewards)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}
func checkDelegatorAddressVar(w http.ResponseWriter, r *http.Request) (sdk.AccAddress, bool) {
addr, err := sdk.AccAddressFromBech32(mux.Vars(r)["delegatorAddr"])
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return nil, false
}
return addr, true
}

View File

@ -1,66 +0,0 @@
package v38_5
import (
"encoding/json"
"github.com/tendermint/tendermint/crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// BaseAccount - a base account structure.
// This can be extended by embedding within in your AppAccount.
// However one doesn't have to use BaseAccount as long as your struct
// implements Account.
type BaseAccount struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey crypto.PubKey `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
}
// NewBaseAccount creates a new BaseAccount object
func NewBaseAccount(address sdk.AccAddress, coins sdk.Coins,
pubKey crypto.PubKey, accountNumber uint64, sequence uint64) *BaseAccount {
return &BaseAccount{
Address: address,
Coins: coins,
PubKey: pubKey,
AccountNumber: accountNumber,
Sequence: sequence,
}
}
type baseAccountPretty struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey string `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
}
// UnmarshalJSON unmarshals raw JSON bytes into a BaseAccount.
func (acc *BaseAccount) UnmarshalJSON(bz []byte) error {
var alias baseAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
if alias.PubKey != "" {
pk, err := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}
acc.PubKey = pk
}
acc.Address = alias.Address
acc.Coins = alias.Coins
acc.AccountNumber = alias.AccountNumber
acc.Sequence = alias.Sequence
return nil
}

View File

@ -1,14 +0,0 @@
package v38_5
import (
"github.com/cosmos/cosmos-sdk/codec"
)
const ModuleName = "auth"
// RegisterCodec registers concrete types on the codec
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterInterface((*GenesisAccount)(nil), nil)
cdc.RegisterInterface((*Account)(nil), nil)
cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/Account", nil)
}

View File

@ -1,18 +0,0 @@
package v38_5
// Account is an interface used to store coins at a given address within state.
// It presumes a notion of sequence numbers for replay protection,
// a notion of account numbers for replay protection for previously pruned accounts,
// and a pubkey for authentication purposes.
//
// Many complex conditions can be used in the concrete struct which implements Account.
type Account interface {
}
// GenesisAccounts defines a slice of GenesisAccount objects
type GenesisAccounts []GenesisAccount
// GenesisAccount defines a genesis account that embeds an Account with validation capabilities.
type GenesisAccount interface {
Account
}

View File

@ -1,7 +0,0 @@
package v38_5
// GenesisState - all auth state that must be provided at genesis
type GenesisState struct {
Params Params `json:"params" yaml:"params"`
Accounts GenesisAccounts `json:"accounts" yaml:"accounts"`
}

View File

@ -1,10 +0,0 @@
package v38_5
// Params defines the parameters for the auth module.
type Params struct {
MaxMemoCharacters uint64 `json:"max_memo_characters" yaml:"max_memo_characters"`
TxSigLimit uint64 `json:"tx_sig_limit" yaml:"tx_sig_limit"`
TxSizeCostPerByte uint64 `json:"tx_size_cost_per_byte" yaml:"tx_size_cost_per_byte"`
SigVerifyCostED25519 uint64 `json:"sig_verify_cost_ed25519" yaml:"sig_verify_cost_ed25519"`
SigVerifyCostSecp256k1 uint64 `json:"sig_verify_cost_secp256k1" yaml:"sig_verify_cost_secp256k1"`
}

View File

@ -1,14 +0,0 @@
package v38_5
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Period defines a length of time and amount of coins that will vest
type Period struct {
Length int64 `json:"length" yaml:"length"` // length of the period, in seconds
Amount sdk.Coins `json:"amount" yaml:"amount"` // amount of coins vesting during this period
}
// Periods stores all vesting periods passed as part of a PeriodicVestingAccount
type Periods []Period

View File

@ -1,194 +0,0 @@
package v38_5
import (
"encoding/json"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/tendermint/tendermint/crypto"
)
// VestingAccount defines an account type that vests coins via a vesting schedule.
type VestingAccount interface {
Account
}
// BaseVestingAccount implements the VestingAccount interface. It contains all
// the necessary fields needed for any vesting account implementation.
type BaseVestingAccount struct {
*BaseAccount
OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"` // coins in account upon initialization
DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"` // coins that are vested and delegated
DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"` // coins that vesting and delegated
EndTime int64 `json:"end_time" yaml:"end_time"` // when the coins become unlocked
}
type vestingAccountPretty struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey string `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"`
DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"`
DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"`
EndTime int64 `json:"end_time" yaml:"end_time"`
// custom fields based on concrete vesting type which can be omitted
StartTime int64 `json:"start_time,omitempty" yaml:"start_time,omitempty"`
VestingPeriods Periods `json:"vesting_periods,omitempty" yaml:"vesting_periods,omitempty"`
}
// UnmarshalJSON unmarshals raw JSON bytes into a BaseVestingAccount.
func (bva *BaseVestingAccount) UnmarshalJSON(bz []byte) error {
var alias vestingAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
var (
pk crypto.PubKey
err error
)
if alias.PubKey != "" {
pk, err = sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}
}
bva.BaseAccount = NewBaseAccount(alias.Address, alias.Coins, pk, alias.AccountNumber, alias.Sequence)
bva.OriginalVesting = alias.OriginalVesting
bva.DelegatedFree = alias.DelegatedFree
bva.DelegatedVesting = alias.DelegatedVesting
bva.EndTime = alias.EndTime
return nil
}
// ContinuousVestingAccount implements the VestingAccount interface. It
// continuously vests by unlocking coins linearly with respect to time.
type ContinuousVestingAccount struct {
*BaseVestingAccount
StartTime int64 `json:"start_time" yaml:"start_time"` // when the coins start to vest
}
// UnmarshalJSON unmarshals raw JSON bytes into a ContinuousVestingAccount.
func (cva *ContinuousVestingAccount) UnmarshalJSON(bz []byte) error {
var alias vestingAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
var (
pk crypto.PubKey
err error
)
if alias.PubKey != "" {
pk, err = sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}
}
cva.BaseVestingAccount = &BaseVestingAccount{
BaseAccount: NewBaseAccount(alias.Address, alias.Coins, pk, alias.AccountNumber, alias.Sequence),
OriginalVesting: alias.OriginalVesting,
DelegatedFree: alias.DelegatedFree,
DelegatedVesting: alias.DelegatedVesting,
EndTime: alias.EndTime,
}
cva.StartTime = alias.StartTime
return nil
}
// PeriodicVestingAccount implements the VestingAccount interface. It
// periodically vests by unlocking coins during each specified period
type PeriodicVestingAccount struct {
*BaseVestingAccount
StartTime int64 `json:"start_time" yaml:"start_time"` // when the coins start to vest
VestingPeriods Periods `json:"vesting_periods" yaml:"vesting_periods"` // the vesting schedule
}
// NewPeriodicVestingAccountRaw creates a new PeriodicVestingAccount object from BaseVestingAccount
func NewPeriodicVestingAccountRaw(bva *BaseVestingAccount, startTime int64, periods Periods) *PeriodicVestingAccount {
return &PeriodicVestingAccount{
BaseVestingAccount: bva,
StartTime: startTime,
VestingPeriods: periods,
}
}
// UnmarshalJSON unmarshals raw JSON bytes into a PeriodicVestingAccount.
func (pva *PeriodicVestingAccount) UnmarshalJSON(bz []byte) error {
var alias vestingAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
var (
pk crypto.PubKey
err error
)
if alias.PubKey != "" {
pk, err = sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}
}
pva.BaseVestingAccount = &BaseVestingAccount{
BaseAccount: NewBaseAccount(alias.Address, alias.Coins, pk, alias.AccountNumber, alias.Sequence),
OriginalVesting: alias.OriginalVesting,
DelegatedFree: alias.DelegatedFree,
DelegatedVesting: alias.DelegatedVesting,
EndTime: alias.EndTime,
}
pva.StartTime = alias.StartTime
pva.VestingPeriods = alias.VestingPeriods
return nil
}
// DelayedVestingAccount implements the VestingAccount interface. It vests all
// coins after a specific time, but non prior. In other words, it keeps them
// locked until a specified time.
type DelayedVestingAccount struct {
*BaseVestingAccount
}
// UnmarshalJSON unmarshals raw JSON bytes into a DelayedVestingAccount.
func (dva *DelayedVestingAccount) UnmarshalJSON(bz []byte) error {
var alias vestingAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
var (
pk crypto.PubKey
err error
)
if alias.PubKey != "" {
pk, err = sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}
}
dva.BaseVestingAccount = &BaseVestingAccount{
BaseAccount: NewBaseAccount(alias.Address, alias.Coins, pk, alias.AccountNumber, alias.Sequence),
OriginalVesting: alias.OriginalVesting,
DelegatedFree: alias.DelegatedFree,
DelegatedVesting: alias.DelegatedVesting,
EndTime: alias.EndTime,
}
return nil
}

View File

@ -1,14 +0,0 @@
package v38_5
import (
"github.com/cosmos/cosmos-sdk/codec"
)
// RegisterCodecVesting registers concrete types on the codec
func RegisterCodecVesting(cdc *codec.Codec) { // renamed to avoid conflict as packages are combined
cdc.RegisterInterface((*VestingAccount)(nil), nil)
cdc.RegisterConcrete(&BaseVestingAccount{}, "cosmos-sdk/BaseVestingAccount", nil)
cdc.RegisterConcrete(&ContinuousVestingAccount{}, "cosmos-sdk/ContinuousVestingAccount", nil)
cdc.RegisterConcrete(&DelayedVestingAccount{}, "cosmos-sdk/DelayedVestingAccount", nil)
cdc.RegisterConcrete(&PeriodicVestingAccount{}, "cosmos-sdk/PeriodicVestingAccount", nil)
}

View File

@ -1,46 +0,0 @@
package v38_5
import (
"encoding/json"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/kava-labs/kava/migrate/v0_11/legacy/cosmos-sdk/v0.38.5/auth"
)
// ModuleAccount defines an account for modules that holds coins on a pool
type ModuleAccount struct {
*authtypes.BaseAccount
Name string `json:"name" yaml:"name"` // name of the module
Permissions []string `json:"permissions" yaml:"permissions"` // permissions of module account
}
type moduleAccountPretty struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey string `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
Name string `json:"name" yaml:"name"`
Permissions []string `json:"permissions" yaml:"permissions"`
}
// UnmarshalJSON unmarshals raw JSON bytes into a ModuleAccount.
func (ma *ModuleAccount) UnmarshalJSON(bz []byte) error {
var alias moduleAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
ma.BaseAccount = authtypes.NewBaseAccount(alias.Address, alias.Coins, nil, alias.AccountNumber, alias.Sequence)
ma.Name = alias.Name
ma.Permissions = alias.Permissions
return nil
}
// RegisterCodec registers the account types and interface
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterConcrete(&ModuleAccount{}, "cosmos-sdk/ModuleAccount", nil)
}

View File

@ -1,858 +0,0 @@
package v0_11
import (
"fmt"
"time"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
v39_1auth "github.com/cosmos/cosmos-sdk/x/auth"
v39_1authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
v39_1vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
v39_genutil "github.com/cosmos/cosmos-sdk/x/genutil"
v39_1gov "github.com/cosmos/cosmos-sdk/x/gov"
v39_1supply "github.com/cosmos/cosmos-sdk/x/supply"
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/kava-labs/kava/app"
v38_5auth "github.com/kava-labs/kava/migrate/v0_11/legacy/cosmos-sdk/v0.38.5/auth"
v38_5supply "github.com/kava-labs/kava/migrate/v0_11/legacy/cosmos-sdk/v0.38.5/supply"
v0_11bep3 "github.com/kava-labs/kava/x/bep3"
v0_9bep3 "github.com/kava-labs/kava/x/bep3/legacy/v0_9"
v0_11cdp "github.com/kava-labs/kava/x/cdp/legacy/v0_11"
v0_9cdp "github.com/kava-labs/kava/x/cdp/legacy/v0_9"
v0_11committee "github.com/kava-labs/kava/x/committee/legacy/v0_11"
v0_9committee "github.com/kava-labs/kava/x/committee/legacy/v0_9"
v0_11harvest "github.com/kava-labs/kava/x/hard/legacy/v0_11"
v0_11incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_11"
v0_9incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_9"
v0_11issuance "github.com/kava-labs/kava/x/issuance"
v0_11pricefeed "github.com/kava-labs/kava/x/pricefeed"
v0_9pricefeed "github.com/kava-labs/kava/x/pricefeed/legacy/v0_9"
v0_11validator_vesting "github.com/kava-labs/kava/x/validator-vesting"
v0_9validator_vesting "github.com/kava-labs/kava/x/validator-vesting/legacy/v0_9"
)
var deputyBnbBalance sdk.Coin
var hardBalance sdk.Coin
// Migrate translates a genesis file from kava v0.9 (or v0.10) format to kava v0.11.x format.
func Migrate(genDoc tmtypes.GenesisDoc) tmtypes.GenesisDoc {
// migrate app state
var appStateMap v39_genutil.AppMap
cdc := codec.New()
cryptoAmino.RegisterAmino(cdc)
tmtypes.RegisterEvidences(cdc)
if err := cdc.UnmarshalJSON(genDoc.AppState, &appStateMap); err != nil {
panic(err)
}
newAppState := MigrateAppState(appStateMap)
v0_11Codec := app.MakeCodec()
marshaledNewAppState, err := v0_11Codec.MarshalJSON(newAppState)
if err != nil {
panic(err)
}
genDoc.AppState = marshaledNewAppState
genDoc.GenesisTime = time.Date(2020, 10, 15, 14, 0, 0, 0, time.UTC)
genDoc.ChainID = "kava-4"
return genDoc
}
// MigrateAppState migrates application state from v0.9 (or v0.10) format to a kava v0.11.x format
func MigrateAppState(v0_9AppState v39_genutil.AppMap) v39_genutil.AppMap {
v0_11AppState := v0_9AppState
v0_11Codec := app.MakeCodec()
if v0_9AppState[v38_5auth.ModuleName] != nil {
v0_9cdc := codec.New()
codec.RegisterCrypto(v0_9cdc)
v38_5auth.RegisterCodec(v0_9cdc)
v38_5auth.RegisterCodecVesting(v0_9cdc)
v38_5supply.RegisterCodec(v0_9cdc)
v0_9validator_vesting.RegisterCodec(v0_9cdc)
var authGenState v38_5auth.GenesisState
v0_9cdc.MustUnmarshalJSON(v0_9AppState[v38_5auth.ModuleName], &authGenState)
delete(v0_9AppState, v38_5auth.ModuleName)
newAuthGS := MigrateAuth(authGenState)
v0_11AppState[v39_1auth.ModuleName] = v0_11Codec.MustMarshalJSON(newAuthGS)
}
if v0_9AppState[v39_1supply.ModuleName] != nil {
var supplyGenstate v39_1supply.GenesisState
v0_11Codec.MustUnmarshalJSON(v0_9AppState[v39_1supply.ModuleName], &supplyGenstate)
delete(v0_9AppState, v39_1supply.ModuleName)
v0_11AppState[v39_1supply.ModuleName] = v0_11Codec.MustMarshalJSON(
MigrateSupply(
supplyGenstate, deputyBnbBalance, sdk.NewCoin("hard", sdk.NewInt(200000000000000))))
}
if v0_9AppState[v39_1gov.ModuleName] != nil {
var govGenstate v39_1gov.GenesisState
v0_11Codec.MustUnmarshalJSON(v0_9AppState[v39_1gov.ModuleName], &govGenstate)
delete(v0_9AppState, v39_1gov.ModuleName)
v0_11AppState[v39_1gov.ModuleName] = v0_11Codec.MustMarshalJSON(
MigrateGov(govGenstate))
}
if v0_9AppState[v0_9bep3.ModuleName] != nil {
var bep3GenState v0_9bep3.GenesisState
v0_11Codec.MustUnmarshalJSON(v0_9AppState[v0_9bep3.ModuleName], &bep3GenState)
delete(v0_9AppState, v0_9bep3.ModuleName)
v0_11AppState[v0_9bep3.ModuleName] = v0_11Codec.MustMarshalJSON(MigrateBep3(bep3GenState))
}
if v0_9AppState[v0_9cdp.ModuleName] != nil {
var cdpGenState v0_9cdp.GenesisState
v0_11Codec.MustUnmarshalJSON(v0_9AppState[v0_9cdp.ModuleName], &cdpGenState)
delete(v0_9AppState, v0_9cdp.ModuleName)
v0_11AppState[v0_9cdp.ModuleName] = v0_11Codec.MustMarshalJSON(MigrateCDP(cdpGenState))
}
if v0_9AppState[v0_9committee.ModuleName] != nil {
var committeeGenState v0_9committee.GenesisState
cdc := codec.New()
sdk.RegisterCodec(cdc)
v0_9committee.RegisterCodec(cdc)
cdc.MustUnmarshalJSON(v0_9AppState[v0_9committee.ModuleName], &committeeGenState)
delete(v0_9AppState, v0_9committee.ModuleName)
v0_11AppState[v0_9committee.ModuleName] = v0_11Codec.MustMarshalJSON(MigrateCommittee(committeeGenState))
}
if v0_9AppState[v0_9incentive.ModuleName] != nil {
var incentiveGenState v0_9incentive.GenesisState
v0_11Codec.MustUnmarshalJSON(v0_9AppState[v0_9incentive.ModuleName], &incentiveGenState)
delete(v0_9AppState, v0_9incentive.ModuleName)
v0_11AppState[v0_9incentive.ModuleName] = v0_11Codec.MustMarshalJSON(MigrateIncentive(incentiveGenState))
}
if v0_9AppState[v0_9pricefeed.ModuleName] != nil {
var pricefeedGenState v0_9pricefeed.GenesisState
v0_11Codec.MustUnmarshalJSON(v0_9AppState[v0_9pricefeed.ModuleName], &pricefeedGenState)
delete(v0_9AppState, v0_9pricefeed.ModuleName)
v0_11AppState[v0_9pricefeed.ModuleName] = v0_11Codec.MustMarshalJSON(MigratePricefeed(pricefeedGenState))
}
v0_11AppState[v0_11harvest.ModuleName] = v0_11Codec.MustMarshalJSON(MigrateHarvest())
v0_11AppState[v0_11issuance.ModuleName] = v0_11Codec.MustMarshalJSON(v0_11issuance.DefaultGenesisState())
return v0_11AppState
}
// MigrateBep3 migrates from a v0.9 (or v0.10) bep3 genesis state to a v0.11 bep3 genesis state
func MigrateBep3(oldGenState v0_9bep3.GenesisState) v0_11bep3.GenesisState {
var assetParams v0_11bep3.AssetParams
var assetSupplies v0_11bep3.AssetSupplies
v0_9Params := oldGenState.Params
for _, asset := range v0_9Params.SupportedAssets {
v11AssetParam := v0_11bep3.AssetParam{
Active: asset.Active,
Denom: asset.Denom,
CoinID: asset.CoinID,
DeputyAddress: v0_9Params.BnbDeputyAddress,
FixedFee: v0_9Params.BnbDeputyFixedFee,
MinSwapAmount: v0_9Params.BnbDeputyFixedFee.Add(sdk.OneInt()), // set min swap to one (after fees)- prevents accounts that hold zero bnb from creating spam txs
MaxSwapAmount: v0_9Params.MaxAmount,
MinBlockLock: v0_9Params.MinBlockLock,
MaxBlockLock: v0_9Params.MaxBlockLock,
SupplyLimit: v0_11bep3.SupplyLimit{
Limit: asset.Limit,
TimeLimited: false,
TimePeriod: time.Duration(0),
TimeBasedLimit: sdk.ZeroInt(),
},
}
assetParams = append(assetParams, v11AssetParam)
}
for _, supply := range oldGenState.AssetSupplies {
newSupply := v0_11bep3.NewAssetSupply(supply.IncomingSupply, supply.OutgoingSupply, supply.CurrentSupply, sdk.NewCoin(supply.CurrentSupply.Denom, sdk.ZeroInt()), time.Duration(0))
assetSupplies = append(assetSupplies, newSupply)
}
var swaps v0_11bep3.AtomicSwaps
for _, oldSwap := range oldGenState.AtomicSwaps {
newSwap := v0_11bep3.AtomicSwap{
Amount: oldSwap.Amount,
RandomNumberHash: oldSwap.RandomNumberHash,
ExpireHeight: oldSwap.ExpireHeight,
Timestamp: oldSwap.Timestamp,
Sender: oldSwap.Sender,
Recipient: oldSwap.Recipient,
SenderOtherChain: oldSwap.SenderOtherChain,
RecipientOtherChain: oldSwap.RecipientOtherChain,
ClosedBlock: oldSwap.ClosedBlock,
Status: v0_11bep3.SwapStatus(oldSwap.Status),
CrossChain: oldSwap.CrossChain,
Direction: v0_11bep3.SwapDirection(oldSwap.Direction),
}
swaps = append(swaps, newSwap)
}
// -------------- ADD BTCB To BEP3 params --------------------
btcbAssetParam := v0_11bep3.NewAssetParam(
"btcb",
0,
v0_11bep3.SupplyLimit{
Limit: sdk.NewInt(100000000), // 1 BTC limit at launch
TimeLimited: false,
TimePeriod: time.Duration(0),
TimeBasedLimit: sdk.ZeroInt()},
true,
mustAccAddressFromBech32("kava14qsmvzprqvhwmgql9fr0u3zv9n2qla8zhnm5pc"),
sdk.NewInt(2), // 2 satoshi fee
sdk.NewInt(3),
sdk.NewInt(1000000000),
220,
270,
)
btcbAssetSupply := v0_11bep3.NewAssetSupply(
sdk.NewCoin("btcb", sdk.ZeroInt()),
sdk.NewCoin("btcb", sdk.ZeroInt()),
sdk.NewCoin("btcb", sdk.ZeroInt()),
sdk.NewCoin("btcb", sdk.ZeroInt()),
time.Duration(0))
assetParams = append(assetParams, btcbAssetParam)
assetSupplies = append(assetSupplies, btcbAssetSupply)
// -------------- ADD XRPB To BEP3 params --------------------
xrpbAssetParam := v0_11bep3.NewAssetParam(
"xrpb", // NOTE: XRPB has 8 decimals on binance chain, whereas XRP has 6 decimals natively
144,
v0_11bep3.SupplyLimit{
Limit: sdk.NewInt(1000000000000), // 10,000 XRP limit at launch
TimeLimited: false,
TimePeriod: time.Duration(0),
TimeBasedLimit: sdk.ZeroInt()},
true,
mustAccAddressFromBech32("kava1c0ju5vnwgpgxnrktfnkccuth9xqc68dcdpzpas"),
sdk.NewInt(100000), // 0.001 XRP fee
sdk.NewInt(100001),
sdk.NewInt(10000000000000),
220,
270,
)
xrpbAssetSupply := v0_11bep3.NewAssetSupply(
sdk.NewCoin("xrpb", sdk.ZeroInt()),
sdk.NewCoin("xrpb", sdk.ZeroInt()),
sdk.NewCoin("xrpb", sdk.ZeroInt()),
sdk.NewCoin("xrpb", sdk.ZeroInt()),
time.Duration(0))
assetParams = append(assetParams, xrpbAssetParam)
assetSupplies = append(assetSupplies, xrpbAssetSupply)
// -------------- ADD BUSD To BEP3 params --------------------
busdAssetParam := v0_11bep3.NewAssetParam(
"busd",
727, // note - no official SLIP 44 ID
v0_11bep3.SupplyLimit{
Limit: sdk.NewInt(100000000000), // 1,000 BUSD limit at launch
TimeLimited: false,
TimePeriod: time.Duration(0),
TimeBasedLimit: sdk.ZeroInt()},
true,
mustAccAddressFromBech32("kava1hh4x3a4suu5zyaeauvmv7ypf7w9llwlfufjmuu"),
sdk.NewInt(20000),
sdk.NewInt(20001),
sdk.NewInt(1000000000000),
220,
270,
)
busdAssetSupply := v0_11bep3.NewAssetSupply(
sdk.NewCoin("busd", sdk.ZeroInt()),
sdk.NewCoin("busd", sdk.ZeroInt()),
sdk.NewCoin("busd", sdk.ZeroInt()),
sdk.NewCoin("busd", sdk.ZeroInt()),
time.Duration(0))
assetParams = append(assetParams, busdAssetParam)
assetSupplies = append(assetSupplies, busdAssetSupply)
return v0_11bep3.GenesisState{
Params: v0_11bep3.NewParams(assetParams),
AtomicSwaps: swaps,
Supplies: assetSupplies,
PreviousBlockTime: v0_11bep3.DefaultPreviousBlockTime,
}
}
// MigrateCommittee migrates from a v0.9 (or v0.10) committee genesis state to a v0.11 committee genesis state
func MigrateCommittee(oldGenState v0_9committee.GenesisState) v0_11committee.GenesisState {
var newCommittees []v0_11committee.Committee
var newStabilityCommittee v0_11committee.Committee
var newSafetyCommittee v0_11committee.Committee
var newProposals []v0_11committee.Proposal
var newVotes []v0_11committee.Vote
for _, committee := range oldGenState.Committees {
if committee.ID == 1 {
newStabilityCommittee.Description = committee.Description
newStabilityCommittee.ID = committee.ID
newStabilityCommittee.Members = committee.Members
newStabilityCommittee.VoteThreshold = committee.VoteThreshold
newStabilityCommittee.ProposalDuration = committee.ProposalDuration
var newStabilityPermissions []v0_11committee.Permission
var newStabilitySubParamPermissions v0_11committee.SubParamChangePermission
for _, permission := range committee.Permissions {
subPermission, ok := permission.(v0_9committee.SubParamChangePermission)
if ok {
oldCollateralParam := subPermission.AllowedCollateralParams[0]
newCollateralParam := v0_11committee.AllowedCollateralParam{
Type: "bnb-a",
Denom: false,
AuctionSize: oldCollateralParam.AuctionSize,
ConversionFactor: oldCollateralParam.ConversionFactor,
DebtLimit: oldCollateralParam.DebtLimit,
LiquidationMarketID: oldCollateralParam.LiquidationMarketID,
SpotMarketID: oldCollateralParam.SpotMarketID,
LiquidationPenalty: oldCollateralParam.LiquidationPenalty,
LiquidationRatio: oldCollateralParam.LiquidationRatio,
Prefix: oldCollateralParam.Prefix,
StabilityFee: oldCollateralParam.StabilityFee,
}
oldDebtParam := subPermission.AllowedDebtParam
newDebtParam := v0_11committee.AllowedDebtParam{
ConversionFactor: oldDebtParam.ConversionFactor,
DebtFloor: oldDebtParam.DebtFloor,
Denom: oldDebtParam.Denom,
ReferenceAsset: oldDebtParam.ReferenceAsset,
}
oldAssetParam := subPermission.AllowedAssetParams[0]
newAssetParam := v0_11committee.AllowedAssetParam{
Active: oldAssetParam.Active,
CoinID: oldAssetParam.CoinID,
Denom: oldAssetParam.Denom,
Limit: oldAssetParam.Limit,
MaxSwapAmount: true,
MinBlockLock: true,
}
oldMarketParams := subPermission.AllowedMarkets
var newMarketParams v0_11committee.AllowedMarkets
for _, oldMarketParam := range oldMarketParams {
newMarketParam := v0_11committee.AllowedMarket(oldMarketParam)
newMarketParams = append(newMarketParams, newMarketParam)
}
// add btc, xrp, busd markets to committee
btcMarketParam := v0_11committee.AllowedMarket{
MarketID: "btc:usd",
BaseAsset: false,
QuoteAsset: false,
Oracles: false,
Active: true,
}
btc30MarketParam := v0_11committee.AllowedMarket{
MarketID: "btc:usd:30",
BaseAsset: false,
QuoteAsset: false,
Oracles: false,
Active: true,
}
xrpMarketParam := v0_11committee.AllowedMarket{
MarketID: "xrp:usd",
BaseAsset: false,
QuoteAsset: false,
Oracles: false,
Active: true,
}
xrp30MarketParam := v0_11committee.AllowedMarket{
MarketID: "xrp:usd:30",
BaseAsset: false,
QuoteAsset: false,
Oracles: false,
Active: true,
}
busdMarketParam := v0_11committee.AllowedMarket{
MarketID: "busd:usd",
BaseAsset: false,
QuoteAsset: false,
Oracles: false,
Active: true,
}
busd30MarketParam := v0_11committee.AllowedMarket{
MarketID: "busd:usd:30",
BaseAsset: false,
QuoteAsset: false,
Oracles: false,
Active: true,
}
newMarketParams = append(newMarketParams, btcMarketParam, btc30MarketParam, xrpMarketParam, xrp30MarketParam, busdMarketParam, busd30MarketParam)
oldAllowedParams := subPermission.AllowedParams
var newAllowedParams v0_11committee.AllowedParams
for _, oldAllowedParam := range oldAllowedParams {
newAllowedParam := v0_11committee.AllowedParam(oldAllowedParam)
if oldAllowedParam.Subspace == "bep3" && oldAllowedParam.Key == "SupportedAssets" {
newAllowedParam.Key = "AssetParams"
}
harvestParam := v0_11committee.AllowedParam{Subspace: "harvest", Key: "Active"}
newAllowedParams = append(newAllowedParams, newAllowedParam, harvestParam)
}
// --------------- ADD BUSD, XRP-B, BTC-B BEP3 parameters to Stability Committee Permissions
busdAllowedAssetParam := v0_11committee.AllowedAssetParam{
Active: true,
CoinID: true, // allow busd coinID to be updated in case it gets its own slip-44
Denom: "busd",
Limit: true,
MaxSwapAmount: true,
MinBlockLock: true,
}
xrpbAllowedAssetParam := v0_11committee.AllowedAssetParam{
Active: true,
CoinID: false,
Denom: "xrpb",
Limit: true,
MaxSwapAmount: true,
MinBlockLock: true,
}
btcbAllowedAssetParam := v0_11committee.AllowedAssetParam{
Active: true,
CoinID: false,
Denom: "btcb",
Limit: true,
MaxSwapAmount: true,
MinBlockLock: true,
}
// --------- ADD BTC-B, XRP-B, BUSD(a), BUSD(b) cdp collateral params to stability committee
busdaAllowedCollateralParam := v0_11committee.NewAllowedCollateralParam(
"busd-a", false, false, true, true, true, false, false, false, false, false,
)
busdbAllowedCollateralParam := v0_11committee.NewAllowedCollateralParam(
"busd-b", false, false, true, true, true, false, false, false, false, false,
)
btcbAllowedCollateralParam := v0_11committee.NewAllowedCollateralParam(
"btcb-a", false, false, true, true, true, false, false, false, false, false,
)
xrpbAllowedCollateralParam := v0_11committee.NewAllowedCollateralParam(
"xrpb-a", false, false, true, true, true, false, false, false, false, false,
)
newStabilitySubParamPermissions.AllowedAssetParams = v0_11committee.AllowedAssetParams{
newAssetParam, busdAllowedAssetParam, btcbAllowedAssetParam, xrpbAllowedAssetParam}
newStabilitySubParamPermissions.AllowedCollateralParams = v0_11committee.AllowedCollateralParams{
newCollateralParam, busdaAllowedCollateralParam, busdbAllowedCollateralParam, btcbAllowedCollateralParam, xrpbAllowedCollateralParam}
newStabilitySubParamPermissions.AllowedDebtParam = newDebtParam
newStabilitySubParamPermissions.AllowedMarkets = newMarketParams
newStabilitySubParamPermissions.AllowedParams = newAllowedParams
newStabilityPermissions = append(newStabilityPermissions, newStabilitySubParamPermissions)
}
}
newStabilityPermissions = append(newStabilityPermissions, v0_11committee.TextPermission{})
newStabilityCommittee.Permissions = newStabilityPermissions
newCommittees = append(newCommittees, newStabilityCommittee)
} else {
newSafetyCommittee.ID = committee.ID
newSafetyCommittee.Description = committee.Description
newSafetyCommittee.Members = committee.Members
newSafetyCommittee.Permissions = []v0_11committee.Permission{v0_11committee.SoftwareUpgradePermission{}}
newSafetyCommittee.VoteThreshold = committee.VoteThreshold
newSafetyCommittee.ProposalDuration = committee.ProposalDuration
newCommittees = append(newCommittees, newSafetyCommittee)
}
}
for _, oldProp := range oldGenState.Proposals {
newPubProposal := v0_11committee.PubProposal(oldProp.PubProposal)
newProp := v0_11committee.NewProposal(newPubProposal, oldProp.ID, oldProp.CommitteeID, oldProp.Deadline)
newProposals = append(newProposals, newProp)
}
for _, oldVote := range oldGenState.Votes {
newVote := v0_11committee.NewVote(oldVote.ProposalID, oldVote.Voter)
newVotes = append(newVotes, newVote)
}
return v0_11committee.GenesisState{
NextProposalID: oldGenState.NextProposalID,
Committees: newCommittees,
Proposals: newProposals,
Votes: newVotes,
}
}
// MigrateAuth migrates from a v0.38.5 auth genesis state to a v0.39.1 auth genesis state
func MigrateAuth(oldGenState v38_5auth.GenesisState) v39_1auth.GenesisState {
var newAccounts v39_1authexported.GenesisAccounts
deputyBnbBalance = sdk.NewCoin("bnb", sdk.ZeroInt())
deputyAddr, err := sdk.AccAddressFromBech32("kava1r4v2zdhdalfj2ydazallqvrus9fkphmglhn6u6")
if err != nil {
panic(err)
}
deputyColdAddr, err := sdk.AccAddressFromBech32("kava1qm2u6nyv7kg6awdm46caccgzn5h7mdkde0sue6")
if err != nil {
panic(err)
}
for _, account := range oldGenState.Accounts {
switch acc := account.(type) {
case *v38_5auth.BaseAccount:
a := v39_1auth.BaseAccount(*acc)
// Remove deputy bnb
if a.GetAddress().Equals(deputyAddr) || a.GetAddress().Equals(deputyColdAddr) {
deputyBnbBalance = deputyBnbBalance.Add(sdk.NewCoin("bnb", a.GetCoins().AmountOf("bnb")))
err := a.SetCoins(a.GetCoins().Sub(sdk.NewCoins(sdk.NewCoin("bnb", a.GetCoins().AmountOf("bnb")))))
if err != nil {
panic(err)
}
}
newAccounts = append(newAccounts, v39_1authexported.GenesisAccount(&a))
case *v38_5auth.BaseVestingAccount:
ba := v39_1auth.BaseAccount(*(acc.BaseAccount))
bva := v39_1vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.OriginalVesting,
DelegatedFree: acc.DelegatedFree,
DelegatedVesting: acc.DelegatedVesting,
EndTime: acc.EndTime,
}
newAccounts = append(newAccounts, v39_1authexported.GenesisAccount(&bva))
case *v38_5auth.ContinuousVestingAccount:
ba := v39_1auth.BaseAccount(*(acc.BaseVestingAccount.BaseAccount))
bva := v39_1vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.BaseVestingAccount.DelegatedVesting,
EndTime: acc.BaseVestingAccount.EndTime,
}
cva := v39_1vesting.ContinuousVestingAccount{
BaseVestingAccount: &bva,
StartTime: acc.StartTime,
}
newAccounts = append(newAccounts, v39_1authexported.GenesisAccount(&cva))
case *v38_5auth.DelayedVestingAccount:
ba := v39_1auth.BaseAccount(*(acc.BaseVestingAccount.BaseAccount))
bva := v39_1vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.BaseVestingAccount.DelegatedVesting,
EndTime: acc.BaseVestingAccount.EndTime,
}
dva := v39_1vesting.DelayedVestingAccount{
BaseVestingAccount: &bva,
}
newAccounts = append(newAccounts, v39_1authexported.GenesisAccount(&dva))
case *v38_5auth.PeriodicVestingAccount:
ba := v39_1auth.BaseAccount(*(acc.BaseVestingAccount.BaseAccount))
bva := v39_1vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.BaseVestingAccount.DelegatedVesting,
EndTime: acc.BaseVestingAccount.EndTime,
}
var newPeriods v39_1vesting.Periods
for _, p := range acc.VestingPeriods {
newPeriods = append(newPeriods, v39_1vesting.Period(p))
}
pva := v39_1vesting.PeriodicVestingAccount{
BaseVestingAccount: &bva,
StartTime: acc.StartTime,
VestingPeriods: newPeriods,
}
newAccounts = append(newAccounts, v39_1authexported.GenesisAccount(&pva))
case *v38_5supply.ModuleAccount:
ba := v39_1auth.BaseAccount(*(acc.BaseAccount))
ma := v39_1supply.ModuleAccount{
BaseAccount: &ba,
Name: acc.Name,
Permissions: acc.Permissions,
}
newAccounts = append(newAccounts, v39_1authexported.GenesisAccount(&ma))
case *v0_9validator_vesting.ValidatorVestingAccount:
ba := v39_1auth.BaseAccount(*(acc.BaseAccount))
bva := v39_1vesting.BaseVestingAccount{
BaseAccount: &ba,
OriginalVesting: acc.BaseVestingAccount.OriginalVesting,
DelegatedFree: acc.BaseVestingAccount.DelegatedFree,
DelegatedVesting: acc.BaseVestingAccount.DelegatedVesting,
EndTime: acc.BaseVestingAccount.EndTime,
}
var newPeriods v39_1vesting.Periods
for _, p := range acc.VestingPeriods {
newPeriods = append(newPeriods, v39_1vesting.Period(p))
}
pva := v39_1vesting.PeriodicVestingAccount{
BaseVestingAccount: &bva,
StartTime: acc.StartTime,
VestingPeriods: newPeriods,
}
var newVestingProgress []v0_11validator_vesting.VestingProgress
for _, p := range acc.VestingPeriodProgress {
newVestingProgress = append(newVestingProgress, v0_11validator_vesting.VestingProgress(p))
}
vva := v0_11validator_vesting.ValidatorVestingAccount{
PeriodicVestingAccount: &pva,
ValidatorAddress: acc.ValidatorAddress,
ReturnAddress: acc.ReturnAddress,
SigningThreshold: acc.SigningThreshold,
CurrentPeriodProgress: v0_11validator_vesting.CurrentPeriodProgress(acc.CurrentPeriodProgress),
VestingPeriodProgress: newVestingProgress,
DebtAfterFailedVesting: acc.DebtAfterFailedVesting,
}
newAccounts = append(newAccounts, v39_1authexported.GenesisAccount(&vva))
default:
panic(fmt.Sprintf("unrecognized account type: %T", acc))
}
}
// ---- add harvest module accounts -------
lpMacc := v39_1supply.NewEmptyModuleAccount(v0_11harvest.LPAccount, v39_1supply.Minter, v39_1supply.Burner)
err = lpMacc.SetCoins(sdk.NewCoins(sdk.NewCoin("hard", sdk.NewInt(80000000000000))))
if err != nil {
panic(err)
}
newAccounts = append(newAccounts, v39_1authexported.GenesisAccount(lpMacc))
delegatorMacc := v39_1supply.NewEmptyModuleAccount(v0_11harvest.DelegatorAccount, v39_1supply.Minter, v39_1supply.Burner)
err = delegatorMacc.SetCoins(sdk.NewCoins(sdk.NewCoin("hard", sdk.NewInt(40000000000000))))
if err != nil {
panic(err)
}
newAccounts = append(newAccounts, v39_1authexported.GenesisAccount(delegatorMacc))
hardBalance = sdk.NewCoin("hard", sdk.NewInt(200000000000000))
hardTeam := createHardTeamVestingAccount()
hardTreasury := createHardTreasuryVestingAccount()
hardIEO := createHardIEOAccount()
newAccounts = append(newAccounts, hardTeam, hardTreasury, &hardIEO)
return v39_1auth.NewGenesisState(v39_1auth.Params(oldGenState.Params), newAccounts)
}
// MigrateSupply reconciles supply from kava-3 to kava-4
// deputy balance of bnb coins is removed (deputy now mints coins)
// hard token supply is added
func MigrateSupply(oldGenState v39_1supply.GenesisState, deputyBalance sdk.Coin, hardBalance sdk.Coin) v39_1supply.GenesisState {
oldGenState.Supply = oldGenState.Supply.Sub(sdk.Coins{deputyBalance}).Add(hardBalance)
return oldGenState
}
// MigrateGov migrates gov genesis state
func MigrateGov(oldGenState v39_1gov.GenesisState) v39_1gov.GenesisState {
oldGenState.VotingParams.VotingPeriod = time.Hour * 24 * 7
return oldGenState
}
// MigrateHarvest initializes the harvest genesis state for kava-4
func MigrateHarvest() v0_11harvest.GenesisState {
// total HARD per second for lps (week one): 633761
// HARD per second for delegators (week one): 1267522
incentiveGoLiveDate := time.Date(2020, 10, 16, 14, 0, 0, 0, time.UTC)
incentiveEndDate := time.Date(2024, 10, 16, 14, 0, 0, 0, time.UTC)
claimEndDate := time.Date(2025, 10, 16, 14, 0, 0, 0, time.UTC)
harvestGS := v0_11harvest.NewGenesisState(v0_11harvest.NewParams(
true,
v0_11harvest.DistributionSchedules{
v0_11harvest.NewDistributionSchedule(true, "usdx", incentiveGoLiveDate, incentiveEndDate, sdk.NewCoin("hard", sdk.NewInt(310543)), claimEndDate, v0_11harvest.Multipliers{v0_11harvest.NewMultiplier(v0_11harvest.Small, 1, sdk.MustNewDecFromStr("0.33")), v0_11harvest.NewMultiplier(v0_11harvest.Large, 12, sdk.OneDec())}),
v0_11harvest.NewDistributionSchedule(true, "hard", incentiveGoLiveDate, incentiveEndDate, sdk.NewCoin("hard", sdk.NewInt(285193)), claimEndDate, v0_11harvest.Multipliers{v0_11harvest.NewMultiplier(v0_11harvest.Small, 1, sdk.MustNewDecFromStr("0.33")), v0_11harvest.NewMultiplier(v0_11harvest.Large, 12, sdk.OneDec())}),
v0_11harvest.NewDistributionSchedule(true, "bnb", incentiveGoLiveDate, incentiveEndDate, sdk.NewCoin("hard", sdk.NewInt(12675)), claimEndDate, v0_11harvest.Multipliers{v0_11harvest.NewMultiplier(v0_11harvest.Small, 1, sdk.MustNewDecFromStr("0.33")), v0_11harvest.NewMultiplier(v0_11harvest.Large, 12, sdk.OneDec())}),
v0_11harvest.NewDistributionSchedule(true, "ukava", incentiveGoLiveDate, incentiveEndDate, sdk.NewCoin("hard", sdk.NewInt(25350)), claimEndDate, v0_11harvest.Multipliers{v0_11harvest.NewMultiplier(v0_11harvest.Small, 1, sdk.MustNewDecFromStr("0.33")), v0_11harvest.NewMultiplier(v0_11harvest.Large, 12, sdk.OneDec())}),
},
v0_11harvest.DelegatorDistributionSchedules{v0_11harvest.NewDelegatorDistributionSchedule(
v0_11harvest.NewDistributionSchedule(true, "ukava", incentiveGoLiveDate, incentiveEndDate, sdk.NewCoin("hard", sdk.NewInt(1267522)), claimEndDate, v0_11harvest.Multipliers{v0_11harvest.NewMultiplier(v0_11harvest.Small, 1, sdk.MustNewDecFromStr("0.33")), v0_11harvest.NewMultiplier(v0_11harvest.Large, 12, sdk.OneDec())}),
time.Hour*24,
),
},
), v0_11harvest.DefaultPreviousBlockTime, v0_11harvest.DefaultDistributionTimes, v0_11harvest.DefaultDeposits, v0_11harvest.DefaultClaims)
return harvestGS
}
// MigrateCDP migrates from a v0.9 (or v0.10) cdp genesis state to a v0.11 cdp genesis state
func MigrateCDP(oldGenState v0_9cdp.GenesisState) v0_11cdp.GenesisState {
var newCDPs v0_11cdp.CDPs
var newDeposits v0_11cdp.Deposits
var newCollateralParams v0_11cdp.CollateralParams
newStartingID := oldGenState.StartingCdpID
for _, cdp := range oldGenState.CDPs {
newCDP := v0_11cdp.NewCDPWithFees(cdp.ID, cdp.Owner, cdp.Collateral, "bnb-a", cdp.Principal, cdp.AccumulatedFees, cdp.FeesUpdated)
newCDPs = append(newCDPs, newCDP)
}
for _, dep := range oldGenState.Deposits {
newDep := v0_11cdp.NewDeposit(dep.CdpID, dep.Depositor, dep.Amount)
newDeposits = append(newDeposits, newDep)
}
for _, cp := range oldGenState.Params.CollateralParams {
newCollateralParam := v0_11cdp.NewCollateralParam(cp.Denom, "bnb-a", cp.LiquidationRatio, cp.DebtLimit, cp.StabilityFee, cp.AuctionSize, cp.LiquidationPenalty, 0x01, cp.SpotMarketID, cp.LiquidationMarketID, cp.ConversionFactor)
newCollateralParams = append(newCollateralParams, newCollateralParam)
}
btcbCollateralParam := v0_11cdp.NewCollateralParam("btcb", "btcb-a", sdk.MustNewDecFromStr("1.5"), sdk.NewCoin("usdx", sdk.NewInt(100000000000)), sdk.MustNewDecFromStr("1.000000001547125958"), sdk.NewInt(100000000), sdk.MustNewDecFromStr("0.075000000000000000"), 0x02, "btc:usd", "btc:usd:30", sdk.NewInt(8))
busdaCollateralParam := v0_11cdp.NewCollateralParam("busd", "busd-a", sdk.MustNewDecFromStr("1.01"), sdk.NewCoin("usdx", sdk.NewInt(3000000000000)), sdk.OneDec(), sdk.NewInt(1000000000000), sdk.MustNewDecFromStr("0.075000000000000000"), 0x03, "busd:usd", "busd:usd:30", sdk.NewInt(8))
busdbCollateralParam := v0_11cdp.NewCollateralParam("busd", "busd-b", sdk.MustNewDecFromStr("1.1"), sdk.NewCoin("usdx", sdk.NewInt(1000000000000)), sdk.MustNewDecFromStr("1.000000012857214317"), sdk.NewInt(1000000000000), sdk.MustNewDecFromStr("0.075000000000000000"), 0x04, "busd:usd", "busd:usd:30", sdk.NewInt(8))
xrpbCollateralParam := v0_11cdp.NewCollateralParam("xrpb", "xrpb-a", sdk.MustNewDecFromStr("1.5"), sdk.NewCoin("usdx", sdk.NewInt(100000000000)), sdk.MustNewDecFromStr("1.000000001547125958"), sdk.NewInt(4000000000000), sdk.MustNewDecFromStr("0.075000000000000000"), 0x05, "xrp:usd", "xrp:usd:30", sdk.NewInt(8))
newCollateralParams = append(newCollateralParams, btcbCollateralParam, busdaCollateralParam, busdbCollateralParam, xrpbCollateralParam)
oldDebtParam := oldGenState.Params.DebtParam
newDebtParam := v0_11cdp.NewDebtParam(oldDebtParam.Denom, oldDebtParam.ReferenceAsset, oldDebtParam.ConversionFactor, oldDebtParam.DebtFloor, oldDebtParam.SavingsRate)
newGlobalDebtLimit := oldGenState.Params.GlobalDebtLimit.Add(btcbCollateralParam.DebtLimit).Add(busdaCollateralParam.DebtLimit).Add(busdbCollateralParam.DebtLimit).Add(xrpbCollateralParam.DebtLimit)
newParams := v0_11cdp.NewParams(newGlobalDebtLimit, newCollateralParams, newDebtParam, oldGenState.Params.SurplusAuctionThreshold, oldGenState.Params.SurplusAuctionLot, oldGenState.Params.DebtAuctionThreshold, oldGenState.Params.DebtAuctionLot, oldGenState.Params.SavingsDistributionFrequency, false)
return v0_11cdp.NewGenesisState(
newParams,
newCDPs,
newDeposits,
newStartingID,
oldGenState.DebtDenom,
oldGenState.GovDenom,
oldGenState.PreviousDistributionTime,
sdk.ZeroInt(),
)
}
// MigrateIncentive migrates from a v0.9 (or v0.10) incentive genesis state to a v0.11 incentive genesis state
func MigrateIncentive(oldGenState v0_9incentive.GenesisState) v0_11incentive.GenesisState {
var newRewards v0_11incentive.Rewards
var newRewardPeriods v0_11incentive.RewardPeriods
var newClaimPeriods v0_11incentive.ClaimPeriods
var newClaims v0_11incentive.Claims
var newClaimPeriodIds v0_11incentive.GenesisClaimPeriodIDs
newMultiplier := v0_11incentive.NewMultiplier(v0_11incentive.Large, 12, sdk.OneDec())
smallMultiplier := v0_11incentive.NewMultiplier(v0_11incentive.Small, 1, sdk.MustNewDecFromStr("0.25"))
for _, oldReward := range oldGenState.Params.Rewards {
newReward := v0_11incentive.NewReward(oldReward.Active, oldReward.Denom+"-a", oldReward.AvailableRewards, oldReward.Duration, v0_11incentive.Multipliers{smallMultiplier, newMultiplier}, oldReward.ClaimDuration)
newRewards = append(newRewards, newReward)
}
newParams := v0_11incentive.NewParams(true, newRewards)
for _, oldRewardPeriod := range oldGenState.RewardPeriods {
newRewardPeriod := v0_11incentive.NewRewardPeriod(oldRewardPeriod.Denom+"-a", oldRewardPeriod.Start, oldRewardPeriod.End, oldRewardPeriod.Reward, oldRewardPeriod.ClaimEnd, v0_11incentive.Multipliers{smallMultiplier, newMultiplier})
newRewardPeriods = append(newRewardPeriods, newRewardPeriod)
}
for _, oldClaimPeriod := range oldGenState.ClaimPeriods {
newClaimPeriod := v0_11incentive.NewClaimPeriod(oldClaimPeriod.Denom+"-a", oldClaimPeriod.ID, oldClaimPeriod.End, v0_11incentive.Multipliers{smallMultiplier, newMultiplier})
newClaimPeriods = append(newClaimPeriods, newClaimPeriod)
}
for _, oldClaim := range oldGenState.Claims {
newClaim := v0_11incentive.NewClaim(oldClaim.Owner, oldClaim.Reward, oldClaim.Denom+"-a", oldClaim.ClaimPeriodID)
newClaims = append(newClaims, newClaim)
}
for _, oldClaimPeriodID := range oldGenState.NextClaimPeriodIDs {
newClaimPeriodID := v0_11incentive.GenesisClaimPeriodID{
CollateralType: oldClaimPeriodID.Denom + "-a",
ID: oldClaimPeriodID.ID,
}
newClaimPeriodIds = append(newClaimPeriodIds, newClaimPeriodID)
}
return v0_11incentive.NewGenesisState(newParams, oldGenState.PreviousBlockTime, newRewardPeriods, newClaimPeriods, newClaims, newClaimPeriodIds)
}
// MigratePricefeed migrates from a v0.9 (or v0.10) pricefeed genesis state to a v0.11 pricefeed genesis state
func MigratePricefeed(oldGenState v0_9pricefeed.GenesisState) v0_11pricefeed.GenesisState {
var newMarkets v0_11pricefeed.Markets
var newPostedPrices v0_11pricefeed.PostedPrices
var oracles []sdk.AccAddress
for _, market := range oldGenState.Params.Markets {
newMarket := v0_11pricefeed.NewMarket(market.MarketID, market.BaseAsset, market.QuoteAsset, market.Oracles, market.Active)
newMarkets = append(newMarkets, newMarket)
oracles = market.Oracles
}
// ------- add btc, xrp, busd markets --------
btcSpotMarket := v0_11pricefeed.NewMarket("btc:usd", "btc", "usd", oracles, true)
btcLiquidationMarket := v0_11pricefeed.NewMarket("btc:usd:30", "btc", "usd", oracles, true)
xrpSpotMarket := v0_11pricefeed.NewMarket("xrp:usd", "xrp", "usd", oracles, true)
xrpLiquidationMarket := v0_11pricefeed.NewMarket("xrp:usd:30", "xrp", "usd", oracles, true)
busdSpotMarket := v0_11pricefeed.NewMarket("busd:usd", "busd", "usd", oracles, true)
busdLiquidationMarket := v0_11pricefeed.NewMarket("busd:usd:30", "busd", "usd", oracles, true)
newMarkets = append(newMarkets, btcSpotMarket, btcLiquidationMarket, xrpSpotMarket, xrpLiquidationMarket, busdSpotMarket, busdLiquidationMarket)
for _, price := range oldGenState.PostedPrices {
newPrice := v0_11pricefeed.NewPostedPrice(price.MarketID, price.OracleAddress, price.Price, price.Expiry)
newPostedPrices = append(newPostedPrices, newPrice)
}
newParams := v0_11pricefeed.NewParams(newMarkets)
return v0_11pricefeed.NewGenesisState(newParams, newPostedPrices)
}
func mustAccAddressFromBech32(bech32Addr string) sdk.AccAddress {
addr, err := sdk.AccAddressFromBech32(bech32Addr)
if err != nil {
panic(err)
}
return addr
}
func createHardTeamVestingAccount() *v39_1vesting.PeriodicVestingAccount {
bacc := v39_1auth.NewBaseAccountWithAddress(mustAccAddressFromBech32("kava17a9m9zxs3r5zhxnultt5k5kyer0afd7kc8dq80"))
coins := sdk.NewCoin("hard", sdk.NewInt(20000000000000))
tokenSchedule := []sdk.Coin{
sdk.NewCoin("hard", sdk.NewInt(6666666720000)),
sdk.NewCoin("hard", sdk.NewInt(1666666660000)),
sdk.NewCoin("hard", sdk.NewInt(1666666660000)),
sdk.NewCoin("hard", sdk.NewInt(1666666660000)),
sdk.NewCoin("hard", sdk.NewInt(1666666660000)),
sdk.NewCoin("hard", sdk.NewInt(1666666660000)),
sdk.NewCoin("hard", sdk.NewInt(1666666660000)),
sdk.NewCoin("hard", sdk.NewInt(1666666660000)),
sdk.NewCoin("hard", sdk.NewInt(1666666660000)),
}
err := bacc.SetCoins(sdk.NewCoins(coins))
if err != nil {
panic(err)
}
bva, err := v39_1vesting.NewBaseVestingAccount(&bacc, sdk.NewCoins(coins), 1697378400)
if err != nil {
panic(err)
}
vestingPeriodLengths := []int64{31536000, 7948800, 7776000, 7862400, 7948800, 7948800, 7776000, 7862400, 7948800}
periods := v39_1vesting.Periods{}
for i, vestingCoin := range tokenSchedule {
period := v39_1vesting.Period{Length: vestingPeriodLengths[i], Amount: sdk.NewCoins(vestingCoin)}
periods = append(periods, period)
}
return vesting.NewPeriodicVestingAccountRaw(bva, 1602770400, periods)
}
func createHardTreasuryVestingAccount() *v39_1vesting.PeriodicVestingAccount {
bacc := v39_1auth.NewBaseAccountWithAddress(mustAccAddressFromBech32("kava1yqt02z2e4gpt4w0jnw9n0hnqyfu45afns669r2"))
coins := sdk.NewCoin("hard", sdk.NewInt(50000000000000))
originalVestingCoins := sdk.NewCoin("hard", sdk.NewInt(35000000000000))
tokenSchedule := []sdk.Coin{
sdk.NewCoin("hard", sdk.NewInt(4375000000000)),
sdk.NewCoin("hard", sdk.NewInt(4375000000000)),
sdk.NewCoin("hard", sdk.NewInt(4375000000000)),
sdk.NewCoin("hard", sdk.NewInt(4375000000000)),
sdk.NewCoin("hard", sdk.NewInt(4375000000000)),
sdk.NewCoin("hard", sdk.NewInt(4375000000000)),
sdk.NewCoin("hard", sdk.NewInt(4375000000000)),
sdk.NewCoin("hard", sdk.NewInt(4375000000000)),
}
err := bacc.SetCoins(sdk.NewCoins(coins))
if err != nil {
panic(err)
}
bva, err := v39_1vesting.NewBaseVestingAccount(&bacc, sdk.NewCoins(originalVestingCoins), 1665842400)
if err != nil {
panic(err)
}
vestingPeriodLengths := []int64{7948800, 7776000, 7862400, 7948800, 7948800, 7776000, 7862400, 7948800}
periods := v39_1vesting.Periods{}
for i, vestingCoin := range tokenSchedule {
period := v39_1vesting.Period{Length: vestingPeriodLengths[i], Amount: sdk.NewCoins(vestingCoin)}
periods = append(periods, period)
}
return vesting.NewPeriodicVestingAccountRaw(bva, 1602770400, periods)
}
func createHardIEOAccount() v39_1auth.BaseAccount {
bacc := v39_1auth.NewBaseAccountWithAddress(mustAccAddressFromBech32("kava16yapwtdxm5hkjfpeatr39vhu5c336fgf4utlyf"))
coins := sdk.NewCoin("hard", sdk.NewInt(10000000000000))
err := bacc.SetCoins(sdk.NewCoins(coins))
if err != nil {
panic(err)
}
return bacc
}

View File

@ -1,84 +0,0 @@
# Kava-4 Upgrade Instructions
## Software Version and Key Dates
* The version of Kava for kava-4 is v0.11
* Kava-3 validators should prepare to shutdown their nodes October 15th, 2020 at 12:00 UTC
* Kava-4 genesis time is set to October 15th, 2020 at 14:00 UTC
* The version of cosmos-sdk for kava-4 is v0.39.1
* The version of tendermint for kava-4 v0.33.7
### Risks
As a validator, performing the upgrade procedure on your consensus nodes carries a heightened risk of double-signing and being slashed. The most important piece of this procedure is verifying your software version and genesis file hash before starting your validator and signing.
The riskiest thing a validator can do is discover that they made a mistake and repeat the upgrade procedure again during the network startup. If you discover a mistake in the process, the best thing to do is wait for the network to start before correcting it. If the network is halted and you have started with a different genesis file than the expected one, seek advice from a Kava developer before resetting your validator.
### Recovery
Prior to exporting kava-3 state, validators are encouraged to take a full data snapshot at the export height before proceeding. Snap-shotting depends heavily on infrastructure, but generally this can be done by backing up the .kvd and .kvcli directories.
It is critically important to back-up the .kvd/data/priv_validator_state.json file after stopping your kvd process. This file is updated every block as your validator participates in consensus rounds. It is a critical file needed to prevent double-signing, in case the upgrade fails and the previous chain needs to be restarted.
In the event that the upgrade does not succeed, validators and operators must downgrade back to v0.10.0 of the Kava software and restore to their latest snapshot before restarting their nodes.
## Upgrade Procedure
### Before the upgrade
Set your node to produce the final block of kava-3 at __12:00__ UTC October 15th, 2020. To restart your node with that stop time,
```sh
kvd start --halt-time 1602763200
```
You can safely set the halt-time flag at any time.
### On the day of the upgrade
__The kava chain is expected to halt at 12:00 UTC, and restart with new software at 14:00 UTC October 15th. Do not stop your node and begin the upgrade before 12:00UTC on October 15th, or you may go offline and be unable to recover until after the upgrade!__
Kava developers will update this PR with the final block number when it is reached. __Make sure the kvd process is stopped before proceeding and that you have backed up your validator__. Failure to backup your validator could make it impossible to restart your node if the upgrade fails.
1. Export State
```sh
kvd export --for-zero-height > export-genesis.json
```
2. Update to kava-4
```sh
# in the `kava` folder
git pull
git checkout v0.11.0
make install
# verify versions
kvd version --long
# name: kava
# server_name: kvd
# client_name: kvcli
# version: 0.11.0
# commit: a9c253c09f8ed4a2a7180f76ed4cd46017805590
# build_tags: netgo,ledger
# go: go version go1.15.2 linux/amd64
# Migrate genesis state
kvd migrate export-genesis.json > genesis.json
# Verify output of genesis migration
kvd validate-genesis genesis.json # should say it's valid
jq -S -c -M '' genesis.json | shasum -a 256
# [PLACEHOLDER]
# Restart node with migrated genesis state
cp genesis.json ~/.kvd/config/genesis.json
kvd unsafe-reset-all
kvd start
```
### Coordination
If the kava-4 chain does not launch by October 15, 2020 at 16:00 UTC, the launch should be considered a failure. Validators should restore the state from kava-3 and coordinate a relaunch. In the event of launch failure, coordination will occur in the [Kava discord](https://discord.com/invite/kQzh3Uv).

View File

@ -1,166 +0,0 @@
package v0_11
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types"
v39_1auth "github.com/cosmos/cosmos-sdk/x/auth"
v39_1auth_vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting"
v39_1supply "github.com/cosmos/cosmos-sdk/x/supply"
"github.com/kava-labs/kava/app"
v38_5auth "github.com/kava-labs/kava/migrate/v0_11/legacy/cosmos-sdk/v0.38.5/auth"
v38_5supply "github.com/kava-labs/kava/migrate/v0_11/legacy/cosmos-sdk/v0.38.5/supply"
v0_9bep3 "github.com/kava-labs/kava/x/bep3/legacy/v0_9"
v0_9cdp "github.com/kava-labs/kava/x/cdp/legacy/v0_9"
v0_9committee "github.com/kava-labs/kava/x/committee/legacy/v0_9"
v0_9incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_9"
v0_9pricefeed "github.com/kava-labs/kava/x/pricefeed/legacy/v0_9"
v0_11validator_vesting "github.com/kava-labs/kava/x/validator-vesting"
v0_9validator_vesting "github.com/kava-labs/kava/x/validator-vesting/legacy/v0_9"
)
func TestMain(m *testing.M) {
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
app.SetBip44CoinType(config)
os.Exit(m.Run())
}
func TestMigrateBep3(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "bep3-v09.json"))
require.NoError(t, err)
var oldGenState v0_9bep3.GenesisState
cdc := app.MakeCodec()
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := MigrateBep3(oldGenState)
err = newGenState.Validate()
require.NoError(t, err)
}
func TestMigrateCommittee(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "committee-v09.json"))
require.NoError(t, err)
var oldGenState v0_9committee.GenesisState
cdc := codec.New()
sdk.RegisterCodec(cdc)
v0_9committee.RegisterCodec(cdc)
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := MigrateCommittee(oldGenState)
err = newGenState.Validate()
require.NoError(t, err)
}
func TestMigrateAuth(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "auth-v09.json"))
require.NoError(t, err)
var oldGenState v38_5auth.GenesisState
cdc := codec.New()
codec.RegisterCrypto(cdc)
v38_5auth.RegisterCodec(cdc)
v38_5auth.RegisterCodecVesting(cdc)
v38_5supply.RegisterCodec(cdc)
v0_9validator_vesting.RegisterCodec(cdc)
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := MigrateAuth(oldGenState)
err = v39_1auth.ValidateGenesis(newGenState)
require.NoError(t, err)
require.Equal(t, len(oldGenState.Accounts)+5, len(newGenState.Accounts))
}
func TestMigrateAuthExact(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "auth-v09-simplified.json"))
require.NoError(t, err)
var oldGenState v38_5auth.GenesisState
v09_cdc := codec.New()
codec.RegisterCrypto(v09_cdc)
v38_5auth.RegisterCodec(v09_cdc)
v38_5auth.RegisterCodecVesting(v09_cdc)
v38_5supply.RegisterCodec(v09_cdc)
v0_9validator_vesting.RegisterCodec(v09_cdc)
require.NotPanics(t, func() {
v09_cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := MigrateAuth(oldGenState)
v011_cdc := codec.New()
codec.RegisterCrypto(v011_cdc)
v39_1auth.RegisterCodec(v011_cdc)
v39_1auth_vesting.RegisterCodec(v011_cdc)
v39_1supply.RegisterCodec(v011_cdc)
v0_11validator_vesting.RegisterCodec(v011_cdc)
newGenStateBz, err := v011_cdc.MarshalJSON(newGenState)
require.NoError(t, err)
expectedGenStateBz, err := ioutil.ReadFile(filepath.Join("testdata", "auth-v011-simplified.json"))
require.NoError(t, err)
require.JSONEq(t, string(expectedGenStateBz), string(newGenStateBz))
}
func TestMigrateHarvest(t *testing.T) {
newGenState := MigrateHarvest()
err := newGenState.Validate()
require.NoError(t, err)
}
func TestMigrateCdp(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "cdp-v09.json"))
require.NoError(t, err)
var oldGenState v0_9cdp.GenesisState
cdc := app.MakeCodec()
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := MigrateCDP(oldGenState)
err = newGenState.Validate()
require.NoError(t, err)
}
func TestMigrateIncentive(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "incentive-v09.json"))
require.NoError(t, err)
var oldGenState v0_9incentive.GenesisState
cdc := app.MakeCodec()
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := MigrateIncentive(oldGenState)
err = newGenState.Validate()
require.NoError(t, err)
}
func TestMigratePricefeed(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "pricefeed-v09.json"))
require.NoError(t, err)
var oldGenState v0_9pricefeed.GenesisState
cdc := app.MakeCodec()
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := MigratePricefeed(oldGenState)
err = newGenState.Validate()
require.NoError(t, err)
}

View File

@ -1,683 +0,0 @@
{
"params": {
"max_memo_characters": "512",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": "10145",
"address": "kava1llungtpe0aku8c2gqpm23jvs4r0caqdwjzq078",
"coins": [
{
"amount": "92810900",
"denom": "ukava"
}
],
"public_key": null,
"sequence": "0"
}
},
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": "96",
"address": "kava1ceun2qqw65qce5la33j8zv8ltyyaqqfcxftutz",
"coins": [
{
"amount": "1095029582",
"denom": "ukava"
}
],
"public_key": {
"type": "tendermint/PubKeyMultisigThreshold",
"value": {
"pubkeys": [
{
"type": "tendermint/PubKeySecp256k1",
"value": "AxUMR/GKoycWplR+2otzaQZ9zhHRQWJFt3h1bPg1ltha"
},
{
"type": "tendermint/PubKeySecp256k1",
"value": "Az/Xn9XKadn79UpA8TRVrHKbi64QGTxjVSKR9tzMy15o"
},
{
"type": "tendermint/PubKeySecp256k1",
"value": "As7R9fDUnwsUVLDr1cxspp+cY9UfXfUf7i9/w+N0EzKA"
},
{
"type": "tendermint/PubKeySecp256k1",
"value": "A708lKSSivhkgH3n1UGy/AlfWyiehRVAp9G+Nlsy+rDj"
},
{
"type": "tendermint/PubKeySecp256k1",
"value": "ArixmwMR2HoBdIzWiUT6HZFMScZv8odQ0KkIMcoqXHwq"
}
],
"threshold": "2"
}
},
"sequence": "8"
}
},
{
"type": "cosmos-sdk/ValidatorVestingAccount",
"value": {
"account_number": "4",
"address": "kava1qzvq736hxfwdqgxwek3229z7ec4rfmc6s4kdc2",
"coins": [
{
"amount": "1829450",
"denom": "ukava"
}
],
"current_period_progress": {
"missed_blocks": "1540",
"total_blocks": "3468891"
},
"debt_after_failed_vesting": [],
"delegated_free": [
{
"amount": "9990000",
"denom": "ukava"
}
],
"delegated_vesting": [
{
"amount": "333317710000",
"denom": "ukava"
}
],
"end_time": "1636120800",
"original_vesting": [
{
"amount": "333317710000",
"denom": "ukava"
}
],
"public_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "A9hxcErxj1laSwp7Ipj1eiCDtyqKG18xYFPjknoc0keG"
},
"return_address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"sequence": "24",
"signing_threshold": "90",
"start_time": "1572962400",
"validator_address": "kavavalcons16mkm6ggf280kjtsxnvzur7tnqttgavj4mzr4zf",
"vesting_period_progress": [
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
}
],
"vesting_periods": [
{
"amount": [
{
"amount": "92588250185",
"denom": "ukava"
}
],
"length": "31622400"
},
{
"amount": [
{
"amount": "60182345788",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "60182345788",
"denom": "ukava"
}
],
"length": "7689600"
},
{
"amount": [
{
"amount": "60182345788",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "60182422451",
"denom": "ukava"
}
],
"length": "7948800"
}
]
}
},
{
"type": "cosmos-sdk/PeriodicVestingAccount",
"value": {
"account_number": "159",
"address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"coins": [
{
"amount": "899999001",
"denom": "bnb"
},
{
"amount": "2200212895",
"denom": "ukava"
},
{
"amount": "1004240",
"denom": "usdx"
}
],
"delegated_free": [],
"delegated_vesting": [
{
"amount": "4147313000000",
"denom": "ukava"
}
],
"end_time": "1636120800",
"original_vesting": [
{
"amount": "5177909376500",
"denom": "ukava"
}
],
"public_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "A5HnBfmGgoeySJ1vZZ7tT1RMhSBuw6V2XfazETdfupQd"
},
"sequence": "184",
"start_time": "1572962400",
"vesting_periods": [
{
"amount": [
{
"amount": "247437068100",
"denom": "ukava"
}
],
"length": "7948800"
},
{
"amount": [
{
"amount": "484707541700",
"denom": "ukava"
}
],
"length": "7776000"
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": "2592000"
},
{
"amount": [
{
"amount": "606688729200",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": "2592000"
},
{
"amount": [
{
"amount": "760072166700",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": "2592000"
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "910727972900",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "20971305600",
"denom": "ukava"
}
],
"length": "2419200"
},
{
"amount": [
{
"amount": "20971305600",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "912464084000",
"denom": "ukava"
}
],
"length": "2592000"
},
{
"amount": [
{
"amount": "20971305600",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "20971305600",
"denom": "ukava"
}
],
"length": "2592000"
},
{
"amount": [
{
"amount": "818755417400",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "21492138900",
"denom": "ukava"
}
],
"length": "2678400"
},
{
"amount": [
{
"amount": "21492138900",
"denom": "ukava"
}
],
"length": "2592000"
},
{
"amount": [
{
"amount": "194775729900",
"denom": "ukava"
}
],
"length": "2678400"
}
]
}
},
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": "3",
"address": "kava1r4v2zdhdalfj2ydazallqvrus9fkphmglhn6u6",
"coins": [
{
"amount": "9900",
"denom": "ukava"
}
],
"public_key": null,
"sequence": "1234"
}
},
{
"type": "cosmos-sdk/ModuleAccount",
"value": {
"account_number": "0",
"address": "kava1nzenvfcapyjr9qe3cr3c5k2aucssg6wnknlvll",
"coins": [
{
"denom": "hard",
"amount": "80000000000000"
}
],
"name": "harvest_lp_distribution",
"permissions": [
"minter",
"burner"
],
"public_key": "",
"sequence": "0"
}
},
{
"type": "cosmos-sdk/ModuleAccount",
"value": {
"account_number": "0",
"address": "kava1e3qvdzau5ww0m43d00gqj0ncgy8j03ndge6c2c",
"coins": [
{
"denom": "hard",
"amount": "40000000000000"
}
],
"name": "harvest_delegator_distribution",
"permissions": [
"minter",
"burner"
],
"public_key": "",
"sequence": "0"
}
},
{
"type": "cosmos-sdk/PeriodicVestingAccount",
"value": {
"address": "kava17a9m9zxs3r5zhxnultt5k5kyer0afd7kc8dq80",
"coins": [
{
"denom": "hard",
"amount": "20000000000000"
}
],
"public_key": null,
"account_number": "0",
"sequence": "0",
"original_vesting": [
{
"denom": "hard",
"amount": "20000000000000"
}
],
"delegated_free": [],
"delegated_vesting": [],
"end_time": "1697378400",
"start_time": "1602770400",
"vesting_periods": [
{
"length": "31536000",
"amount": [
{
"denom": "hard",
"amount": "6666666720000"
}
]
},
{
"length": "7948800",
"amount": [
{
"denom": "hard",
"amount": "1666666660000"
}
]
},
{
"length": "7776000",
"amount": [
{
"denom": "hard",
"amount": "1666666660000"
}
]
},
{
"length": "7862400",
"amount": [
{
"denom": "hard",
"amount": "1666666660000"
}
]
},
{
"length": "7948800",
"amount": [
{
"denom": "hard",
"amount": "1666666660000"
}
]
},
{
"length": "7948800",
"amount": [
{
"denom": "hard",
"amount": "1666666660000"
}
]
},
{
"length": "7776000",
"amount": [
{
"denom": "hard",
"amount": "1666666660000"
}
]
},
{
"length": "7862400",
"amount": [
{
"denom": "hard",
"amount": "1666666660000"
}
]
},
{
"length": "7948800",
"amount": [
{
"denom": "hard",
"amount": "1666666660000"
}
]
}
]
}
},
{
"type": "cosmos-sdk/PeriodicVestingAccount",
"value": {
"address": "kava1yqt02z2e4gpt4w0jnw9n0hnqyfu45afns669r2",
"coins": [
{
"denom": "hard",
"amount": "50000000000000"
}
],
"public_key": null,
"account_number": "0",
"sequence": "0",
"original_vesting": [
{
"denom": "hard",
"amount": "35000000000000"
}
],
"delegated_free": [],
"delegated_vesting": [],
"end_time": "1665842400",
"start_time": "1602770400",
"vesting_periods": [
{
"length": "7948800",
"amount": [
{
"denom": "hard",
"amount": "4375000000000"
}
]
},
{
"length": "7776000",
"amount": [
{
"denom": "hard",
"amount": "4375000000000"
}
]
},
{
"length": "7862400",
"amount": [
{
"denom": "hard",
"amount": "4375000000000"
}
]
},
{
"length": "7948800",
"amount": [
{
"denom": "hard",
"amount": "4375000000000"
}
]
},
{
"length": "7948800",
"amount": [
{
"denom": "hard",
"amount": "4375000000000"
}
]
},
{
"length": "7776000",
"amount": [
{
"denom": "hard",
"amount": "4375000000000"
}
]
},
{
"length": "7862400",
"amount": [
{
"denom": "hard",
"amount": "4375000000000"
}
]
},
{
"length": "7948800",
"amount": [
{
"denom": "hard",
"amount": "4375000000000"
}
]
}
]
}
},
{
"type": "cosmos-sdk/Account",
"value": {
"address": "kava16yapwtdxm5hkjfpeatr39vhu5c336fgf4utlyf",
"coins": [
{
"denom": "hard",
"amount": "10000000000000"
}
],
"public_key": null,
"account_number": "0",
"sequence": "0"
}
}
]
}

View File

@ -1,392 +0,0 @@
{
"params": {
"max_memo_characters": "512",
"sig_verify_cost_ed25519": "590",
"sig_verify_cost_secp256k1": "1000",
"tx_sig_limit": "7",
"tx_size_cost_per_byte": "10"
},
"accounts": [
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": 10145,
"address": "kava1llungtpe0aku8c2gqpm23jvs4r0caqdwjzq078",
"coins": [
{
"amount": "92810900",
"denom": "ukava"
}
],
"public_key": "",
"sequence": 0
}
},
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": 96,
"address": "kava1ceun2qqw65qce5la33j8zv8ltyyaqqfcxftutz",
"coins": [
{
"amount": "1095029582",
"denom": "ukava"
}
],
"public_key": "kavapub1ytql0csgqgfzd666axrjzqc4p3rlrz4ryut2v4r7m29hx6gx0h8pr52pvfzmw7r4dnurt9kctgfzd666axrjzqel670atjnfm8al2jjq7y69ttrjnw96uyqe83342g537mwvej67dqfzd666axrjzqkw686lp4ylpv29fv8t6hxxef5ln33a286a7507utmlc03hgyejsqfzd666axrjzqaa8j22fy52lpjgql0864qm9lqftadj3859z4q205d7xedn974suvfzd666axrjzq4ckxdsxywc0gqhfrxk39z058v3f3yuvmljsagdp2ggx89z5hru9gx07cnh",
"sequence": 8
}
},
{
"type": "cosmos-sdk/ValidatorVestingAccount",
"value": {
"account_number": 4,
"address": "kava1qzvq736hxfwdqgxwek3229z7ec4rfmc6s4kdc2",
"coins": [
{
"amount": "1829450",
"denom": "ukava"
}
],
"current_period_progress": {
"missed_blocks": 1540,
"total_blocks": 3468891
},
"debt_after_failed_vesting": [],
"delegated_free": [
{
"amount": "9990000",
"denom": "ukava"
}
],
"delegated_vesting": [
{
"amount": "333317710000",
"denom": "ukava"
}
],
"end_time": 1636120800,
"original_vesting": [
{
"amount": "333317710000",
"denom": "ukava"
}
],
"public_key": "kavapub1addwnpepq0v8zuz27x84jkjtpfaj9x840gsg8de23gd47vtq203ey7su6frcv5edh9v",
"return_address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"sequence": 24,
"signing_threshold": 90,
"start_time": 1572962400,
"validator_address": "kavavalcons16mkm6ggf280kjtsxnvzur7tnqttgavj4mzr4zf",
"vesting_period_progress": [
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
},
{
"period_complete": false,
"vesting_successful": false
}
],
"vesting_periods": [
{
"amount": [
{
"amount": "92588250185",
"denom": "ukava"
}
],
"length": 31622400
},
{
"amount": [
{
"amount": "60182345788",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "60182345788",
"denom": "ukava"
}
],
"length": 7689600
},
{
"amount": [
{
"amount": "60182345788",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "60182422451",
"denom": "ukava"
}
],
"length": 7948800
}
]
}
},
{
"type": "cosmos-sdk/PeriodicVestingAccount",
"value": {
"account_number": 159,
"address": "kava1qvsus5qg8yhre7k2c78xkkw4nvqqgev7ezrja8",
"coins": [
{
"amount": "899999001",
"denom": "bnb"
},
{
"amount": "2200212895",
"denom": "ukava"
},
{
"amount": "1004240",
"denom": "usdx"
}
],
"delegated_free": [],
"delegated_vesting": [
{
"amount": "4147313000000",
"denom": "ukava"
}
],
"end_time": 1636120800,
"original_vesting": [
{
"amount": "5177909376500",
"denom": "ukava"
}
],
"public_key": "kavapub1addwnpepqwg7wp0es6pg0vjgn4hkt8hdfa2yepfqdmp62aja76e3zd6lh22p6f9jte2",
"sequence": 184,
"start_time": 1572962400,
"vesting_periods": [
{
"amount": [
{
"amount": "247437068100",
"denom": "ukava"
}
],
"length": 7948800
},
{
"amount": [
{
"amount": "484707541700",
"denom": "ukava"
}
],
"length": 7776000
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": 2592000
},
{
"amount": [
{
"amount": "606688729200",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": 2592000
},
{
"amount": [
{
"amount": "760072166700",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": 2592000
},
{
"amount": [
{
"amount": "19235194400",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "910727972900",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "20971305600",
"denom": "ukava"
}
],
"length": 2419200
},
{
"amount": [
{
"amount": "20971305600",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "912464084000",
"denom": "ukava"
}
],
"length": 2592000
},
{
"amount": [
{
"amount": "20971305600",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "20971305600",
"denom": "ukava"
}
],
"length": 2592000
},
{
"amount": [
{
"amount": "818755417400",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "21492138900",
"denom": "ukava"
}
],
"length": 2678400
},
{
"amount": [
{
"amount": "21492138900",
"denom": "ukava"
}
],
"length": 2592000
},
{
"amount": [
{
"amount": "194775729900",
"denom": "ukava"
}
],
"length": 2678400
}
]
}
},
{
"type": "cosmos-sdk/Account",
"value": {
"account_number": 3,
"address": "kava1r4v2zdhdalfj2ydazallqvrus9fkphmglhn6u6",
"coins": [
{
"amount": "100200300",
"denom": "bnb"
},
{
"amount": "9900",
"denom": "ukava"
}
],
"public_key": "",
"sequence": 1234
}
}
]
}

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

View File

@ -1,157 +0,0 @@
{
"committees": [
{
"description": "Kava Stability Committee",
"id": "1",
"members": [
"kava1gru35up50ql2wxhegr880qy6ynl63ujlv8gum2",
"kava1sc3mh3pkas5e7xd269am4xm5mp6zweyzmhjagj",
"kava1c9ye54e3pzwm3e0zpdlel6pnavrj9qqv6e8r4h",
"kava1m7p6sjqrz6mylz776ct48wj6lpnpcd0z82209d",
"kava1a9pmkzk570egv3sflu3uwdf3gejl7qfy9hghzl"
],
"permissions": [
{
"type": "kava/SubParamChangePermission",
"value": {
"allowed_asset_params": [
{
"active": true,
"coin_id": false,
"denom": "bnb",
"limit": true
}
],
"allowed_collateral_params": [
{
"auction_size": true,
"conversion_factor": false,
"debt_limit": true,
"denom": "bnb",
"liquidation_market_id": false,
"liquidation_penalty": false,
"liquidation_ratio": false,
"prefix": false,
"spot_market_id": false,
"stability_fee": true
}
],
"allowed_debt_param": {
"conversion_factor": false,
"debt_floor": true,
"denom": false,
"reference_asset": false,
"savings_rate": true
},
"allowed_markets": [
{
"active": true,
"base_asset": false,
"market_id": "bnb:usd",
"oracles": false,
"quote_asset": false
},
{
"active": true,
"base_asset": false,
"market_id": "bnb:usd:30",
"oracles": false,
"quote_asset": false
}
],
"allowed_params": [
{
"key": "BidDuration",
"subspace": "auction"
},
{
"key": "IncrementSurplus",
"subspace": "auction"
},
{
"key": "IncrementDebt",
"subspace": "auction"
},
{
"key": "IncrementCollateral",
"subspace": "auction"
},
{
"key": "SupportedAssets",
"subspace": "bep3"
},
{
"key": "GlobalDebtLimit",
"subspace": "cdp"
},
{
"key": "SurplusThreshold",
"subspace": "cdp"
},
{
"key": "SurplusLot",
"subspace": "cdp"
},
{
"key": "DebtThreshold",
"subspace": "cdp"
},
{
"key": "DebtLot",
"subspace": "cdp"
},
{
"key": "DistributionFrequency",
"subspace": "cdp"
},
{
"key": "CollateralParams",
"subspace": "cdp"
},
{
"key": "DebtParam",
"subspace": "cdp"
},
{
"key": "Active",
"subspace": "incentive"
},
{
"key": "Active",
"subspace": "kavadist"
},
{
"key": "Markets",
"subspace": "pricefeed"
}
]
}
},
{
"type": "kava/TextPermission",
"value": {}
}
],
"proposal_duration": "604800000000000",
"vote_threshold": "0.500000000000000000"
},
{
"description": "Kava Safety Committee",
"id": "2",
"members": [
"kava1e0agyg6eug9r62fly9sls77ycjgw8ax6xk73es"
],
"permissions": [
{
"type": "kava/SoftwareUpgradePermission",
"value": {}
}
],
"proposal_duration": "604800000000000",
"vote_threshold": "0.500000000000000000"
}
],
"next_proposal_id": "27",
"proposals": [],
"votes": []
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,152 +0,0 @@
{
"params": {
"markets": [
{
"active": true,
"base_asset": "bnb",
"market_id": "bnb:usd",
"oracles": [
"kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl",
"kava1tuxyepdrkwraa22k99w04c0wa64tgh70mv87fs",
"kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg",
"kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl",
"kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp",
"kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj",
"kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
"kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn",
"kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy",
"kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh"
],
"quote_asset": "usd"
},
{
"active": true,
"base_asset": "bnb",
"market_id": "bnb:usd:30",
"oracles": [
"kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl",
"kava1tuxyepdrkwraa22k99w04c0wa64tgh70mv87fs",
"kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg",
"kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl",
"kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp",
"kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj",
"kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
"kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn",
"kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy",
"kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh"
],
"quote_asset": "usd"
}
]
},
"posted_prices": [
{
"expiry": "2020-08-19T06:14:00Z",
"market_id": "bnb:usd",
"oracle_address": "kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
"price": "22.925799999999998846"
},
{
"expiry": "2020-08-19T06:14:00Z",
"market_id": "bnb:usd",
"oracle_address": "kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy",
"price": "22.932800000000000296"
},
{
"expiry": "2020-07-28T07:30:00Z",
"market_id": "bnb:usd",
"oracle_address": "kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp",
"price": "20.084499999999998465"
},
{
"expiry": "2020-08-19T06:14:00Z",
"market_id": "bnb:usd",
"oracle_address": "kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg",
"price": "22.932800000000000296"
},
{
"expiry": "2020-08-19T06:22:00Z",
"market_id": "bnb:usd",
"oracle_address": "kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj",
"price": "22.866299999999998960"
},
{
"expiry": "2020-08-19T06:14:01Z",
"market_id": "bnb:usd",
"oracle_address": "kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl",
"price": "22.932800000000000296"
},
{
"expiry": "2020-08-19T06:14:00Z",
"market_id": "bnb:usd",
"oracle_address": "kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn",
"price": "22.932800000000000296"
},
{
"expiry": "2020-08-19T06:28:00Z",
"market_id": "bnb:usd",
"oracle_address": "kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh",
"price": "22.836200000000001609"
},
{
"expiry": "2020-08-19T06:29:31Z",
"market_id": "bnb:usd",
"oracle_address": "kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl",
"price": "22.834499999999998465"
},
{
"expiry": "2020-08-19T06:25:00Z",
"market_id": "bnb:usd:30",
"oracle_address": "kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
"price": "22.967586666666665707"
},
{
"expiry": "2020-08-19T06:24:00Z",
"market_id": "bnb:usd:30",
"oracle_address": "kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy",
"price": "22.972826666666666284"
},
{
"expiry": "2020-08-19T06:22:30Z",
"market_id": "bnb:usd:30",
"oracle_address": "kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg",
"price": "22.980756666666668053"
},
{
"expiry": "2020-07-28T08:30:00Z",
"market_id": "bnb:usd:30",
"oracle_address": "kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp",
"price": "20.056519999999995463"
},
{
"expiry": "2020-08-19T06:25:00Z",
"market_id": "bnb:usd:30",
"oracle_address": "kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj",
"price": "22.967586666666665707"
},
{
"expiry": "2020-08-19T06:25:00Z",
"market_id": "bnb:usd:30",
"oracle_address": "kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl",
"price": "22.967586666666665707"
},
{
"expiry": "2020-08-19T06:25:00Z",
"market_id": "bnb:usd:30",
"oracle_address": "kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn",
"price": "22.967586666666665707"
},
{
"expiry": "2020-08-19T06:22:00Z",
"market_id": "bnb:usd:30",
"oracle_address": "kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh",
"price": "22.972629999999998773"
},
{
"expiry": "2020-08-19T06:24:31Z",
"market_id": "bnb:usd:30",
"oracle_address": "kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl",
"price": "22.967533333333335577"
}
]
}

View File

@ -1,697 +0,0 @@
package v0_14
import (
"fmt"
"sort"
"time"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/supply"
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/x/bep3"
v0_14cdp "github.com/kava-labs/kava/x/cdp"
v0_11cdp "github.com/kava-labs/kava/x/cdp/legacy/v0_11"
v0_11committee "github.com/kava-labs/kava/x/committee/legacy/v0_11"
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
v0_14hard "github.com/kava-labs/kava/x/hard"
v0_11hard "github.com/kava-labs/kava/x/hard/legacy/v0_11"
v0_11incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_11"
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
"github.com/kava-labs/kava/x/kavadist"
v0_11pricefeed "github.com/kava-labs/kava/x/pricefeed"
v0_14pricefeed "github.com/kava-labs/kava/x/pricefeed"
validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
)
var (
GenesisTime = time.Date(2021, 4, 8, 15, 0, 0, 0, time.UTC)
RewardEndTime = time.Date(2022, 4, 8, 14, 0, 0, 0, time.UTC)
ClaimEndTime = time.Date(2026, 4, 8, 14, 0, 0, 0, time.UTC)
)
// Migrate translates a genesis file from kava v0.11 (or v0.12) format to kava v0.13.x format.
func Migrate(genDoc tmtypes.GenesisDoc) tmtypes.GenesisDoc {
// migrate app state
var appStateMap genutil.AppMap
cdc := codec.New()
cryptoAmino.RegisterAmino(cdc)
tmtypes.RegisterEvidences(cdc)
if err := cdc.UnmarshalJSON(genDoc.AppState, &appStateMap); err != nil {
panic(err)
}
newAppState := MigrateAppState(appStateMap)
v0_14Codec := app.MakeCodec()
marshaledNewAppState, err := v0_14Codec.MarshalJSON(newAppState)
if err != nil {
panic(err)
}
genDoc.AppState = marshaledNewAppState
genDoc.GenesisTime = GenesisTime
genDoc.ChainID = "kava-7"
genDoc.ConsensusParams.Block.MaxGas = 20000000
return genDoc
}
// MigrateAppState migrates application state from v0.11 (or v0.12) format to a kava v0.13.x format
func MigrateAppState(v0_11AppState genutil.AppMap) genutil.AppMap {
v0_14AppState := v0_11AppState
cdc := app.MakeCodec()
var hardGenState v0_11hard.GenesisState
if v0_11AppState[v0_14hard.ModuleName] == nil {
cdc.MustUnmarshalJSON(v0_11AppState[v0_11hard.ModuleName], &hardGenState)
delete(v0_11AppState, v0_11hard.ModuleName)
v0_14AppState[v0_14hard.ModuleName] = cdc.MustMarshalJSON(
Hard(hardGenState))
}
delete(v0_14AppState, v0_11hard.ModuleName)
if v0_11AppState[v0_11cdp.ModuleName] != nil {
var cdpGenState v0_11cdp.GenesisState
cdc.MustUnmarshalJSON(v0_11AppState[v0_11cdp.ModuleName], &cdpGenState)
delete(v0_11AppState, v0_11cdp.ModuleName)
v0_14AppState[v0_14cdp.ModuleName] = cdc.MustMarshalJSON(
CDP(cdpGenState))
}
if v0_11AppState[v0_11incentive.ModuleName] != nil {
var incentiveGenState v0_11incentive.GenesisState
cdc.MustUnmarshalJSON(v0_11AppState[v0_14incentive.ModuleName], &incentiveGenState)
delete(v0_11AppState, v0_11incentive.ModuleName)
v0_14AppState[v0_14incentive.ModuleName] = cdc.MustMarshalJSON(Incentive(hardGenState, incentiveGenState))
}
if v0_11AppState[v0_11pricefeed.ModuleName] != nil {
var pricefeedGS v0_11pricefeed.GenesisState
cdc.MustUnmarshalJSON(v0_11AppState[v0_14pricefeed.ModuleName], &pricefeedGS)
delete(v0_11AppState, v0_11pricefeed.ModuleName)
v0_14AppState[v0_14pricefeed.ModuleName] = cdc.MustMarshalJSON(Pricefeed(pricefeedGS))
}
if v0_11AppState[bep3.ModuleName] != nil {
var bep3GS bep3.GenesisState
cdc.MustUnmarshalJSON(v0_11AppState[bep3.ModuleName], &bep3GS)
delete(v0_11AppState, bep3.ModuleName)
v0_14AppState[bep3.ModuleName] = cdc.MustMarshalJSON(Bep3(bep3GS))
}
if v0_11AppState[v0_11committee.ModuleName] != nil {
var committeeGS v0_11committee.GenesisState
cdc := codec.New()
sdk.RegisterCodec(cdc)
v0_11committee.RegisterCodec(cdc)
cdc.MustUnmarshalJSON(v0_11AppState[v0_11committee.ModuleName], &committeeGS)
delete(v0_11AppState, v0_11committee.ModuleName)
cdc = app.MakeCodec()
v0_14AppState[v0_14committee.ModuleName] = cdc.MustMarshalJSON(Committee(committeeGS))
}
if v0_11AppState[auth.ModuleName] != nil {
var authGS auth.GenesisState
cdc.MustUnmarshalJSON(v0_11AppState[auth.ModuleName], &authGS)
delete(v0_11AppState, auth.ModuleName)
v0_14AppState[auth.ModuleName] = cdc.MustMarshalJSON(Auth(authGS))
}
return v0_14AppState
}
// CDP migrates from a v0.11 cdp genesis state to a v0.13 cdp genesis state
func CDP(oldGenState v0_11cdp.GenesisState) v0_14cdp.GenesisState {
var newCDPs v0_14cdp.CDPs
var newDeposits v0_14cdp.Deposits
var newCollateralParams v0_14cdp.CollateralParams
var newGenesisAccumulationTimes v0_14cdp.GenesisAccumulationTimes
var previousAccumulationTime time.Time
var totalPrincipals v0_14cdp.GenesisTotalPrincipals
newStartingID := oldGenState.StartingCdpID
totalPrincipalMap := make(map[string]sdk.Int)
for _, cdp := range oldGenState.CDPs {
newCDP := v0_14cdp.NewCDPWithFees(cdp.ID, cdp.Owner, cdp.Collateral, cdp.Type, cdp.Principal, cdp.AccumulatedFees, cdp.FeesUpdated, sdk.OneDec())
if previousAccumulationTime.Before(cdp.FeesUpdated) {
previousAccumulationTime = cdp.FeesUpdated
}
_, found := totalPrincipalMap[cdp.Type]
if !found {
totalPrincipalMap[cdp.Type] = sdk.ZeroInt()
}
totalPrincipalMap[cdp.Type] = totalPrincipalMap[cdp.Type].Add(newCDP.GetTotalPrincipal().Amount)
newCDPs = append(newCDPs, newCDP)
}
for _, cp := range oldGenState.Params.CollateralParams {
newCollateralParam := v0_14cdp.NewCollateralParam(cp.Denom, cp.Type, cp.LiquidationRatio, cp.DebtLimit, cp.StabilityFee, cp.AuctionSize, cp.LiquidationPenalty, cp.Prefix, cp.SpotMarketID, cp.LiquidationMarketID, sdk.MustNewDecFromStr("0.01"), sdk.NewInt(10), cp.ConversionFactor)
newCollateralParams = append(newCollateralParams, newCollateralParam)
newGenesisAccumulationTime := v0_14cdp.NewGenesisAccumulationTime(cp.Type, previousAccumulationTime, sdk.OneDec())
newGenesisAccumulationTimes = append(newGenesisAccumulationTimes, newGenesisAccumulationTime)
}
for _, dep := range oldGenState.Deposits {
newDep := v0_14cdp.NewDeposit(dep.CdpID, dep.Depositor, dep.Amount)
newDeposits = append(newDeposits, newDep)
}
for ctype, tp := range totalPrincipalMap {
totalPrincipal := v0_14cdp.NewGenesisTotalPrincipal(ctype, tp)
totalPrincipals = append(totalPrincipals, totalPrincipal)
}
sort.Slice(totalPrincipals, func(i, j int) bool { return totalPrincipals[i].CollateralType < totalPrincipals[j].CollateralType })
oldDebtParam := oldGenState.Params.DebtParam
newDebtParam := v0_14cdp.NewDebtParam(oldDebtParam.Denom, oldDebtParam.ReferenceAsset, oldDebtParam.ConversionFactor, oldDebtParam.DebtFloor)
newGlobalDebtLimit := oldGenState.Params.GlobalDebtLimit
newParams := v0_14cdp.NewParams(newGlobalDebtLimit, newCollateralParams, newDebtParam, oldGenState.Params.SurplusAuctionThreshold, oldGenState.Params.SurplusAuctionLot, oldGenState.Params.DebtAuctionThreshold, oldGenState.Params.DebtAuctionLot, false)
return v0_14cdp.NewGenesisState(
newParams,
newCDPs,
newDeposits,
newStartingID,
oldGenState.DebtDenom,
oldGenState.GovDenom,
newGenesisAccumulationTimes,
totalPrincipals,
)
}
// Hard migrates from a v0.11 hard (harvest) genesis state to a v0.13 hard genesis state
func Hard(genesisState v0_11hard.GenesisState) v0_14hard.GenesisState {
v13Deposits := v0_14hard.Deposits{}
v13DepositorMap := make(map[string]v0_14hard.Deposit)
v13GenesisAccumulationTimes := v0_14hard.GenesisAccumulationTimes{}
v13TotalSupplied := sdk.NewCoins()
for _, dep := range genesisState.Deposits {
v13Deposit, ok := v13DepositorMap[dep.Depositor.String()]
if !ok {
v13Deposit := v0_14hard.NewDeposit(dep.Depositor, sdk.NewCoins(dep.Amount), v0_14hard.SupplyInterestFactors{v0_14hard.NewSupplyInterestFactor(dep.Amount.Denom, sdk.OneDec())})
v13DepositorMap[dep.Depositor.String()] = v13Deposit
} else {
v13Deposit.Amount = v13Deposit.Amount.Add(dep.Amount)
v13Deposit.Index = append(v13Deposit.Index, v0_14hard.NewSupplyInterestFactor(dep.Amount.Denom, sdk.OneDec()))
v13DepositorMap[dep.Depositor.String()] = v13Deposit
}
}
defaultInterestModel := v0_14hard.NewInterestRateModel(sdk.ZeroDec(), sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("1.0"))
newParams := v0_14hard.NewParams(
v0_14hard.MoneyMarkets{
v0_14hard.NewMoneyMarket("btcb", v0_14hard.NewBorrowLimit(true, sdk.ZeroDec(), sdk.MustNewDecFromStr("0.5")), "btc:usd", sdk.NewInt(100000000),
defaultInterestModel,
sdk.MustNewDecFromStr("0.025"), sdk.MustNewDecFromStr("0.02"),
),
// bnb
v0_14hard.NewMoneyMarket("bnb", v0_14hard.NewBorrowLimit(true, sdk.ZeroDec(), sdk.MustNewDecFromStr("0.5")), "bnb:usd", sdk.NewInt(100000000),
defaultInterestModel,
sdk.MustNewDecFromStr("0.025"), sdk.MustNewDecFromStr("0.02"),
),
// xrpb
v0_14hard.NewMoneyMarket("xrpb", v0_14hard.NewBorrowLimit(true, sdk.ZeroDec(), sdk.MustNewDecFromStr("0.5")), "xrp:usd", sdk.NewInt(100000000),
defaultInterestModel,
sdk.MustNewDecFromStr("0.025"), sdk.MustNewDecFromStr("0.02"),
),
// busd
v0_14hard.NewMoneyMarket("busd", v0_14hard.NewBorrowLimit(true, sdk.MustNewDecFromStr("100000000000000"), sdk.MustNewDecFromStr("0.5")), "busd:usd", sdk.NewInt(100000000),
defaultInterestModel,
sdk.MustNewDecFromStr("0.025"), sdk.MustNewDecFromStr("0.02"),
),
// usdx
v0_14hard.NewMoneyMarket("usdx", v0_14hard.NewBorrowLimit(true, sdk.ZeroDec(), sdk.ZeroDec()), "usdx:usd", sdk.NewInt(1000000),
defaultInterestModel,
sdk.MustNewDecFromStr("0.025"), sdk.MustNewDecFromStr("0.02"),
),
// ukava
v0_14hard.NewMoneyMarket("ukava", v0_14hard.NewBorrowLimit(true, sdk.ZeroDec(), sdk.MustNewDecFromStr("0.5")), "kava:usd", sdk.NewInt(1000000),
defaultInterestModel,
sdk.MustNewDecFromStr("0.025"), sdk.MustNewDecFromStr("0.02"),
),
// hard
v0_14hard.NewMoneyMarket("hard", v0_14hard.NewBorrowLimit(true, sdk.ZeroDec(), sdk.MustNewDecFromStr("0.5")), "hard:usd", sdk.NewInt(1000000),
defaultInterestModel,
sdk.MustNewDecFromStr("0.025"), sdk.MustNewDecFromStr("0.02"),
),
},
sdk.MustNewDecFromStr("10.0"),
)
for _, newDep := range v13DepositorMap {
v13Deposits = append(v13Deposits, newDep)
v13TotalSupplied = v13TotalSupplied.Add(newDep.Amount...)
}
sort.Slice(v13Deposits, func(i, j int) bool {
return v13Deposits[i].Depositor.String() > v13Deposits[j].Depositor.String()
})
for _, mm := range newParams.MoneyMarkets {
genAccumulationTime := v0_14hard.NewGenesisAccumulationTime(mm.Denom, GenesisTime, sdk.OneDec(), sdk.OneDec())
v13GenesisAccumulationTimes = append(v13GenesisAccumulationTimes, genAccumulationTime)
}
return v0_14hard.NewGenesisState(newParams, v13GenesisAccumulationTimes, v13Deposits, v0_14hard.DefaultBorrows, v13TotalSupplied, v0_14hard.DefaultTotalBorrowed, v0_14hard.DefaultTotalReserves)
}
// Incentive migrates from a v0.11 incentive genesis state to a v0.13 incentive genesis state
func Incentive(hardGS v0_11hard.GenesisState, incentiveGS v0_11incentive.GenesisState) v0_14incentive.GenesisState {
usdxMintingRewardPeriods := v0_14incentive.RewardPeriods{}
usdxRewardsPerSecondMap := make(map[string]sdk.Coin)
usdxRewardsPerSecondMap["bnb-a"] = sdk.NewCoin("ukava", sdk.NewInt(122354))
usdxRewardsPerSecondMap["btcb-a"] = sdk.NewCoin("ukava", sdk.NewInt(110780))
usdxRewardsPerSecondMap["busd-a"] = sdk.NewCoin("ukava", sdk.NewInt(30588))
usdxRewardsPerSecondMap["hard-a"] = sdk.NewCoin("ukava", sdk.NewInt(23809))
usdxRewardsPerSecondMap["ukava-a"] = sdk.NewCoin("ukava", sdk.NewInt(31746))
usdxRewardsPerSecondMap["xrpb-a"] = sdk.NewCoin("ukava", sdk.NewInt(31746))
usdxRewardsPerSecondMap["hbtc-a"] = sdk.NewCoin("ukava", sdk.NewInt(79365))
for _, rp := range incentiveGS.RewardPeriods {
rewardsPerSecond, ok := usdxRewardsPerSecondMap[rp.CollateralType]
if !ok {
panic(fmt.Sprintf("No rewards per second for collateral type: %s\n", rp.CollateralType))
}
newRP := v0_14incentive.NewRewardPeriod(true, rp.CollateralType, GenesisTime, RewardEndTime, rewardsPerSecond)
usdxMintingRewardPeriods = append(usdxMintingRewardPeriods, newRP)
}
hardSupplyRewardPeriods := v0_14incentive.MultiRewardPeriods{}
for _, rp := range hardGS.Params.LiquidityProviderSchedules {
newRP := v0_14incentive.NewMultiRewardPeriod(true, rp.DepositDenom, rp.Start, rp.End, sdk.NewCoins(rp.RewardsPerSecond))
hardSupplyRewardPeriods = append(hardSupplyRewardPeriods, newRP)
}
hardBorrowRewardPeriods := v0_14incentive.MultiRewardPeriods{}
hardDelegatorRewardPeriods := v0_14incentive.RewardPeriods{}
for _, rp := range hardGS.Params.DelegatorDistributionSchedules {
newRP := v0_14incentive.NewRewardPeriod(rp.DistributionSchedule.Active, rp.DistributionSchedule.DepositDenom, rp.DistributionSchedule.Start, rp.DistributionSchedule.End, rp.DistributionSchedule.RewardsPerSecond)
hardDelegatorRewardPeriods = append(hardDelegatorRewardPeriods, newRP)
}
params := v0_14incentive.NewParams(usdxMintingRewardPeriods, hardSupplyRewardPeriods, hardBorrowRewardPeriods, hardDelegatorRewardPeriods, v0_14incentive.Multipliers{v0_14incentive.NewMultiplier(v0_14incentive.Small, 1, sdk.MustNewDecFromStr("0.2")), v0_14incentive.NewMultiplier(v0_14incentive.Large, 12, sdk.MustNewDecFromStr("1.0"))}, ClaimEndTime)
usdxGenAccumulationTimes := v0_14incentive.GenesisAccumulationTimes{}
for _, rp := range params.USDXMintingRewardPeriods {
gat := v0_14incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime)
usdxGenAccumulationTimes = append(usdxGenAccumulationTimes, gat)
}
hardSupplyGenAccumulationTimes := v0_14incentive.GenesisAccumulationTimes{}
for _, rp := range params.HardSupplyRewardPeriods {
gat := v0_14incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime)
hardSupplyGenAccumulationTimes = append(hardSupplyGenAccumulationTimes, gat)
}
hardBorrowGenAccumulationTimes := v0_14incentive.GenesisAccumulationTimes{}
for _, rp := range params.HardBorrowRewardPeriods {
gat := v0_14incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime)
hardBorrowGenAccumulationTimes = append(hardBorrowGenAccumulationTimes, gat)
}
hardDelegatorGenAccumulationTimes := v0_14incentive.GenesisAccumulationTimes{}
for _, rp := range params.HardDelegatorRewardPeriods {
gat := v0_14incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime)
hardDelegatorGenAccumulationTimes = append(hardDelegatorGenAccumulationTimes, gat)
}
usdxClaims := v0_14incentive.USDXMintingClaims{}
usdxClaimMap := make(map[string]v0_14incentive.USDXMintingClaim)
claimEndMap := make(map[uint64]time.Time)
for _, cp := range incentiveGS.ClaimPeriods {
claimEndMap[cp.ID] = cp.End
}
for _, claim := range incentiveGS.Claims {
if claimEndMap[claim.ClaimPeriodID].Before(GenesisTime) {
continue
}
newClaim, ok := usdxClaimMap[claim.Owner.String()]
if !ok {
newClaim = v0_14incentive.NewUSDXMintingClaim(claim.Owner, claim.Reward, v0_14incentive.RewardIndexes{v0_14incentive.NewRewardIndex(claim.CollateralType, sdk.ZeroDec())})
} else {
newClaim.Reward = newClaim.Reward.Add(claim.Reward)
_, found := newClaim.RewardIndexes.GetRewardIndex(claim.CollateralType)
if !found {
newClaim.RewardIndexes = append(newClaim.RewardIndexes, v0_14incentive.NewRewardIndex(claim.CollateralType, sdk.ZeroDec()))
}
}
usdxClaimMap[newClaim.Owner.String()] = newClaim
}
for _, claim := range usdxClaimMap {
usdxClaims = append(usdxClaims, claim)
}
hardClaims := v0_14incentive.HardLiquidityProviderClaims{}
hardClaimMap := make(map[string]v0_14incentive.HardLiquidityProviderClaim)
for _, claim := range hardGS.Claims {
newClaim, ok := hardClaimMap[claim.Owner.String()]
if !ok {
// if claim.Type == "lp" -- hard supply
// if claim.Type == "stake" -- hard delegator
// hard barrow always empty
delegatorIndexes := v0_14incentive.RewardIndexes{}
supplyIndexes := v0_14incentive.MultiRewardIndexes{}
borrowIndexes := v0_14incentive.MultiRewardIndexes{}
if claim.Type == v0_11hard.Stake {
delegatorIndexes = v0_14incentive.RewardIndexes{v0_14incentive.NewRewardIndex(claim.DepositDenom, sdk.ZeroDec())}
}
if claim.Type == v0_11hard.LP {
supplyIndexes = v0_14incentive.MultiRewardIndexes{v0_14incentive.NewMultiRewardIndex(claim.DepositDenom, v0_14incentive.RewardIndexes{v0_14incentive.NewRewardIndex("hard", sdk.ZeroDec())})}
}
newClaim = v0_14incentive.NewHardLiquidityProviderClaim(claim.Owner, sdk.NewCoins(claim.Amount), supplyIndexes, borrowIndexes, delegatorIndexes)
} else {
newClaim.Reward = newClaim.Reward.Add(claim.Amount)
if claim.Type == v0_11hard.Stake {
newClaim.DelegatorRewardIndexes = v0_14incentive.RewardIndexes{v0_14incentive.NewRewardIndex(claim.DepositDenom, sdk.ZeroDec())}
}
if claim.Type == v0_11hard.LP {
_, found := newClaim.SupplyRewardIndexes.GetRewardIndex(claim.DepositDenom)
if !found {
newClaim.SupplyRewardIndexes = append(newClaim.SupplyRewardIndexes, v0_14incentive.NewMultiRewardIndex(claim.DepositDenom, v0_14incentive.RewardIndexes{v0_14incentive.NewRewardIndex("hard", sdk.ZeroDec())}))
}
}
}
hardClaimMap[claim.Owner.String()] = newClaim
}
for _, claim := range hardClaimMap {
hardClaims = append(hardClaims, claim)
}
sort.Slice(hardClaims, func(i, j int) bool { return hardClaims[i].Owner.String() < hardClaims[j].Owner.String() })
sort.Slice(usdxClaims, func(i, j int) bool { return usdxClaims[i].Owner.String() < usdxClaims[j].Owner.String() })
return v0_14incentive.NewGenesisState(
params,
usdxGenAccumulationTimes,
hardSupplyGenAccumulationTimes,
hardBorrowGenAccumulationTimes,
hardDelegatorGenAccumulationTimes,
usdxClaims,
hardClaims,
)
}
// Auth migrates from a v0.11 auth genesis state to a v0.13
func Auth(genesisState auth.GenesisState) auth.GenesisState {
validatorVestingChangeAddress, err := sdk.AccAddressFromBech32("kava1a3qmze57knfj29a5knqs5ptewh76v4fg23xsvn")
if err != nil {
panic(err)
}
validatorVestingUpdatedValAddress, err := sdk.ConsAddressFromBech32("kavavalcons1ucxhn6zh7y2zun49m36psjffrhmux7ukqxdcte")
if err != nil {
panic(err)
}
savingsRateMaccCoins := sdk.NewCoins()
savingsMaccAddr := supply.NewModuleAddress(v0_11cdp.SavingsRateMacc)
savingsRateMaccIndex := 0
liquidatorMaccIndex := 0
// moves hard distributions from hard module account to kavadist module account
hardDelegatorAddr := supply.NewModuleAddress(v0_11hard.DelegatorAccount)
hardDelegatorIdx := 0
hardDelegatorCoins := sdk.NewCoins()
hardLPAddr := supply.NewModuleAddress(v0_11hard.LPAccount)
hardLPIdx := 0
hardLPCoins := sdk.NewCoins()
harvestAddr := supply.NewModuleAddress(v0_11hard.ModuleAccountName)
harvestIdx := 0
kavaDistAddr := supply.NewModuleAddress(kavadist.KavaDistMacc)
kavaDistIdx := 0
for idx, acc := range genesisState.Accounts {
// reset validator vesting missed blocks to zero (due to ongoing network issues in kava-4)
vvacc, ok := acc.(*validatorvesting.ValidatorVestingAccount)
if ok {
vvacc.CurrentPeriodProgress.MissedBlocks = 0
if vvacc.GetAddress().Equals(validatorVestingChangeAddress) {
// update validator vesting validator address for shiprekt
vvacc.ValidatorAddress = validatorVestingUpdatedValAddress
}
}
if acc.GetAddress().Equals(savingsMaccAddr) {
savingsRateMaccCoins = acc.GetCoins()
savingsRateMaccIndex = idx
err := acc.SetCoins(acc.GetCoins().Sub(acc.GetCoins()))
if err != nil {
panic(err)
}
}
if acc.GetAddress().Equals(supply.NewModuleAddress(v0_14cdp.LiquidatorMacc)) {
liquidatorMaccIndex = idx
}
if acc.GetAddress().Equals(hardDelegatorAddr) {
hardDelegatorIdx = idx
hardDelegatorCoins = acc.GetCoins()
}
if acc.GetAddress().Equals(hardLPAddr) {
hardLPIdx = idx
hardLPCoins = acc.GetCoins()
}
if acc.GetAddress().Equals(kavaDistAddr) {
kavaDistIdx = idx
}
if acc.GetAddress().Equals(harvestAddr) {
harvestIdx = idx
}
}
// move remaining cdp savings to liquidator account
liquidatorAcc := genesisState.Accounts[liquidatorMaccIndex]
err = liquidatorAcc.SetCoins(liquidatorAcc.GetCoins().Add(savingsRateMaccCoins...))
if err != nil {
panic(err)
}
genesisState.Accounts[liquidatorMaccIndex] = liquidatorAcc
// migrate harvest account to new hard name
harvestAcc := genesisState.Accounts[harvestIdx].(*supply.ModuleAccount)
harvestAcc.Address = supply.NewModuleAddress(v0_14hard.ModuleAccountName)
harvestAcc.Name = v0_14hard.ModuleAccountName
harvestAcc.Permissions = []string{supply.Minter}
genesisState.Accounts[harvestIdx] = harvestAcc
// add hard module accounts to kavadist
kavaDistAcc := genesisState.Accounts[kavaDistIdx]
err = kavaDistAcc.SetCoins(kavaDistAcc.GetCoins().Add(hardDelegatorCoins...).Add(hardLPCoins...))
if err != nil {
panic(err)
}
genesisState.Accounts[kavaDistIdx] = kavaDistAcc
// reverse sort indexes of accounts to remove so that re-numbering is irrelevant
indexesToRemove := []int{savingsRateMaccIndex, hardDelegatorIdx, hardLPIdx}
sort.Slice(indexesToRemove, func(i, j int) bool { return indexesToRemove[i] > indexesToRemove[j] })
// delete hard delegator, hard lp, and savings rate module accounts
for _, idx := range indexesToRemove {
genesisState.Accounts = removeIndex(genesisState.Accounts, idx)
}
return genesisState
}
// Bep3 migrates a v0.11 bep3 genesis state to a v0.13 genesis state
func Bep3(genesisState bep3.GenesisState) bep3.GenesisState {
var newSupplies bep3.AssetSupplies
for _, supply := range genesisState.Supplies {
if supply.GetDenom() == "bnb" {
supply.CurrentSupply = supply.CurrentSupply.Sub(sdk.NewCoin("bnb", sdk.NewInt(1000000000000)))
}
newSupplies = append(newSupplies, supply)
}
var newSwaps bep3.AtomicSwaps
for _, swap := range genesisState.AtomicSwaps {
if swap.Status == bep3.Completed {
swap.ClosedBlock = 1 // reset closed block to one so completed swaps are removed from long term storage properly
}
if swap.Status == bep3.Open || swap.Status == bep3.Expired {
swap.Status = bep3.Expired // set open swaps to expired so they can be refunded after chain start
swap.ExpireHeight = 1 // set expire on first block as well to be safe
}
newSwaps = append(newSwaps, swap)
}
var newAssetParams bep3.AssetParams
for _, ap := range genesisState.Params.AssetParams {
ap.MinBlockLock = uint64(24686)
ap.MaxBlockLock = uint64(86400)
newAssetParams = append(newAssetParams, ap)
}
newParams := bep3.NewParams(newAssetParams)
return bep3.NewGenesisState(newParams, newSwaps, newSupplies, genesisState.PreviousBlockTime)
}
// Committee migrates from a v0.11 (or v0.12) committee genesis state to a v0.13 committee genesis state
func Committee(genesisState v0_11committee.GenesisState) v0_14committee.GenesisState {
committees := []v0_14committee.Committee{}
votes := []v0_14committee.Vote{}
proposals := []v0_14committee.Proposal{}
var newStabilityCommittee v0_14committee.Committee
var newSafetyCommittee v0_14committee.Committee
for _, com := range genesisState.Committees {
if com.ID == 1 {
newStabilityCommittee.Description = com.Description
newStabilityCommittee.ID = com.ID
newStabilityCommittee.Members = com.Members
newStabilityCommittee.VoteThreshold = com.VoteThreshold
newStabilityCommittee.ProposalDuration = com.ProposalDuration
var newStabilityCommitteePermissions []v0_14committee.Permission
var newStabilitySubParamPermissions v0_14committee.SubParamChangePermission
for _, perm := range com.Permissions {
subPerm, ok := perm.(v0_11committee.SubParamChangePermission)
if ok {
// update AllowedParams
var newAllowedParams v0_14committee.AllowedParams
for _, ap := range subPerm.AllowedParams {
if ap.Subspace == "harvest" {
continue
}
newAP := v0_14committee.AllowedParam(ap)
newAllowedParams = append(newAllowedParams, newAP)
}
hrdaMMAp := v0_14committee.AllowedParam{Subspace: "hard", Key: "MoneyMarkets"}
hardLimitAp := v0_14committee.AllowedParam{Subspace: "hard", Key: "MinimumBorrowUSDValue"}
newAllowedParams = append(newAllowedParams, hrdaMMAp)
newAllowedParams = append(newAllowedParams, hardLimitAp)
newStabilitySubParamPermissions.AllowedParams = newAllowedParams
// update AllowedCollateralParams
var newCollateralParams v0_14committee.AllowedCollateralParams
collateralTypes := []string{"bnb-a", "busd-a", "busd-b", "btcb-a", "xrpb-a", "ukava-a", "hard-a", "hbtc-a"}
for _, cp := range subPerm.AllowedCollateralParams {
newCP := v0_14committee.NewAllowedCollateralParam(
cp.Type,
cp.Denom,
cp.LiquidationRatio,
cp.DebtLimit,
cp.StabilityFee,
cp.AuctionSize,
cp.LiquidationPenalty,
cp.Prefix,
cp.SpotMarketID,
cp.LiquidationMarketID,
cp.ConversionFactor,
true,
true,
)
newCollateralParams = append(newCollateralParams, newCP)
}
for _, cType := range collateralTypes {
var foundCtype bool
for _, cp := range newCollateralParams {
if cType == cp.Type {
foundCtype = true
}
}
if !foundCtype {
newCP := v0_14committee.NewAllowedCollateralParam(cType, false, false, true, true, true, false, false, false, false, false, true, true)
newCollateralParams = append(newCollateralParams, newCP)
}
}
newStabilitySubParamPermissions.AllowedCollateralParams = newCollateralParams
// update AllowedDebtParam
newDP := v0_14committee.AllowedDebtParam{
Denom: subPerm.AllowedDebtParam.Denom,
ReferenceAsset: subPerm.AllowedDebtParam.ReferenceAsset,
ConversionFactor: subPerm.AllowedDebtParam.ConversionFactor,
DebtFloor: subPerm.AllowedDebtParam.DebtFloor,
}
newStabilitySubParamPermissions.AllowedDebtParam = newDP
// update AllowedAssetParams
var newAssetParams v0_14committee.AllowedAssetParams
for _, ap := range subPerm.AllowedAssetParams {
newAP := v0_14committee.AllowedAssetParam(ap)
newAssetParams = append(newAssetParams, newAP)
}
newStabilitySubParamPermissions.AllowedAssetParams = newAssetParams
// Update Allowed Markets
var newMarketParams v0_14committee.AllowedMarkets
for _, mp := range subPerm.AllowedMarkets {
newMP := v0_14committee.AllowedMarket(mp)
newMarketParams = append(newMarketParams, newMP)
}
newStabilitySubParamPermissions.AllowedMarkets = newMarketParams
// Add hard money market committee permissions
var newMoneyMarketParams v0_14committee.AllowedMoneyMarkets
hardMMDenoms := []string{"bnb", "busd", "btcb", "xrpb", "usdx", "ukava", "hard"}
for _, mmDenom := range hardMMDenoms {
newMoneyMarketParam := v0_14committee.NewAllowedMoneyMarket(mmDenom, true, false, false, true, true, true)
newMoneyMarketParams = append(newMoneyMarketParams, newMoneyMarketParam)
}
newStabilitySubParamPermissions.AllowedMoneyMarkets = newMoneyMarketParams
newStabilityCommitteePermissions = append(newStabilityCommitteePermissions, newStabilitySubParamPermissions)
}
}
newStabilityCommitteePermissions = append(newStabilityCommitteePermissions, v0_14committee.TextPermission{})
newStabilityCommittee.Permissions = newStabilityCommitteePermissions
committees = append(committees, newStabilityCommittee)
} else {
newSafetyCommittee.ID = com.ID
newSafetyCommittee.Description = com.Description
newSafetyCommittee.Members = com.Members
newSafetyCommittee.Permissions = []v0_14committee.Permission{v0_14committee.SoftwareUpgradePermission{}}
newSafetyCommittee.VoteThreshold = com.VoteThreshold
newSafetyCommittee.ProposalDuration = com.ProposalDuration
committees = append(committees, newSafetyCommittee)
}
}
for _, v := range genesisState.Votes {
votes = append(votes, v0_14committee.Vote(v))
}
for _, p := range genesisState.Proposals {
newPubProp := v0_14committee.PubProposal(p.PubProposal)
newProp := v0_14committee.NewProposal(newPubProp, p.ID, p.CommitteeID, p.Deadline)
proposals = append(proposals, newProp)
}
return v0_14committee.NewGenesisState(
genesisState.NextProposalID, committees, proposals, votes)
}
// Pricefeed migrates from a v0.11 (or v0.12) pricefeed genesis state to a v0.13 pricefeed genesis state
func Pricefeed(genesisState v0_11pricefeed.GenesisState) v0_14pricefeed.GenesisState {
newMarkets := v0_14pricefeed.Markets{}
oracles := genesisState.Params.Markets[0].Oracles
for _, m := range genesisState.Params.Markets {
newMarkets = append(newMarkets, m)
}
usdx := v0_11pricefeed.NewMarket("usdx:usd", "usdx", "usd", oracles, true)
newMarkets = append(newMarkets, usdx)
newPrices := v0_14pricefeed.PostedPrices{}
for _, p := range genesisState.PostedPrices {
if p.Expiry.After(GenesisTime) {
newPrices = append(newPrices, p)
}
}
return v0_14pricefeed.NewGenesisState(v0_14pricefeed.NewParams(newMarkets), newPrices)
}
func removeIndex(accs authexported.GenesisAccounts, index int) authexported.GenesisAccounts {
ret := make(authexported.GenesisAccounts, 0)
ret = append(ret, accs[:index]...)
newAccounts := append(ret, accs[index+1:]...)
return newAccounts
}

View File

@ -1,91 +0,0 @@
# kava-7 Upgrade Instructions
## Software Version and Key Dates
* We will be upgrading from chain-id "kava-6" to chain-id "kava-7". This is to keep the features in our roadmap aligned with the features on mainnet going forward.
* The version of Kava for kava-7 is v0.14.1
* Kava-6 validators should prepare to shutdown their nodes April 8th, 2021 at 13:00 UTC by setting `--halt-time` to `1617886800`
* kava-7 genesis time is set to April 8th, 2021 at 15:00 UTC
* The version of cosmos-sdk for kava-7 is v0.39.2
* The version of tendermint for kava-7 v0.33.9
* The minimum version of golang for kava-7 is 1.13+, 1.15+ has been tested and is recommended.
### Risks
As a validator, performing the upgrade procedure on your consensus nodes carries a heightened risk of double-signing and being slashed. The most important piece of this procedure is verifying your software version and genesis file hash before starting your validator and signing.
The riskiest thing a validator can do is discover that they made a mistake and repeat the upgrade procedure again during the network startup. If you discover a mistake in the process, the best thing to do is wait for the network to start before correcting it. If the network is halted and you have started with a different genesis file than the expected one, seek advice from a Kava developer before resetting your validator.
### Recovery
Prior to exporting kava-6 state, validators are encouraged to take a full data snapshot at the export height before proceeding. Snap-shotting depends heavily on infrastructure, but generally this can be done by backing up the .kvd and .kvcli directories.
It is critically important to back-up the .kvd/data/priv_validator_state.json file after stopping your kvd process. This file is updated every block as your validator participates in consensus rounds. It is a critical file needed to prevent double-signing, in case the upgrade fails and the previous chain needs to be restarted.
In the event that the upgrade does not succeed, validators and operators must downgrade back to v0.12.4 of the Kava software and restore to their latest snapshot before restarting their nodes.
## Upgrade Procedure
### Before the upgrade
Set your node to produce the final block of kava-6 at __13:00__ UTC April 8th, 2021. To restart your node with that stop time,
```sh
kvd start --halt-time 1617886800
```
You can safely set the halt-time flag at any time.
### On the day of the upgrade
__The kava chain is expected to halt at 13:00 UTC, and restart with new software at 15:00 UTC April 8th. Do not stop your node and begin the upgrade before 13:00UTC on April 8th, or you may go offline and be unable to recover until after the upgrade!__
Kava developers will update this PR with the final block number when it is reached. __Make sure the kvd process is stopped before proceeding and that you have backed up your validator__. Failure to backup your validator could make it impossible to restart your node if the upgrade fails.
1. Export State (this __MUST__ be done using __v0.12.4__, previous v0.12.x versions will not produce the same genesis hash!)
```sh
kvd export --for-zero-height --height PLACEHOLDER > export-genesis.json
```
__Note:__ This can take a while!
2. Update to kava-7
```sh
# in the `kava` folder
git pull
git checkout v0.14.1
make install
# verify versions
kvd version --long
# name: kava
# server_name: kvd
# client_name: kvcli
# version: 0.14.1
# commit: PLACEHOLDER
# build_tags: netgo,ledger
# go: go version go1.15.8 linux/amd64
# Migrate genesis state
kvd migrate export-genesis.json > genesis.json
# Verify output of genesis migration
kvd validate-genesis genesis.json # should say it's valid
jq -S -c -M '' genesis.json | shasum -a 256
# PLACEHOLDER
# Restart node with migrated genesis state
cp genesis.json ~/.kvd/config/genesis.json
kvd unsafe-reset-all
# Restart node -
# ! Be sure to remove --halt-time flag if it is set in systemd/docker
kvd start
```
### Coordination
If the kava-7 chain does not launch by April 8, 2021 at 17:00 UTC, the launch should be considered a failure and validators should refer to the [rollback](./rollback.md) instructions to restart the previous kava-6 chain. In the event of launch failure, coordination will occur in the [Kava discord](https://discord.com/invite/kQzh3Uv).

View File

@ -1,250 +0,0 @@
package v0_14
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/supply"
supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/x/bep3"
v0_11cdp "github.com/kava-labs/kava/x/cdp/legacy/v0_11"
v0_11committee "github.com/kava-labs/kava/x/committee/legacy/v0_11"
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
v0_14hard "github.com/kava-labs/kava/x/hard"
v0_11hard "github.com/kava-labs/kava/x/hard/legacy/v0_11"
v0_11incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_11"
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
v0_11pricefeed "github.com/kava-labs/kava/x/pricefeed"
validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
"github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
app.SetBip44CoinType(config)
os.Exit(m.Run())
}
func TestCDP(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-6-cdp-state.json"))
require.NoError(t, err)
var oldGenState v0_11cdp.GenesisState
cdc := app.MakeCodec()
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := CDP(oldGenState)
err = newGenState.Validate()
require.NoError(t, err)
require.Equal(t, len(newGenState.Params.CollateralParams), len(newGenState.PreviousAccumulationTimes))
cdp1 := newGenState.CDPs[0]
require.Equal(t, sdk.OneDec(), cdp1.InterestFactor)
}
func TestAuth(t *testing.T) {
validatorVestingChangeAddress, err := sdk.AccAddressFromBech32("kava1a3qmze57knfj29a5knqs5ptewh76v4fg23xsvn")
if err != nil {
panic(err)
}
validatorVestingUpdatedValAddress, err := sdk.ConsAddressFromBech32("kavavalcons1ucxhn6zh7y2zun49m36psjffrhmux7ukqxdcte")
if err != nil {
panic(err)
}
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-6-auth-state.json"))
require.NoError(t, err)
var oldGenState auth.GenesisState
cdc := app.MakeCodec()
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
harvestCoins := getModuleAccount(oldGenState.Accounts, "harvest").GetCoins()
newGenState := Auth(oldGenState)
for _, acc := range newGenState.Accounts {
if acc.GetAddress().Equals(validatorVestingChangeAddress) {
vacc := acc.(*validatorvesting.ValidatorVestingAccount)
require.Equal(t, int64(0), vacc.CurrentPeriodProgress.MissedBlocks)
require.Equal(t, validatorVestingUpdatedValAddress, vacc.ValidatorAddress)
}
}
err = auth.ValidateGenesis(newGenState)
require.NoError(t, err)
require.Equal(t, len(oldGenState.Accounts), len(newGenState.Accounts)+3)
require.Nil(t, getModuleAccount(newGenState.Accounts, "harvest"))
require.Equal(t, getModuleAccount(newGenState.Accounts, "hard").GetCoins(), harvestCoins)
}
func getModuleAccount(accounts authexported.GenesisAccounts, name string) supplyexported.ModuleAccountI {
modAcc, ok := getAccount(accounts, supply.NewModuleAddress(name)).(supplyexported.ModuleAccountI)
if !ok {
return nil
}
return modAcc
}
func getAccount(accounts authexported.GenesisAccounts, address sdk.AccAddress) authexported.GenesisAccount {
for _, acc := range accounts {
if acc.GetAddress().Equals(address) {
return acc
}
}
return nil
}
func TestIncentive(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-6-incentive-state.json"))
require.NoError(t, err)
var oldIncentiveGenState v0_11incentive.GenesisState
cdc := app.MakeCodec()
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldIncentiveGenState)
})
bz, err = ioutil.ReadFile(filepath.Join("testdata", "kava-6-harvest-state.json"))
require.NoError(t, err)
var oldHarvestGenState v0_11hard.GenesisState
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldHarvestGenState)
})
newGenState := v0_14incentive.GenesisState{}
require.NotPanics(t, func() {
newGenState = Incentive(oldHarvestGenState, oldIncentiveGenState)
})
err = newGenState.Validate()
require.NoError(t, err)
fmt.Printf("Number of incentive claims in kava-6: %d\nNumber of incentive Claims in kava-5.1: %d\n",
len(oldIncentiveGenState.Claims), len(newGenState.USDXMintingClaims),
)
fmt.Printf("Number of harvest claims in kava-6: %d\nNumber of hard claims in kava-5.1: %d\n", len(oldHarvestGenState.Claims), len(newGenState.HardLiquidityProviderClaims))
}
func TestHard(t *testing.T) {
cdc := app.MakeCodec()
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-6-harvest-state.json"))
require.NoError(t, err)
var oldHarvestGenState v0_11hard.GenesisState
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldHarvestGenState)
})
newGenState := v0_14hard.GenesisState{}
require.NotPanics(t, func() {
newGenState = Hard(oldHarvestGenState)
})
err = newGenState.Validate()
require.NoError(t, err)
}
func TestCommittee(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-6-committee-state.json"))
require.NoError(t, err)
var oldGenState v0_11committee.GenesisState
cdc := codec.New()
sdk.RegisterCodec(cdc)
v0_11committee.RegisterCodec(cdc)
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := Committee(oldGenState)
err = newGenState.Validate()
require.NoError(t, err)
require.Equal(t, len(oldGenState.Committees), len(newGenState.Committees))
for i := 0; i < len(oldGenState.Committees); i++ {
require.Equal(t, len(oldGenState.Committees[i].Permissions), len(newGenState.Committees[i].Permissions))
}
oldSPCP := oldGenState.Committees[0].Permissions[0].(v0_11committee.SubParamChangePermission)
newSPCP := newGenState.Committees[0].Permissions[0].(v0_14committee.SubParamChangePermission)
require.Equal(t, len(oldSPCP.AllowedParams)-14, len(newSPCP.AllowedParams)) // accounts for removed/redundant keys
require.Equal(t, len(oldSPCP.AllowedAssetParams), len(newSPCP.AllowedAssetParams))
require.Equal(t, len(oldSPCP.AllowedCollateralParams)+3, len(newSPCP.AllowedCollateralParams)) // accounts for new cdp collateral types
require.Equal(t, len(oldSPCP.AllowedMarkets), len(newSPCP.AllowedMarkets))
}
func TestPricefeed(t *testing.T) {
cdc := app.MakeCodec()
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-6-pricefeed-state.json"))
require.NoError(t, err)
var oldPricefeedGenState v0_11pricefeed.GenesisState
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldPricefeedGenState)
})
newGenState := Pricefeed(oldPricefeedGenState)
err = newGenState.Validate()
require.NoError(t, err)
require.Equal(t, len(oldPricefeedGenState.Params.Markets)+1, len(newGenState.Params.Markets))
}
func TestBep3(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-6-bep3-state.json"))
require.NoError(t, err)
var oldGenState bep3.GenesisState
cdc := app.MakeCodec()
require.NotPanics(t, func() {
cdc.MustUnmarshalJSON(bz, &oldGenState)
})
newGenState := Bep3(oldGenState)
err = newGenState.Validate()
require.NoError(t, err)
var oldBNBSupply bep3.AssetSupply
var newBNBSupply bep3.AssetSupply
for _, supply := range oldGenState.Supplies {
if supply.GetDenom() == "bnb" {
oldBNBSupply = supply
}
}
for _, supply := range newGenState.Supplies {
if supply.GetDenom() == "bnb" {
newBNBSupply = supply
}
}
require.Equal(t, oldBNBSupply.CurrentSupply.Sub(sdk.NewCoin("bnb", sdk.NewInt(1000000000000))), newBNBSupply.CurrentSupply)
require.Equal(t, uint64(24686), newGenState.Params.AssetParams[0].MinBlockLock)
require.Equal(t, uint64(86400), newGenState.Params.AssetParams[0].MaxBlockLock)
}
func TestMigrateFull(t *testing.T) {
oldGenDoc, err := tmtypes.GenesisDocFromFile(filepath.Join("testdata", "kava-6-block-127500.json"))
require.NoError(t, err)
// 2) migrate
newGenDoc := Migrate(*oldGenDoc)
tApp := app.NewTestApp()
cdc := app.MakeCodec()
var newAppState genutil.AppMap
require.NoError(t,
cdc.UnmarshalJSON(newGenDoc.AppState, &newAppState),
)
err = app.ModuleBasics.ValidateGenesis(newAppState)
if err != nil {
require.NoError(t, err)
}
require.NotPanics(t, func() {
// this runs both InitGenesis for all modules (which panic on errors) and runs all invariants
tApp.InitializeFromGenesisStatesWithTime(newGenDoc.GenesisTime, app.GenesisState(newAppState))
})
}

View File

@ -1,40 +0,0 @@
# Kava-5-1 Rollback Instructions
In the event that the kava-5.1 relaunch is unsuccessful, we will restart the kava-6 chain using the last known state.
In order to restore the previous chain, the following data must be recovered by validators:
* The database that contains the state of the previous chain (in ~/.kvd/data by default)
* The priv_validator_state.json file of the validator (in ~/.kvd/data by default)
If you don't have the database data, the Kava developer team or another validator will share a copy of the database via Amazon s3 or a similar service. You will be able to download a copy of the data and verify it before starting your node.
If you don't have the backup priv_validator_state.json file, you will not have double sign protection on the first block. If this is the case, it's best to consult in the validator discord before starting your node.
## Restoring state procedure
1. Copy the contents of your backup data directory back to the $KVD_HOME/data directory. By default this is ~/.kvd/data.
```
# Assumes backup is stored in "backup" directory
rm -rf ~/.kvd/data
mv backup/.kvd/data ~/.kvd/data
```
2. Install the previous version of kava
```
# from kava directory
git checkout v0.12.4
make install
## verify version
kvd version --long
```
3. Restart kvd process
```
### be sure to remove --halt-time flag if it is set
sudo systemctl daemon-reload
sudo systemctl restart kvd
```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
{"committees":[{"description":"Kava Stability Committee","id":"1","members":["kava1gru35up50ql2wxhegr880qy6ynl63ujlv8gum2","kava1sc3mh3pkas5e7xd269am4xm5mp6zweyzmhjagj","kava1c9ye54e3pzwm3e0zpdlel6pnavrj9qqv6e8r4h","kava1m7p6sjqrz6mylz776ct48wj6lpnpcd0z82209d","kava1a9pmkzk570egv3sflu3uwdf3gejl7qfy9hghzl"],"permissions":[{"type":"kava/SubParamChangePermission","value":{"allowed_asset_params":[{"active":true,"coin_id":false,"denom":"bnb","limit":true,"max_swap_amount":true,"min_block_lock":true},{"active":true,"coin_id":true,"denom":"busd","limit":true,"max_swap_amount":true,"min_block_lock":true},{"active":true,"coin_id":false,"denom":"btcb","limit":true,"max_swap_amount":true,"min_block_lock":true},{"active":true,"coin_id":false,"denom":"xrpb","limit":true,"max_swap_amount":true,"min_block_lock":true}],"allowed_collateral_params":[{"auction_size":true,"conversion_factor":false,"debt_limit":true,"denom":false,"liquidation_market_id":false,"liquidation_penalty":false,"liquidation_ratio":false,"prefix":false,"spot_market_id":false,"stability_fee":true,"type":"bnb-a"},{"auction_size":true,"conversion_factor":false,"debt_limit":true,"denom":false,"liquidation_market_id":false,"liquidation_penalty":false,"liquidation_ratio":false,"prefix":false,"spot_market_id":false,"stability_fee":true,"type":"busd-a"},{"auction_size":true,"conversion_factor":false,"debt_limit":true,"denom":false,"liquidation_market_id":false,"liquidation_penalty":false,"liquidation_ratio":false,"prefix":false,"spot_market_id":false,"stability_fee":true,"type":"busd-b"},{"auction_size":true,"conversion_factor":false,"debt_limit":true,"denom":false,"liquidation_market_id":false,"liquidation_penalty":false,"liquidation_ratio":false,"prefix":false,"spot_market_id":false,"stability_fee":true,"type":"btcb-a"},{"auction_size":true,"conversion_factor":false,"debt_limit":true,"denom":false,"liquidation_market_id":false,"liquidation_penalty":false,"liquidation_ratio":false,"prefix":false,"spot_market_id":false,"stability_fee":true,"type":"xrpb-a"}],"allowed_debt_param":{"conversion_factor":false,"debt_floor":true,"denom":false,"reference_asset":false,"savings_rate":true},"allowed_markets":[{"active":true,"base_asset":false,"market_id":"bnb:usd","oracles":false,"quote_asset":false},{"active":true,"base_asset":false,"market_id":"bnb:usd:30","oracles":false,"quote_asset":false},{"active":true,"base_asset":false,"market_id":"btc:usd","oracles":false,"quote_asset":false},{"active":true,"base_asset":false,"market_id":"btc:usd:30","oracles":false,"quote_asset":false},{"active":true,"base_asset":false,"market_id":"xrp:usd","oracles":false,"quote_asset":false},{"active":true,"base_asset":false,"market_id":"xrp:usd:30","oracles":false,"quote_asset":false},{"active":true,"base_asset":false,"market_id":"busd:usd","oracles":false,"quote_asset":false},{"active":true,"base_asset":false,"market_id":"busd:usd:30","oracles":false,"quote_asset":false}],"allowed_params":[{"key":"BidDuration","subspace":"auction"},{"key":"Active","subspace":"harvest"},{"key":"IncrementSurplus","subspace":"auction"},{"key":"Active","subspace":"harvest"},{"key":"IncrementDebt","subspace":"auction"},{"key":"Active","subspace":"harvest"},{"key":"IncrementCollateral","subspace":"auction"},{"key":"Active","subspace":"harvest"},{"key":"AssetParams","subspace":"bep3"},{"key":"Active","subspace":"harvest"},{"key":"GlobalDebtLimit","subspace":"cdp"},{"key":"Active","subspace":"harvest"},{"key":"SurplusThreshold","subspace":"cdp"},{"key":"Active","subspace":"harvest"},{"key":"SurplusLot","subspace":"cdp"},{"key":"Active","subspace":"harvest"},{"key":"DebtThreshold","subspace":"cdp"},{"key":"Active","subspace":"harvest"},{"key":"DebtLot","subspace":"cdp"},{"key":"Active","subspace":"harvest"},{"key":"DistributionFrequency","subspace":"cdp"},{"key":"Active","subspace":"harvest"},{"key":"CollateralParams","subspace":"cdp"},{"key":"Active","subspace":"harvest"},{"key":"DebtParam","subspace":"cdp"},{"key":"Active","subspace":"harvest"},{"key":"Active","subspace":"incentive"},{"key":"Active","subspace":"harvest"},{"key":"Active","subspace":"kavadist"},{"key":"Active","subspace":"harvest"},{"key":"Markets","subspace":"pricefeed"},{"key":"Active","subspace":"harvest"}]}},{"type":"kava/TextPermission","value":{}}],"proposal_duration":"604800000000000","vote_threshold":"0.500000000000000000"},{"description":"Kava Safety Committee","id":"2","members":["kava1e0agyg6eug9r62fly9sls77ycjgw8ax6xk73es"],"permissions":[{"type":"kava/SoftwareUpgradePermission","value":{}}],"proposal_duration":"604800000000000","vote_threshold":"0.500000000000000000"}],"next_proposal_id":"40","proposals":[],"votes":[]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More