Update to sdk v0.39.x (#625)

* fix cli tests
- add pruning config
- add the new build path

* bump sdk version, make changes to get kvd running

* add draft multi-tx test

* add multiple txs per block test

* remove unused file

* sync VV account json format with sdk account types

* add another jsons test

* refactor coin creation in tests

* add missed file

* update changelog
This commit is contained in:
Ruaridh 2020-09-16 20:16:14 +01:00 committed by GitHub
parent 15a7dc610e
commit 64aa61d285
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 285 additions and 218 deletions

View File

@ -67,6 +67,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
```
[\#598](https://github.com/Kava-Labs/kava/pulls/598) CLI and REST queries for committee proposals (ie `kvcli q committee proposal 1`) now query the historical state to return the proposal object before it was deleted from state
[\#625](https://github.com/Kava-Labs/kava/pull/625) The Cosmos SDK has been updated to v0.39.1. This brings with it several breaking changes detailed [in their changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.39.1/CHANGELOG.md). Notably account JSON serialization has been modified to use amino instead of the Go stdlib, so numbers are serialized to strings, and public keys are no longer encoded into bech32 strings. Also pruning config has changed: `pruning=everything` and `pruning=nothing` still work but there are different flags for custom pruning configuration.
## [v0.8.1](https://github.com/Kava-Labs/kava/releases/tag/v0.8.1) kava-3 Patch Release

View File

@ -162,7 +162,7 @@ test:
@go test $$(go list ./... | grep -v 'migrate\|contrib')
test-rest:
rest_test/./run_all_tests_from_make.sh
rest_test/run_all_tests_from_make.sh
# Run cli integration tests
# `-p 4` to use 4 cores, `-tags cli_test` to tell go not to ignore the cli package

View File

@ -302,6 +302,40 @@ func TestKvCLISend(t *testing.T) {
f.Cleanup()
}
func TestKvCLISendMultiplePerBlock(t *testing.T) {
t.Parallel()
f := InitFixtures(t)
// start kvd server
proc := f.GDStart()
defer proc.Stop(false)
// Save key addresses for later use
fooAddr := f.KeyAddress(keyFoo)
barAddr := f.KeyAddress(keyBar)
fooAcc := f.QueryAccount(fooAddr)
startTokens := fooAcc.GetCoins().AmountOf(fooDenom)
sendTokens := sdk.TokensFromConsensusPower(1)
numTxsToSend := 30
for i := 0; i < numTxsToSend; i++ {
seq := fooAcc.GetSequence() + uint64(i)
f.TxSend(keyFoo, barAddr, sdk.NewCoin(fooDenom, sendTokens), "-y", fmt.Sprintf("--sequence=%d", seq), "--broadcast-mode=sync")
}
tests.WaitForNextNBlocksTM(1, f.Port)
// Ensure account balances match expected
totalSent := sendTokens.MulRaw(int64(numTxsToSend))
barAcc := f.QueryAccount(barAddr)
require.Equal(t, totalSent, barAcc.GetCoins().AmountOf(fooDenom))
fooAcc = f.QueryAccount(fooAddr)
require.Equal(t, startTokens.Sub(totalSent), fooAcc.GetCoins().AmountOf(fooDenom))
f.Cleanup()
}
func TestKvCLIGasAuto(t *testing.T) {
// https://github.com/cosmos/cosmos-sdk/pull/5179
t.Skip()

View File

@ -2,7 +2,6 @@ package main
import (
"encoding/json"
"fmt"
"io"
"github.com/spf13/cobra"
@ -46,7 +45,7 @@ func main() {
rootCmd := &cobra.Command{
Use: "kvd",
Short: "Kava Daemon (server)",
PersistentPreRunE: persistentPreRunEFn(ctx),
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
}
rootCmd.AddCommand(
@ -91,9 +90,14 @@ func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application
skipUpgradeHeights[int64(h)] = true
}
pruningOpts, err := server.GetPruningOptionsFromFlags()
if err != nil {
panic(err)
}
return app.NewApp(
logger, db, traceStore, true, skipUpgradeHeights, invCheckPeriod,
baseapp.SetPruning(store.NewPruningOptionsFromString(viper.GetString("pruning"))),
baseapp.SetPruning(pruningOpts),
baseapp.SetMinGasPrices(viper.GetString(server.FlagMinGasPrices)),
baseapp.SetHaltHeight(viper.GetUint64(server.FlagHaltHeight)),
baseapp.SetHaltTime(viper.GetUint64(server.FlagHaltTime)),
@ -116,27 +120,3 @@ func exportAppStateAndTMValidators(
tempApp := app.NewApp(logger, db, traceStore, true, map[int64]bool{}, uint(1))
return tempApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
}
// persistentPreRunEFn wraps the sdk function server.PersistentPreRunEFn to error on invaid pruning config.
func persistentPreRunEFn(ctx *server.Context) func(*cobra.Command, []string) error {
originalFunc := server.PersistentPreRunEFn(ctx)
return func(cmd *cobra.Command, args []string) error {
if err := originalFunc(cmd, args); err != nil {
return err
}
// check pruning config for `kvd start`
if cmd.Name() == "start" {
if viper.GetString("pruning") == store.PruningStrategySyncable {
return fmt.Errorf(
"invalid app config: pruning == '%s'. Update config (%s) with pruning set to '%s' or '%s'.",
store.PruningStrategySyncable, viper.ConfigFileUsed(), store.PruningStrategyNothing, store.PruningStrategyEverything,
)
}
}
return nil
}
}

10
go.mod
View File

@ -3,14 +3,14 @@ module github.com/kava-labs/kava
go 1.13
require (
github.com/cosmos/cosmos-sdk v0.38.5
github.com/gorilla/mux v1.7.3
github.com/cosmos/cosmos-sdk v0.39.1
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.5.1
github.com/tendermint/tendermint v0.33.6
github.com/stretchr/testify v1.6.1
github.com/tendermint/tendermint v0.33.7
github.com/tendermint/tm-db v0.5.1
gopkg.in/yaml.v2 v2.2.8
gopkg.in/yaml.v2 v2.3.0
)
// patch bech32 decoding to enable larger string lengths

52
go.sum
View File

@ -4,8 +4,6 @@ github.com/99designs/keyring v1.1.3 h1:mEV3iyZWjkxQ7R8ia8GcG97vCX5zQQ7n4o8R2Bylw
github.com/99designs/keyring v1.1.3/go.mod h1:657DQuMrBZRtuL/voxVyiyb6zpMehlm5vLB9Qwrv904=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200102211924-4bcbc698314f h1:4O1om+UVU+Hfcihr1timk8YNXHxzZWgCo7ofnrZRApw=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200102211924-4bcbc698314f/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
@ -70,10 +68,8 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cosmos/cosmos-sdk v0.38.4 h1:jPZOvhMQkm7wwwzcLxuluhVpKfuIgddNGt999pAiz/Y=
github.com/cosmos/cosmos-sdk v0.38.4/go.mod h1:rzWOofbKfRt3wxiylmYWEFHnxxGj0coyqgWl2I9obAw=
github.com/cosmos/cosmos-sdk v0.38.5 h1:hLSrm4pvhqbA+zhyY+ltEfpynjLGeKFefctK8kHG6TE=
github.com/cosmos/cosmos-sdk v0.38.5/go.mod h1:o5V2eXScgPWh8BkKr2Z2Zq+NEt1RFW8l1HBk87JG+PY=
github.com/cosmos/cosmos-sdk v0.39.1 h1:vhjf9PZh9ph8btAj9aBpHoVITgVVjNBpM3x5Gl/Vwac=
github.com/cosmos/cosmos-sdk v0.39.1/go.mod h1:ry2ROl5n+f2/QXpKJo3rdWNJwll00z7KhIVcxNcl16M=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4=
@ -103,8 +99,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
@ -150,8 +144,6 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@ -177,13 +169,15 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
@ -340,8 +334,6 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.5.0 h1:Ctq0iGpCmr3jeP77kbF2UxgvRwzWWz+4Bh9/vJTyg1A=
github.com/prometheus/client_golang v1.5.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@ -396,8 +388,6 @@ github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs=
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
@ -408,8 +398,6 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=
github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/spf13/viper v1.6.3 h1:pDDu1OyEDTKzpJwdq4TiuLyMsUgRa/BT5cn5O62NoHs=
github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
@ -424,6 +412,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs=
@ -437,16 +427,11 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM
github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso=
github.com/tendermint/go-amino v0.15.1 h1:D2uk35eT4iTsvJd9jWIetzthE5C0/k2QmMFkCN+4JgQ=
github.com/tendermint/go-amino v0.15.1/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
github.com/tendermint/iavl v0.13.2 h1:O1m08/Ciy53l9IYmf75uIRVvrNsfjEbre8u/yCu/oqk=
github.com/tendermint/iavl v0.13.2/go.mod h1:vE1u0XAGXYjHykd4BLp8p/yivrw2PF1TuoljBcsQoGA=
github.com/tendermint/tendermint v0.33.2/go.mod h1:25DqB7YvV1tN3tHsjWoc2vFtlwICfrub9XO6UBO+4xk=
github.com/tendermint/tendermint v0.33.3 h1:6lMqjEoCGejCzAghbvfQgmw87snGSqEhDTo/jw+W8CI=
github.com/tendermint/tendermint v0.33.3/go.mod h1:25DqB7YvV1tN3tHsjWoc2vFtlwICfrub9XO6UBO+4xk=
github.com/tendermint/tendermint v0.33.6 h1:W4UOsXY4ROJZ3TLLGVVv71VXD4WK2gJRb3gzeced+mg=
github.com/tendermint/tendermint v0.33.6/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM=
github.com/tendermint/tm-db v0.4.1/go.mod h1:JsJ6qzYkCGiGwm5GHl/H5GLI9XLb6qZX7PRe425dHAY=
github.com/tendermint/tm-db v0.5.0 h1:qtM5UTr1dlRnHtDY6y7MZO5Di8XAE2j3lc/pCnKJ5hQ=
github.com/tendermint/tm-db v0.5.0/go.mod h1:lSq7q5WRR/njf1LnhiZ/lIJHk2S8Y1Zyq5oP/3o9C2U=
github.com/tendermint/iavl v0.14.0 h1:Jkff+IFrXxRWtH9Jn/ga/2cxNnzMTv58xEKgCJsKUBg=
github.com/tendermint/iavl v0.14.0/go.mod h1:QmfViflFiXzxKLQE4tAUuWQHq+RSuQFxablW5oJZ6sE=
github.com/tendermint/tendermint v0.33.5/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM=
github.com/tendermint/tendermint v0.33.7 h1:b5CQD8ggDtl4u0EbXzabi0MaOw9NrcXker6ijEkAE74=
github.com/tendermint/tendermint v0.33.7/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM=
github.com/tendermint/tm-db v0.5.1 h1:H9HDq8UEA7Eeg13kdYckkgwwkQLBnJGgX4PgLJRhieY=
github.com/tendermint/tm-db v0.5.1/go.mod h1:g92zWjHpCYlEvQXvy9M168Su8V1IBEeawpXVVBaK4f4=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@ -484,6 +469,8 @@ golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vK
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y=
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -589,11 +576,12 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k=
google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -621,8 +609,10 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -84,3 +84,6 @@ func NewPubKey(pk string) (res crypto.PubKey) {
copy(pkEd[:], pkBytes[:])
return pkEd
}
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }

View File

@ -1,13 +1,13 @@
package types
import (
"encoding/json"
"errors"
"fmt"
"time"
yaml "gopkg.in/yaml.v2"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
@ -207,7 +207,7 @@ func (vva ValidatorVestingAccount) Validate() error {
return vva.PeriodicVestingAccount.Validate()
}
type validatorVestingAccountPretty struct {
type validatorVestingAccountYAML struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey string `json:"public_key" yaml:"public_key"`
@ -217,6 +217,30 @@ type validatorVestingAccountPretty struct {
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"`
// non-base vesting account fields
StartTime int64 `json:"start_time" yaml:"start_time"`
VestingPeriods vestingtypes.Periods `json:"vesting_periods" yaml:"vesting_periods"`
ValidatorAddress sdk.ConsAddress `json:"validator_address" yaml:"validator_address"`
ReturnAddress sdk.AccAddress `json:"return_address" yaml:"return_address"`
SigningThreshold int64 `json:"signing_threshold" yaml:"signing_threshold"`
CurrentPeriodProgress CurrentPeriodProgress `json:"current_period_progress" yaml:"current_period_progress"`
VestingPeriodProgress []VestingProgress `json:"vesting_period_progress" yaml:"vesting_period_progress"`
DebtAfterFailedVesting sdk.Coins `json:"debt_after_failed_vesting" yaml:"debt_after_failed_vesting"`
}
type validatorVestingAccountJSON 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"`
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"`
// non-base vesting account fields
StartTime int64 `json:"start_time" yaml:"start_time"`
VestingPeriods vestingtypes.Periods `json:"vesting_periods" yaml:"vesting_periods"`
ValidatorAddress sdk.ConsAddress `json:"validator_address" yaml:"validator_address"`
@ -229,15 +253,17 @@ type validatorVestingAccountPretty struct {
// MarshalJSON returns the JSON representation of a PeriodicVestingAccount.
func (vva ValidatorVestingAccount) MarshalJSON() ([]byte, error) {
alias := validatorVestingAccountPretty{
alias := validatorVestingAccountJSON{
Address: vva.Address,
Coins: vva.Coins,
PubKey: vva.GetPubKey(),
AccountNumber: vva.AccountNumber,
Sequence: vva.Sequence,
OriginalVesting: vva.OriginalVesting,
DelegatedFree: vva.DelegatedFree,
DelegatedVesting: vva.DelegatedVesting,
EndTime: vva.EndTime,
StartTime: vva.StartTime,
VestingPeriods: vva.VestingPeriods,
ValidatorAddress: vva.ValidatorAddress,
@ -248,38 +274,17 @@ func (vva ValidatorVestingAccount) MarshalJSON() ([]byte, error) {
DebtAfterFailedVesting: vva.DebtAfterFailedVesting,
}
if vva.PubKey != nil {
pks, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, vva.PubKey)
if err != nil {
return nil, err
return codec.Cdc.MarshalJSON(alias)
}
alias.PubKey = pks
}
return json.Marshal(alias)
}
// UnmarshalJSON unmarshals raw JSON bytes into a PeriodicVestingAccount.
// UnmarshalJSON unmarshals raw JSON bytes into a ValidatorVestingAccount.
func (vva *ValidatorVestingAccount) UnmarshalJSON(bz []byte) error {
var alias validatorVestingAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
var alias validatorVestingAccountJSON
if err := codec.Cdc.UnmarshalJSON(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
}
}
ba := authtypes.NewBaseAccount(alias.Address, alias.Coins, pk, alias.AccountNumber, alias.Sequence)
ba := authtypes.NewBaseAccount(alias.Address, alias.Coins, alias.PubKey, alias.AccountNumber, alias.Sequence)
bva := &vestingtypes.BaseVestingAccount{
BaseAccount: ba,
OriginalVesting: alias.OriginalVesting,
@ -300,45 +305,17 @@ func (vva *ValidatorVestingAccount) UnmarshalJSON(bz []byte) error {
// MarshalYAML returns the YAML representation of an account.
func (vva ValidatorVestingAccount) MarshalYAML() (interface{}, error) {
var bs []byte
var err error
var pubkey string
if vva.PubKey != nil {
pubkey, err = sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, vva.PubKey)
if err != nil {
return nil, err
}
}
bs, err = yaml.Marshal(struct {
Address sdk.AccAddress
Coins sdk.Coins
PubKey string
AccountNumber uint64
Sequence uint64
OriginalVesting sdk.Coins
DelegatedFree sdk.Coins
DelegatedVesting sdk.Coins
EndTime int64
StartTime int64
VestingPeriods vestingtypes.Periods
ValidatorAddress sdk.ConsAddress
ReturnAddress sdk.AccAddress
SigningThreshold int64
CurrentPeriodProgress CurrentPeriodProgress
VestingPeriodProgress []VestingProgress
DebtAfterFailedVesting sdk.Coins
}{
alias := validatorVestingAccountYAML{
Address: vva.Address,
Coins: vva.Coins,
PubKey: pubkey,
// no Pubkey
AccountNumber: vva.AccountNumber,
Sequence: vva.Sequence,
OriginalVesting: vva.OriginalVesting,
DelegatedFree: vva.DelegatedFree,
DelegatedVesting: vva.DelegatedVesting,
EndTime: vva.EndTime,
StartTime: vva.StartTime,
VestingPeriods: vva.VestingPeriods,
ValidatorAddress: vva.ValidatorAddress,
@ -347,10 +324,24 @@ func (vva ValidatorVestingAccount) MarshalYAML() (interface{}, error) {
CurrentPeriodProgress: vva.CurrentPeriodProgress,
VestingPeriodProgress: vva.VestingPeriodProgress,
DebtAfterFailedVesting: vva.DebtAfterFailedVesting,
})
}
pk := vva.GetPubKey()
if pk != nil {
pubkey, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, pk)
if err != nil {
return nil, err
}
return string(bs), err
alias.PubKey = pubkey
}
bz, err := yaml.Marshal(alias)
if err != nil {
return nil, err
}
return string(bz), err
}
func (vva ValidatorVestingAccount) String() string {
out, _ := vva.MarshalYAML()
return out.(string)
}

View File

@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/multisig"
tmtime "github.com/tendermint/tendermint/types/time"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -24,15 +25,15 @@ func TestNewAccount(t *testing.T) {
now := tmtime.Now()
endTime := now.Add(24 * time.Hour).Unix()
periods := vestingtypes.Periods{
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: cs(c(feeDenom, 500), c(stakeDenom, 50))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
}
testAddr := CreateTestAddrs(1)[0]
testPk := CreateTestPubKeys(1)[0]
testConsAddr := sdk.ConsAddress(testPk.Address())
origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)}
origCoins := cs(c(feeDenom, 1000), c(stakeDenom, 100))
bacc := auth.NewBaseAccountWithAddress(testAddr)
bacc.SetCoins(origCoins)
bva, _ := vesting.NewBaseVestingAccount(&bacc, origCoins, endTime)
@ -46,15 +47,15 @@ func TestNewAccount(t *testing.T) {
func TestGetVestedCoinsValidatorVestingAcc(t *testing.T) {
now := tmtime.Now()
periods := vestingtypes.Periods{
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: cs(c(feeDenom, 500), c(stakeDenom, 50))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
}
testAddr := CreateTestAddrs(1)[0]
testPk := CreateTestPubKeys(1)[0]
testConsAddr := sdk.ConsAddress(testPk.Address())
origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)}
origCoins := cs(c(feeDenom, 1000), c(stakeDenom, 100))
bacc := auth.NewBaseAccountWithAddress(testAddr)
bacc.SetCoins(origCoins)
vva := NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
@ -70,36 +71,32 @@ func TestGetVestedCoinsValidatorVestingAcc(t *testing.T) {
// require 50% of coins vested after successful period 1 vesting
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
vestedCoins = vva.GetVestedCoins(now.Add(12 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestedCoins)
require.Equal(t, cs(c(feeDenom, 500), c(stakeDenom, 50)), vestedCoins)
// require 50% of coins vested after unsuccessful period 1 vesting
// NOTE: There is a fairly important semantic distinction here. It seems tempting to say that a failed vesting period should mean that 'GetVestedCoins' should not return those coins. While the point of a validator vesting account is to 'seize' or 'burn' unsuccessfully vested coins, they do in fact vest and become spendable. The intuition is that they have to be spendable in order for the bank keeper to allow us to send/burn them. If they were not vested, then a validator vesting account that failed all of it's vesting periods would never return/burn the coins because it would never have a spendable balance by which to do so. They way we prevent them from being spent in a way other than return/burn is by sending them in the BeginBlock and thus beating any other transfers that would otherwise occur.
vva.VestingPeriodProgress[0] = VestingProgress{true, false}
vestedCoins = vva.GetVestedCoins(now.Add(12 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestedCoins)
require.Equal(t, cs(c(feeDenom, 500), c(stakeDenom, 50)), vestedCoins)
// require period 2 coins don't vest until period is over
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
// even if the vesting period was somehow successful, should still only return 50% of coins as vested, since the second vesting period hasn't completed.
vva.VestingPeriodProgress[1] = VestingProgress{true, true}
vestedCoins = vva.GetVestedCoins(now.Add(15 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestedCoins)
require.Equal(t, cs(c(feeDenom, 500), c(stakeDenom, 50)), vestedCoins)
// require 75% of coins vested after successful period 2
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
vva.VestingPeriodProgress[1] = VestingProgress{true, true}
vestedCoins = vva.GetVestedCoins(now.Add(18 * time.Hour))
require.Equal(t,
sdk.Coins{
sdk.NewInt64Coin(feeDenom, 750), sdk.NewInt64Coin(stakeDenom, 75)}, vestedCoins)
require.Equal(t, cs(c(feeDenom, 750), c(stakeDenom, 75)), vestedCoins)
// require 75% of coins vested after successful period 1 and unsuccessful period 2.
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
vva.VestingPeriodProgress[1] = VestingProgress{true, false}
vestedCoins = vva.GetVestedCoins(now.Add(18 * time.Hour))
require.Equal(t,
sdk.Coins{
sdk.NewInt64Coin(feeDenom, 750), sdk.NewInt64Coin(stakeDenom, 75)}, vestedCoins)
require.Equal(t, cs(c(feeDenom, 750), c(stakeDenom, 75)), vestedCoins)
// require 100% of coins vested after all periods complete successfully
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
@ -121,15 +118,15 @@ func TestGetVestedCoinsValidatorVestingAcc(t *testing.T) {
func TestGetVestingCoinsValidatorVestingAcc(t *testing.T) {
now := tmtime.Now()
periods := vestingtypes.Periods{
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: cs(c(feeDenom, 500), c(stakeDenom, 50))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
}
testAddr := CreateTestAddrs(1)[0]
testPk := CreateTestPubKeys(1)[0]
testConsAddr := sdk.ConsAddress(testPk.Address())
origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)}
origCoins := cs(c(feeDenom, 1000), c(stakeDenom, 100))
bacc := auth.NewBaseAccountWithAddress(testAddr)
bacc.SetCoins(origCoins)
vva := NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
@ -145,33 +142,31 @@ func TestGetVestingCoinsValidatorVestingAcc(t *testing.T) {
// require 50% of coins vesting after successful period 1 vesting
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
vestingCoins = vva.GetVestingCoins(now.Add(12 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestingCoins)
require.Equal(t, cs(c(feeDenom, 500), c(stakeDenom, 50)), vestingCoins)
// require 50% of coins vesting after unsuccessful period 1 vesting
vva.VestingPeriodProgress[0] = VestingProgress{true, false}
vestingCoins = vva.GetVestingCoins(now.Add(12 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestingCoins)
require.Equal(t, cs(c(feeDenom, 500), c(stakeDenom, 50)), vestingCoins)
// require period 2 coins still vesting until period is over
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
// should never happen, but still won't affect vesting balance
vva.VestingPeriodProgress[1] = VestingProgress{true, true}
vestingCoins = vva.GetVestingCoins(now.Add(15 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestingCoins)
require.Equal(t, cs(c(feeDenom, 500), c(stakeDenom, 50)), vestingCoins)
// require 25% of coins vesting after successful period 2
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
vva.VestingPeriodProgress[1] = VestingProgress{true, true}
vestingCoins = vva.GetVestingCoins(now.Add(18 * time.Hour))
require.Equal(t,
sdk.Coins{
sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}, vestingCoins)
require.Equal(t, cs(c(feeDenom, 250), c(stakeDenom, 25)), vestingCoins)
// require 25% of coins vesting after successful period 1 and unsuccessful period 2
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
vva.VestingPeriodProgress[1] = VestingProgress{true, false}
vestingCoins = vva.GetVestingCoins(now.Add(18 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}, vestingCoins)
require.Equal(t, cs(c(feeDenom, 250), c(stakeDenom, 25)), vestingCoins)
// require no coins vesting after all periods complete successfully
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
@ -193,15 +188,15 @@ func TestGetVestingCoinsValidatorVestingAcc(t *testing.T) {
func TestSpendableCoinsValidatorVestingAccount(t *testing.T) {
now := tmtime.Now()
periods := vestingtypes.Periods{
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: cs(c(feeDenom, 500), c(stakeDenom, 50))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
}
testAddr := CreateTestAddrs(1)[0]
testPk := CreateTestPubKeys(1)[0]
testConsAddr := sdk.ConsAddress(testPk.Address())
origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)}
origCoins := cs(c(feeDenom, 1000), c(stakeDenom, 100))
bacc := auth.NewBaseAccountWithAddress(testAddr)
bacc.SetCoins(origCoins)
vva := NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
@ -213,21 +208,21 @@ func TestSpendableCoinsValidatorVestingAccount(t *testing.T) {
// require that all vested coins (50%) are spendable when period 1 completes successfully
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
spendableCoins = vva.SpendableCoins(now.Add(12 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, spendableCoins)
require.Equal(t, cs(c(feeDenom, 500), c(stakeDenom, 50)), spendableCoins)
// require that 50% of coins are spendable after period 1 completes unsuccessfully. See note above. The reason the coins are still 'spendable' is that we need to be able to transfer the coins to the return address/burn them. Making them not spendable means that it would be impossible to recover the debt for a validator vesting account for which all periods failed.
vva.VestingPeriodProgress[0] = VestingProgress{true, false}
spendableCoins = vva.SpendableCoins(now.Add(12 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, spendableCoins)
require.Equal(t, cs(c(feeDenom, 500), c(stakeDenom, 50)), spendableCoins)
// receive some coins
recvAmt := sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}
recvAmt := cs(c(stakeDenom, 50))
vva.SetCoins(vva.GetCoins().Add(recvAmt...))
// require that all vested coins (50%) are spendable plus any received after period 1 completes successfully
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
spendableCoins = vva.SpendableCoins(now.Add(12 * time.Hour))
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 100)}, spendableCoins)
require.Equal(t, cs(c(feeDenom, 500), c(stakeDenom, 100)), spendableCoins)
// spend all spendable coins
vva.SetCoins(vva.GetCoins().Sub(spendableCoins))
@ -240,15 +235,15 @@ func TestSpendableCoinsValidatorVestingAccount(t *testing.T) {
func TestGetFailedVestedCoins(t *testing.T) {
now := tmtime.Now()
periods := vestingtypes.Periods{
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: cs(c(feeDenom, 500), c(stakeDenom, 50))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
}
testAddr := CreateTestAddrs(1)[0]
testPk := CreateTestPubKeys(1)[0]
testConsAddr := sdk.ConsAddress(testPk.Address())
origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)}
origCoins := cs(c(feeDenom, 1000), c(stakeDenom, 100))
bacc := auth.NewBaseAccountWithAddress(testAddr)
bacc.SetCoins(origCoins)
vva := NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
@ -256,7 +251,7 @@ func TestGetFailedVestedCoins(t *testing.T) {
vva.VestingPeriodProgress[0] = VestingProgress{true, false}
// require that period 1 coins are failed if the period completed unsuccessfully.
require.Equal(t,
sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)},
cs(c(feeDenom, 500), c(stakeDenom, 50)),
vva.GetFailedVestedCoins(),
)
@ -270,15 +265,15 @@ func TestGetFailedVestedCoins(t *testing.T) {
func TestTrackDelegationValidatorVestingAcc(t *testing.T) {
now := tmtime.Now()
periods := vestingtypes.Periods{
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: cs(c(feeDenom, 500), c(stakeDenom, 50))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
}
testAddr := CreateTestAddrs(1)[0]
testPk := CreateTestPubKeys(1)[0]
testConsAddr := sdk.ConsAddress(testPk.Address())
origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)}
origCoins := cs(c(feeDenom, 1000), c(stakeDenom, 100))
bacc := auth.NewBaseAccountWithAddress(testAddr)
bacc.SetCoins(origCoins)
vva := NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
@ -301,20 +296,20 @@ func TestTrackDelegationValidatorVestingAcc(t *testing.T) {
// require the ability to delegate all vesting coins (50%) and all vested coins (50%)
bacc.SetCoins(origCoins)
vva = NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
vva.TrackDelegation(now.Add(12*time.Hour), sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)})
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}, vva.DelegatedVesting)
vva.TrackDelegation(now.Add(12*time.Hour), cs(c(stakeDenom, 50)))
require.Equal(t, cs(c(stakeDenom, 50)), vva.DelegatedVesting)
require.Nil(t, vva.DelegatedFree)
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
vva.TrackDelegation(now.Add(12*time.Hour), sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)})
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}, vva.DelegatedVesting)
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}, vva.DelegatedFree)
vva.TrackDelegation(now.Add(12*time.Hour), cs(c(stakeDenom, 50)))
require.Equal(t, cs(c(stakeDenom, 50)), vva.DelegatedVesting)
require.Equal(t, cs(c(stakeDenom, 50)), vva.DelegatedFree)
// require no modifications when delegation amount is zero or not enough funds
bacc.SetCoins(origCoins)
vva = NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
require.Panics(t, func() {
vva.TrackDelegation(now.Add(24*time.Hour), sdk.Coins{sdk.NewInt64Coin(stakeDenom, 1000000)})
vva.TrackDelegation(now.Add(24*time.Hour), cs(c(stakeDenom, 1000000)))
})
require.Nil(t, vva.DelegatedVesting)
require.Nil(t, vva.DelegatedFree)
@ -323,15 +318,15 @@ func TestTrackDelegationValidatorVestingAcc(t *testing.T) {
func TestTrackUndelegationPeriodicVestingAcc(t *testing.T) {
now := tmtime.Now()
periods := vestingtypes.Periods{
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: cs(c(feeDenom, 500), c(stakeDenom, 50))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
}
testAddr := CreateTestAddrs(1)[0]
testPk := CreateTestPubKeys(1)[0]
testConsAddr := sdk.ConsAddress(testPk.Address())
origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)}
origCoins := cs(c(feeDenom, 1000), c(stakeDenom, 100))
bacc := auth.NewBaseAccountWithAddress(testAddr)
bacc.SetCoins(origCoins)
vva := NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
@ -357,7 +352,7 @@ func TestTrackUndelegationPeriodicVestingAcc(t *testing.T) {
bacc.SetCoins(origCoins)
vva = NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
require.Panics(t, func() {
vva.TrackUndelegation(sdk.Coins{sdk.NewInt64Coin(stakeDenom, 0)})
vva.TrackUndelegation(sdk.Coins{c(stakeDenom, 0)})
})
require.Nil(t, vva.DelegatedFree)
require.Nil(t, vva.DelegatedVesting)
@ -365,32 +360,32 @@ func TestTrackUndelegationPeriodicVestingAcc(t *testing.T) {
// successfully vest period 1 and delegate to two validators
vva = NewValidatorVestingAccount(&bacc, now.Unix(), periods, testConsAddr, nil, 90)
vva.VestingPeriodProgress[0] = VestingProgress{true, true}
vva.TrackDelegation(now.Add(12*time.Hour), sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)})
vva.TrackDelegation(now.Add(12*time.Hour), sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)})
vva.TrackDelegation(now.Add(12*time.Hour), cs(c(stakeDenom, 50)))
vva.TrackDelegation(now.Add(12*time.Hour), cs(c(stakeDenom, 50)))
// undelegate from one validator that got slashed 50%
vva.TrackUndelegation(sdk.Coins{sdk.NewInt64Coin(stakeDenom, 25)})
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 25)}, vva.DelegatedFree)
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)}, vva.DelegatedVesting)
vva.TrackUndelegation(cs(c(stakeDenom, 25)))
require.Equal(t, cs(c(stakeDenom, 25)), vva.DelegatedFree)
require.Equal(t, cs(c(stakeDenom, 50)), vva.DelegatedVesting)
// undelegate from the other validator that did not get slashed
vva.TrackUndelegation(sdk.Coins{sdk.NewInt64Coin(stakeDenom, 50)})
vva.TrackUndelegation(cs(c(stakeDenom, 50)))
require.Nil(t, vva.DelegatedFree)
require.Equal(t, sdk.Coins{sdk.NewInt64Coin(stakeDenom, 25)}, vva.DelegatedVesting)
require.Equal(t, cs(c(stakeDenom, 25)), vva.DelegatedVesting)
}
func TestGenesisAccountValidate(t *testing.T) {
now := tmtime.Now()
periods := vestingtypes.Periods{
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}},
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: cs(c(feeDenom, 500), c(stakeDenom, 50))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
}
testAddr := CreateTestAddrs(1)[0]
testPk := CreateTestPubKeys(1)[0]
testConsAddr := sdk.ConsAddress(testPk.Address())
origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)}
origCoins := cs(c(feeDenom, 1000), c(stakeDenom, 100))
bacc := auth.NewBaseAccountWithAddress(testAddr)
bacc.SetCoins(origCoins)
@ -442,3 +437,76 @@ func TestGenesisAccountValidate(t *testing.T) {
}
}
}
func TestMarshalJSON(t *testing.T) {
testTime := tmtime.Now()
periods := vestingtypes.Periods{
vestingtypes.Period{Length: int64(12 * 60 * 60), Amount: cs(c(feeDenom, 500), c(stakeDenom, 50))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
vestingtypes.Period{Length: int64(6 * 60 * 60), Amount: cs(c(feeDenom, 250), c(stakeDenom, 25))},
}
testAddrs := CreateTestAddrs(2)
testPk := CreateTestPubKeys(1)[0]
testConsAddr := sdk.ConsAddress(testPk.Address())
testMultisigPk := multisig.NewPubKeyMultisigThreshold(6, CreateTestPubKeys(10))
testCases := []struct {
name string
account *ValidatorVestingAccount
}{
{
name: "normal",
account: NewValidatorVestingAccount(
auth.NewBaseAccount(
testAddrs[0],
cs(c(stakeDenom, 100)),
testPk,
0,
1,
),
testTime.Unix(),
periods,
testConsAddr,
testAddrs[1],
90,
),
},
{
name: "multisig",
account: NewValidatorVestingAccount(
auth.NewBaseAccount(
testAddrs[0],
cs(c(stakeDenom, 1)),
testMultisigPk,
412,
67,
),
testTime.Unix(),
periods,
testConsAddr,
testAddrs[1],
67,
),
},
}
for _, tc := range testCases {
bz, err := ModuleCdc.MarshalJSON(tc.account)
require.NoError(t, err)
var reconstructedAccount *ValidatorVestingAccount
err = ModuleCdc.UnmarshalJSON(bz, &reconstructedAccount)
require.NoError(t, err)
// first check debt coins using coin equality function, then overwrite to avoid problems with testify's Equality check
require.Truef(t,
tc.account.DebtAfterFailedVesting.IsEqual(reconstructedAccount.DebtAfterFailedVesting),
"DebtAfterFailedVesting not equal, expected: %+v, actual: %+v",
tc.account.DebtAfterFailedVesting,
reconstructedAccount.DebtAfterFailedVesting,
)
reconstructedAccount.DebtAfterFailedVesting = tc.account.DebtAfterFailedVesting
require.Equal(t, tc.account, reconstructedAccount)
}
}