Merge branch 'master' into bez/5444-gov-proto-enc
This commit is contained in:
commit
31dc2729fc
|
@ -3,7 +3,7 @@ version: 2.1
|
||||||
executors:
|
executors:
|
||||||
golang:
|
golang:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.13
|
- image: circleci/golang:1.14
|
||||||
docs:
|
docs:
|
||||||
docker:
|
docker:
|
||||||
- image: tendermintdev/docker-website-deployment
|
- image: tendermintdev/docker-website-deployment
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# CODEOWNERS: https://help.github.com/articles/about-codeowners/
|
# CODEOWNERS: https://help.github.com/articles/about-codeowners/
|
||||||
|
|
||||||
# Primary repo maintainers
|
# Primary repo maintainers
|
||||||
* @alexanderbez @jackzampolin @alessio @fedekunze
|
* @alexanderbez @alessio @fedekunze @nylira @hschoenburg
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
pull_request_rules:
|
||||||
|
- name: automerge to master with label automerge and branch protection passing
|
||||||
|
conditions:
|
||||||
|
- "#approved-reviews-by>=1"
|
||||||
|
- base=master
|
||||||
|
- label=automerge
|
||||||
|
actions:
|
||||||
|
merge:
|
||||||
|
method: squash
|
||||||
|
strict: true
|
|
@ -46,6 +46,7 @@ balances or a single balance by denom when the `denom` query parameter is presen
|
||||||
|
|
||||||
### API Breaking Changes
|
### API Breaking Changes
|
||||||
|
|
||||||
|
* [\#5719](https://github.com/cosmos/cosmos-sdk/pull/5719) Bump Go requirement to 1.14+
|
||||||
* (x/params) [\#5619](https://github.com/cosmos/cosmos-sdk/pull/5619) The `x/params` keeper now accepts a `codec.Marshaller` instead of
|
* (x/params) [\#5619](https://github.com/cosmos/cosmos-sdk/pull/5619) The `x/params` keeper now accepts a `codec.Marshaller` instead of
|
||||||
a reference to an amino codec. Amino is still used for JSON serialization.
|
a reference to an amino codec. Amino is still used for JSON serialization.
|
||||||
* (types) [\#5579](https://github.com/cosmos/cosmos-sdk/pull/5579) The `keepRecent` field has been removed from the `PruningOptions` type.
|
* (types) [\#5579](https://github.com/cosmos/cosmos-sdk/pull/5579) The `keepRecent` field has been removed from the `PruningOptions` type.
|
||||||
|
@ -66,6 +67,8 @@ to now accept a `codec.JSONMarshaler` for modular serialization of genesis state
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (baseapp) [\#5718](https://github.com/cosmos/cosmos-sdk/pull/5718) Remove call to `ctx.BlockGasMeter` during failed message validation which
|
||||||
|
resulted in a panic when the tx execution mode was `CheckTx`.
|
||||||
* (client) [\#5618](https://github.com/cosmos/cosmos-sdk/pull/5618) Fix crash on the client when the verifier is not set.
|
* (client) [\#5618](https://github.com/cosmos/cosmos-sdk/pull/5618) Fix crash on the client when the verifier is not set.
|
||||||
* (x/distribution) [\#5620](https://github.com/cosmos/cosmos-sdk/pull/5620) Fix nil pointer deref in distribution tax/rewward validation helpers.
|
* (x/distribution) [\#5620](https://github.com/cosmos/cosmos-sdk/pull/5620) Fix nil pointer deref in distribution tax/rewward validation helpers.
|
||||||
* (genesis) [\#5086](https://github.com/cosmos/cosmos-sdk/issues/5086) Ensure `gentxs` are always an empty array instead of `nil`
|
* (genesis) [\#5086](https://github.com/cosmos/cosmos-sdk/issues/5086) Ensure `gentxs` are always an empty array instead of `nil`
|
||||||
|
|
8
Makefile
8
Makefile
|
@ -191,10 +191,10 @@ lint:
|
||||||
go mod verify
|
go mod verify
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
|
|
||||||
format: tools
|
format:
|
||||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs gofmt -w -s
|
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" -not -name '*.pb.go' | xargs gofmt -w -s
|
||||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs misspell -w
|
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" -not -name '*.pb.go' | xargs misspell -w
|
||||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs goimports -w -local github.com/cosmos/cosmos-sdk
|
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" -not -name '*.pb.go' | xargs goimports -w -local github.com/cosmos/cosmos-sdk
|
||||||
.PHONY: format
|
.PHONY: format
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
|
@ -22,7 +22,7 @@ It is being used to build [`Gaia`](https://github.com/cosmos/gaia), the first im
|
||||||
**WARNING**: The SDK has mostly stabilized, but we are still making some
|
**WARNING**: The SDK has mostly stabilized, but we are still making some
|
||||||
breaking changes.
|
breaking changes.
|
||||||
|
|
||||||
**Note**: Requires [Go 1.13+](https://golang.org/dl/)
|
**Note**: Requires [Go 1.14+](https://golang.org/dl/)
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
package baseapp
|
package baseapp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -17,7 +14,6 @@ import (
|
||||||
dbm "github.com/tendermint/tm-db"
|
dbm "github.com/tendermint/tm-db"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/store"
|
"github.com/cosmos/cosmos-sdk/store"
|
||||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
)
|
)
|
||||||
|
@ -226,62 +222,6 @@ func DefaultStoreLoader(ms sdk.CommitMultiStore) error {
|
||||||
return ms.LoadLatestVersion()
|
return ms.LoadLatestVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreLoaderWithUpgrade is used to prepare baseapp with a fixed StoreLoader
|
|
||||||
// pattern. This is useful in test cases, or with custom upgrade loading logic.
|
|
||||||
func StoreLoaderWithUpgrade(upgrades *storetypes.StoreUpgrades) StoreLoader {
|
|
||||||
return func(ms sdk.CommitMultiStore) error {
|
|
||||||
return ms.LoadLatestVersionAndUpgrade(upgrades)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpgradeableStoreLoader can be configured by SetStoreLoader() to check for the
|
|
||||||
// existence of a given upgrade file - json encoded StoreUpgrades data.
|
|
||||||
//
|
|
||||||
// If not file is present, it will peform the default load (no upgrades to store).
|
|
||||||
//
|
|
||||||
// If the file is present, it will parse the file and execute those upgrades
|
|
||||||
// (rename or delete stores), while loading the data. It will also delete the
|
|
||||||
// upgrade file upon successful load, so that the upgrade is only applied once,
|
|
||||||
// and not re-applied on next restart
|
|
||||||
//
|
|
||||||
// This is useful for in place migrations when a store key is renamed between
|
|
||||||
// two versions of the software. (TODO: this code will move to x/upgrades
|
|
||||||
// when PR #4233 is merged, here mainly to help test the design)
|
|
||||||
func UpgradeableStoreLoader(upgradeInfoPath string) StoreLoader {
|
|
||||||
return func(ms sdk.CommitMultiStore) error {
|
|
||||||
_, err := os.Stat(upgradeInfoPath)
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return DefaultStoreLoader(ms)
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// there is a migration file, let's execute
|
|
||||||
data, err := ioutil.ReadFile(upgradeInfoPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read upgrade file %s: %v", upgradeInfoPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var upgrades storetypes.StoreUpgrades
|
|
||||||
err = json.Unmarshal(data, &upgrades)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot parse upgrade file: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ms.LoadLatestVersionAndUpgrade(&upgrades)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("load and upgrade database: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we have a successful load, we delete the file
|
|
||||||
err = os.Remove(upgradeInfoPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("deleting upgrade file %s: %v", upgradeInfoPath, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadVersion loads the BaseApp application version. It will panic if called
|
// LoadVersion loads the BaseApp application version. It will panic if called
|
||||||
// more than once on a running baseapp.
|
// more than once on a running baseapp.
|
||||||
func (app *BaseApp) LoadVersion(version int64, baseKey *sdk.KVStoreKey) error {
|
func (app *BaseApp) LoadVersion(version int64, baseKey *sdk.KVStoreKey) error {
|
||||||
|
@ -581,8 +521,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (gInfo sdk.
|
||||||
|
|
||||||
msgs := tx.GetMsgs()
|
msgs := tx.GetMsgs()
|
||||||
if err := validateBasicTxMsgs(msgs); err != nil {
|
if err := validateBasicTxMsgs(msgs); err != nil {
|
||||||
gInfo = sdk.GasInfo{GasUsed: ctx.BlockGasMeter().GasConsumed()}
|
return sdk.GasInfo{}, nil, err
|
||||||
return gInfo, nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.anteHandler != nil {
|
if app.anteHandler != nil {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -137,18 +136,6 @@ func useDefaultLoader(app *BaseApp) {
|
||||||
app.SetStoreLoader(DefaultStoreLoader)
|
app.SetStoreLoader(DefaultStoreLoader)
|
||||||
}
|
}
|
||||||
|
|
||||||
func useUpgradeLoader(upgrades *store.StoreUpgrades) func(*BaseApp) {
|
|
||||||
return func(app *BaseApp) {
|
|
||||||
app.SetStoreLoader(StoreLoaderWithUpgrade(upgrades))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func useFileUpgradeLoader(upgradeInfoPath string) func(*BaseApp) {
|
|
||||||
return func(app *BaseApp) {
|
|
||||||
app.SetStoreLoader(UpgradeableStoreLoader(upgradeInfoPath))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func initStore(t *testing.T, db dbm.DB, storeKey string, k, v []byte) {
|
func initStore(t *testing.T, db dbm.DB, storeKey string, k, v []byte) {
|
||||||
rs := rootmulti.NewStore(db)
|
rs := rootmulti.NewStore(db)
|
||||||
rs.SetPruning(store.PruneNothing)
|
rs.SetPruning(store.PruneNothing)
|
||||||
|
@ -184,19 +171,6 @@ func checkStore(t *testing.T, db dbm.DB, ver int64, storeKey string, k, v []byte
|
||||||
// Test that we can make commits and then reload old versions.
|
// Test that we can make commits and then reload old versions.
|
||||||
// Test that LoadLatestVersion actually does.
|
// Test that LoadLatestVersion actually does.
|
||||||
func TestSetLoader(t *testing.T) {
|
func TestSetLoader(t *testing.T) {
|
||||||
// write a renamer to a file
|
|
||||||
f, err := ioutil.TempFile("", "upgrade-*.json")
|
|
||||||
require.NoError(t, err)
|
|
||||||
data := []byte(`{"renamed":[{"old_key": "bnk", "new_key": "banker"}]}`)
|
|
||||||
_, err = f.Write(data)
|
|
||||||
require.NoError(t, err)
|
|
||||||
configName := f.Name()
|
|
||||||
require.NoError(t, f.Close())
|
|
||||||
|
|
||||||
// make sure it exists before running everything
|
|
||||||
_, err = os.Stat(configName)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
setLoader func(*BaseApp)
|
setLoader func(*BaseApp)
|
||||||
origStoreKey string
|
origStoreKey string
|
||||||
|
@ -211,26 +185,6 @@ func TestSetLoader(t *testing.T) {
|
||||||
origStoreKey: "foo",
|
origStoreKey: "foo",
|
||||||
loadStoreKey: "foo",
|
loadStoreKey: "foo",
|
||||||
},
|
},
|
||||||
"rename with inline opts": {
|
|
||||||
setLoader: useUpgradeLoader(&store.StoreUpgrades{
|
|
||||||
Renamed: []store.StoreRename{{
|
|
||||||
OldKey: "foo",
|
|
||||||
NewKey: "bar",
|
|
||||||
}},
|
|
||||||
}),
|
|
||||||
origStoreKey: "foo",
|
|
||||||
loadStoreKey: "bar",
|
|
||||||
},
|
|
||||||
"file loader with missing file": {
|
|
||||||
setLoader: useFileUpgradeLoader(configName + "randomchars"),
|
|
||||||
origStoreKey: "bnk",
|
|
||||||
loadStoreKey: "bnk",
|
|
||||||
},
|
|
||||||
"file loader with existing file": {
|
|
||||||
setLoader: useFileUpgradeLoader(configName),
|
|
||||||
origStoreKey: "bnk",
|
|
||||||
loadStoreKey: "banker",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
k := []byte("key")
|
k := []byte("key")
|
||||||
|
@ -265,10 +219,6 @@ func TestSetLoader(t *testing.T) {
|
||||||
checkStore(t, db, 2, tc.loadStoreKey, []byte("foo"), nil)
|
checkStore(t, db, 2, tc.loadStoreKey, []byte("foo"), nil)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure config file was deleted
|
|
||||||
_, err = os.Stat(configName)
|
|
||||||
require.True(t, os.IsNotExist(err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAppVersionSetterGetter(t *testing.T) {
|
func TestAppVersionSetterGetter(t *testing.T) {
|
||||||
|
|
|
@ -37,10 +37,10 @@ func TestValidateCmd(t *testing.T) {
|
||||||
args []string
|
args []string
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{"misspelled command", []string{"comission"}, true}, // nolint: misspell
|
{"misspelled command", []string{"commission"}, true}, // nolint: misspell
|
||||||
{"no command provided", []string{}, false},
|
{"no command provided", []string{}, false},
|
||||||
{"help flag", []string{"comission", "--help"}, false}, // nolint: misspell
|
{"help flag", []string{"commission", "--help"}, false}, // nolint: misspell
|
||||||
{"shorthand help flag", []string{"comission", "-h"}, false}, // nolint: misspell
|
{"shorthand help flag", []string{"commission", "-h"}, false}, // nolint: misspell
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
|
@ -3,10 +3,11 @@ package codec_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec/testdata"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
amino "github.com/tendermint/go-amino"
|
amino "github.com/tendermint/go-amino"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec/testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func createTestCodec() *amino.Codec {
|
func createTestCodec() *amino.Codec {
|
||||||
|
|
|
@ -3,9 +3,10 @@ package codec_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/codec/testdata"
|
"github.com/cosmos/cosmos-sdk/codec/testdata"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHybridCodec(t *testing.T) {
|
func TestHybridCodec(t *testing.T) {
|
||||||
|
|
|
@ -3,9 +3,10 @@ package codec_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/codec/testdata"
|
"github.com/cosmos/cosmos-sdk/codec/testdata"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestProtoCodec(t *testing.T) {
|
func TestProtoCodec(t *testing.T) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ various messages and index transactions."
|
||||||
Events are implemented in the Cosmos SDK as an alias of the ABCI `Event` type and
|
Events are implemented in the Cosmos SDK as an alias of the ABCI `Event` type and
|
||||||
take the form of: `{eventType}.{eventAttribute}={value}`.
|
take the form of: `{eventType}.{eventAttribute}={value}`.
|
||||||
|
|
||||||
+++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/types.pb.go#L2661-L2667
|
+++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/types.pb.go#L2187-L2193
|
||||||
|
|
||||||
Events contain:
|
Events contain:
|
||||||
|
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -9,7 +9,7 @@ require (
|
||||||
github.com/cosmos/ledger-cosmos-go v0.11.1
|
github.com/cosmos/ledger-cosmos-go v0.11.1
|
||||||
github.com/gogo/protobuf v1.3.1
|
github.com/gogo/protobuf v1.3.1
|
||||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129
|
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129
|
||||||
github.com/golang/protobuf v1.3.3
|
github.com/golang/protobuf v1.3.4
|
||||||
github.com/gorilla/handlers v1.4.2
|
github.com/gorilla/handlers v1.4.2
|
||||||
github.com/gorilla/mux v1.7.4
|
github.com/gorilla/mux v1.7.4
|
||||||
github.com/hashicorp/golang-lru v0.5.4
|
github.com/hashicorp/golang-lru v0.5.4
|
||||||
|
@ -35,4 +35,4 @@ require (
|
||||||
|
|
||||||
replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.1
|
replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.1
|
||||||
|
|
||||||
go 1.13
|
go 1.14
|
||||||
|
|
15
go.sum
15
go.sum
|
@ -35,7 +35,6 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
|
@ -45,7 +44,6 @@ github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6
|
||||||
github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
|
github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
|
||||||
github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI=
|
github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI=
|
||||||
github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI=
|
github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI=
|
||||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU=
|
github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU=
|
||||||
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
|
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
|
||||||
|
@ -95,6 +93,8 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||||
github.com/golang/protobuf v1.3.2/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 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
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/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
@ -194,8 +194,6 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/rakyll/statik v0.1.6 h1:uICcfUXpgqtw2VopbIncslhAmE5hwc4g20TEyEENBNs=
|
|
||||||
github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
|
|
||||||
github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
|
github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
|
||||||
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
|
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk=
|
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk=
|
||||||
|
@ -207,7 +205,6 @@ github.com/regen-network/protobuf v1.3.2-alpha.regen.1/go.mod h1:lye6mqhOn/GCw1z
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
@ -224,8 +221,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 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
|
||||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
|
||||||
github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs=
|
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 v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
@ -234,7 +229,6 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
|
||||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
|
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
|
||||||
github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=
|
github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=
|
||||||
|
@ -247,8 +241,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.0 h1:DMOzIV76tmoDNE9pX6RSN0aDtCYeCg5VueieJaAo1uw=
|
|
||||||
github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
|
||||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||||
|
@ -277,7 +269,6 @@ github.com/tendermint/tm-db v0.4.1 h1:TvX7JWjJOVZ+N3y+I86wddrGttOdMmmBxXcu0/Y7ZJ
|
||||||
github.com/tendermint/tm-db v0.4.1/go.mod h1:JsJ6qzYkCGiGwm5GHl/H5GLI9XLb6qZX7PRe425dHAY=
|
github.com/tendermint/tm-db v0.4.1/go.mod h1:JsJ6qzYkCGiGwm5GHl/H5GLI9XLb6qZX7PRe425dHAY=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
|
github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
|
||||||
|
@ -290,7 +281,6 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -325,7 +315,6 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
|
@ -122,7 +122,7 @@ type SimApp struct {
|
||||||
// NewSimApp returns a reference to an initialized SimApp.
|
// NewSimApp returns a reference to an initialized SimApp.
|
||||||
func NewSimApp(
|
func NewSimApp(
|
||||||
logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool,
|
logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool,
|
||||||
invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp),
|
homePath string, invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp),
|
||||||
) *SimApp {
|
) *SimApp {
|
||||||
|
|
||||||
// TODO: Remove cdc in favor of appCodec once all modules are migrated.
|
// TODO: Remove cdc in favor of appCodec once all modules are migrated.
|
||||||
|
@ -189,7 +189,7 @@ func NewSimApp(
|
||||||
app.CrisisKeeper = crisis.NewKeeper(
|
app.CrisisKeeper = crisis.NewKeeper(
|
||||||
app.subspaces[crisis.ModuleName], invCheckPeriod, app.SupplyKeeper, auth.FeeCollectorName,
|
app.subspaces[crisis.ModuleName], invCheckPeriod, app.SupplyKeeper, auth.FeeCollectorName,
|
||||||
)
|
)
|
||||||
app.UpgradeKeeper = upgrade.NewKeeper(skipUpgradeHeights, keys[upgrade.StoreKey], appCodec)
|
app.UpgradeKeeper = upgrade.NewKeeper(skipUpgradeHeights, keys[upgrade.StoreKey], appCodec, homePath)
|
||||||
|
|
||||||
// create evidence keeper with router
|
// create evidence keeper with router
|
||||||
evidenceKeeper := evidence.NewKeeper(
|
evidenceKeeper := evidence.NewKeeper(
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
func TestSimAppExport(t *testing.T) {
|
func TestSimAppExport(t *testing.T) {
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, 0)
|
app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0)
|
||||||
|
|
||||||
genesisState := NewDefaultGenesisState()
|
genesisState := NewDefaultGenesisState()
|
||||||
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
|
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
|
||||||
|
@ -31,7 +31,7 @@ func TestSimAppExport(t *testing.T) {
|
||||||
app.Commit()
|
app.Commit()
|
||||||
|
|
||||||
// Making a new app object with the db, so that initchain hasn't been called
|
// Making a new app object with the db, so that initchain hasn't been called
|
||||||
app2 := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, 0)
|
app2 := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0)
|
||||||
_, _, err = app2.ExportAppStateAndValidators(false, []string{})
|
_, _, err = app2.ExportAppStateAndValidators(false, []string{})
|
||||||
require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
|
require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ func TestSimAppExport(t *testing.T) {
|
||||||
// ensure that black listed addresses are properly set in bank keeper
|
// ensure that black listed addresses are properly set in bank keeper
|
||||||
func TestBlackListedAddrs(t *testing.T) {
|
func TestBlackListedAddrs(t *testing.T) {
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, 0)
|
app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0)
|
||||||
|
|
||||||
for acc := range maccPerms {
|
for acc := range maccPerms {
|
||||||
require.Equal(t, !allowedReceivingModAcc[acc], app.BankKeeper.BlacklistedAddr(app.SupplyKeeper.GetModuleAddress(acc)))
|
require.Equal(t, !allowedReceivingModAcc[acc], app.BankKeeper.BlacklistedAddr(app.SupplyKeeper.GetModuleAddress(acc)))
|
||||||
|
|
|
@ -26,7 +26,7 @@ func BenchmarkFullAppSimulation(b *testing.B) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, interBlockCacheOpt())
|
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, interBlockCacheOpt())
|
||||||
|
|
||||||
// run randomized simulation
|
// run randomized simulation
|
||||||
_, simParams, simErr := simulation.SimulateFromSeed(
|
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||||
|
@ -65,7 +65,7 @@ func BenchmarkInvariants(b *testing.B) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, interBlockCacheOpt())
|
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, interBlockCacheOpt())
|
||||||
|
|
||||||
// run randomized simulation
|
// run randomized simulation
|
||||||
_, simParams, simErr := simulation.SimulateFromSeed(
|
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||||
|
|
|
@ -63,7 +63,7 @@ func TestFullAppSimulation(t *testing.T) {
|
||||||
require.NoError(t, os.RemoveAll(dir))
|
require.NoError(t, os.RemoveAll(dir))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt)
|
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt)
|
||||||
require.Equal(t, "SimApp", app.Name())
|
require.Equal(t, "SimApp", app.Name())
|
||||||
|
|
||||||
// run randomized simulation
|
// run randomized simulation
|
||||||
|
@ -95,7 +95,7 @@ func TestAppImportExport(t *testing.T) {
|
||||||
require.NoError(t, os.RemoveAll(dir))
|
require.NoError(t, os.RemoveAll(dir))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt)
|
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt)
|
||||||
require.Equal(t, "SimApp", app.Name())
|
require.Equal(t, "SimApp", app.Name())
|
||||||
|
|
||||||
// Run randomized simulation
|
// Run randomized simulation
|
||||||
|
@ -129,7 +129,7 @@ func TestAppImportExport(t *testing.T) {
|
||||||
require.NoError(t, os.RemoveAll(newDir))
|
require.NoError(t, os.RemoveAll(newDir))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt)
|
newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt)
|
||||||
require.Equal(t, "SimApp", newApp.Name())
|
require.Equal(t, "SimApp", newApp.Name())
|
||||||
|
|
||||||
var genesisState GenesisState
|
var genesisState GenesisState
|
||||||
|
@ -181,7 +181,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
||||||
require.NoError(t, os.RemoveAll(dir))
|
require.NoError(t, os.RemoveAll(dir))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt)
|
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt)
|
||||||
require.Equal(t, "SimApp", app.Name())
|
require.Equal(t, "SimApp", app.Name())
|
||||||
|
|
||||||
// Run randomized simulation
|
// Run randomized simulation
|
||||||
|
@ -220,7 +220,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
||||||
require.NoError(t, os.RemoveAll(newDir))
|
require.NoError(t, os.RemoveAll(newDir))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt)
|
newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt)
|
||||||
require.Equal(t, "SimApp", newApp.Name())
|
require.Equal(t, "SimApp", newApp.Name())
|
||||||
|
|
||||||
newApp.InitChain(abci.RequestInitChain{
|
newApp.InitChain(abci.RequestInitChain{
|
||||||
|
@ -266,7 +266,7 @@ func TestAppStateDeterminism(t *testing.T) {
|
||||||
|
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
|
|
||||||
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, interBlockCacheOpt())
|
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, interBlockCacheOpt())
|
||||||
|
|
||||||
fmt.Printf(
|
fmt.Printf(
|
||||||
"running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n",
|
"running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n",
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package simapp
|
package simapp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -23,7 +27,7 @@ import (
|
||||||
// Setup initializes a new SimApp. A Nop logger is set in SimApp.
|
// Setup initializes a new SimApp. A Nop logger is set in SimApp.
|
||||||
func Setup(isCheckTx bool) *SimApp {
|
func Setup(isCheckTx bool) *SimApp {
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0)
|
app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0)
|
||||||
if !isCheckTx {
|
if !isCheckTx {
|
||||||
// init chain must be called to stop deliverState from being nil
|
// init chain must be called to stop deliverState from being nil
|
||||||
genesisState := NewDefaultGenesisState()
|
genesisState := NewDefaultGenesisState()
|
||||||
|
@ -48,7 +52,7 @@ func Setup(isCheckTx bool) *SimApp {
|
||||||
// accounts and possible balances.
|
// accounts and possible balances.
|
||||||
func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances ...bank.Balance) *SimApp {
|
func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances ...bank.Balance) *SimApp {
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0)
|
app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0)
|
||||||
|
|
||||||
// initialize the chain with the passed in genesis accounts
|
// initialize the chain with the passed in genesis accounts
|
||||||
genesisState := NewDefaultGenesisState()
|
genesisState := NewDefaultGenesisState()
|
||||||
|
@ -77,15 +81,56 @@ func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances ..
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTestAddrs constructs and returns accNum amount of accounts with an
|
type GenerateAccountStrategy func(int) []sdk.AccAddress
|
||||||
// initial balance of accAmt
|
|
||||||
func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress {
|
// createRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order.
|
||||||
|
func createRandomAccounts(accNum int) []sdk.AccAddress {
|
||||||
testAddrs := make([]sdk.AccAddress, accNum)
|
testAddrs := make([]sdk.AccAddress, accNum)
|
||||||
for i := 0; i < accNum; i++ {
|
for i := 0; i < accNum; i++ {
|
||||||
pk := ed25519.GenPrivKey().PubKey()
|
pk := ed25519.GenPrivKey().PubKey()
|
||||||
testAddrs[i] = sdk.AccAddress(pk.Address())
|
testAddrs[i] = sdk.AccAddress(pk.Address())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return testAddrs
|
||||||
|
}
|
||||||
|
|
||||||
|
// createIncrementalAccounts is a strategy used by addTestAddrs() in order to generated addresses in ascending order.
|
||||||
|
func createIncrementalAccounts(accNum int) []sdk.AccAddress {
|
||||||
|
var addresses []sdk.AccAddress
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
|
// start at 100 so we can make up to 999 test addresses with valid test addresses
|
||||||
|
for i := 100; i < (accNum + 100); i++ {
|
||||||
|
numString := strconv.Itoa(i)
|
||||||
|
buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string
|
||||||
|
|
||||||
|
buffer.WriteString(numString) //adding on final two digits to make addresses unique
|
||||||
|
res, _ := sdk.AccAddressFromHex(buffer.String())
|
||||||
|
bech := res.String()
|
||||||
|
addr, _ := TestAddr(buffer.String(), bech)
|
||||||
|
|
||||||
|
addresses = append(addresses, addr)
|
||||||
|
buffer.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
return addresses
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTestAddrs constructs and returns accNum amount of accounts with an
|
||||||
|
// initial balance of accAmt in random order
|
||||||
|
func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress {
|
||||||
|
return addTestAddrs(app, ctx, accNum, accAmt, createRandomAccounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTestAddrs constructs and returns accNum amount of accounts with an
|
||||||
|
// initial balance of accAmt in random order
|
||||||
|
func AddTestAddrsIncremental(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress {
|
||||||
|
return addTestAddrs(app, ctx, accNum, accAmt, createIncrementalAccounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, strategy GenerateAccountStrategy) []sdk.AccAddress {
|
||||||
|
testAddrs := strategy(accNum)
|
||||||
|
|
||||||
initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt))
|
initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt))
|
||||||
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt.MulRaw(int64(len(testAddrs)))))
|
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt.MulRaw(int64(len(testAddrs)))))
|
||||||
prevSupply := app.SupplyKeeper.GetSupply(ctx)
|
prevSupply := app.SupplyKeeper.GetSupply(ctx)
|
||||||
|
@ -104,6 +149,38 @@ func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sd
|
||||||
return testAddrs
|
return testAddrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConvertAddrsToValAddrs converts the provided addresses to ValAddress.
|
||||||
|
func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress {
|
||||||
|
valAddrs := make([]sdk.ValAddress, len(addrs))
|
||||||
|
|
||||||
|
for i, addr := range addrs {
|
||||||
|
valAddrs[i] = sdk.ValAddress(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return valAddrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddr(addr string, bech string) (sdk.AccAddress, error) {
|
||||||
|
res, err := sdk.AccAddressFromHex(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bechexpected := res.String()
|
||||||
|
if bech != bechexpected {
|
||||||
|
return nil, fmt.Errorf("bech encoding doesn't match reference")
|
||||||
|
}
|
||||||
|
|
||||||
|
bechres, err := sdk.AccAddressFromBech32(bech)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !bytes.Equal(bechres, res) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CheckBalance checks the balance of an account.
|
// CheckBalance checks the balance of an account.
|
||||||
func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) {
|
func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) {
|
||||||
ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
|
ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
|
||||||
|
@ -187,3 +264,31 @@ func incrementAllSequenceNumbers(initSeqNums []uint64) {
|
||||||
initSeqNums[i]++
|
initSeqNums[i]++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateTestPubKeys returns a total of numPubKeys public keys in ascending order.
|
||||||
|
func CreateTestPubKeys(numPubKeys int) []crypto.PubKey {
|
||||||
|
var publicKeys []crypto.PubKey
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
|
// start at 10 to avoid changing 1 to 01, 2 to 02, etc
|
||||||
|
for i := 100; i < (numPubKeys + 100); i++ {
|
||||||
|
numString := strconv.Itoa(i)
|
||||||
|
buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") // base pubkey string
|
||||||
|
buffer.WriteString(numString) // adding on final two digits to make pubkeys unique
|
||||||
|
publicKeys = append(publicKeys, NewPubKeyFromHex(buffer.String()))
|
||||||
|
buffer.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
return publicKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPubKeyFromHex returns a PubKey from a hex string.
|
||||||
|
func NewPubKeyFromHex(pk string) (res crypto.PubKey) {
|
||||||
|
pkBytes, err := hex.DecodeString(pk)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
var pkEd ed25519.PubKeyEd25519
|
||||||
|
copy(pkEd[:], pkBytes)
|
||||||
|
return pkEd
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,13 @@ type StoreUpgrades struct {
|
||||||
Deleted []string `json:"deleted"`
|
Deleted []string `json:"deleted"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpgradeInfo defines height and name of the upgrade
|
||||||
|
// to ensure multistore upgrades happen only at matching height.
|
||||||
|
type UpgradeInfo struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Height int64 `json:"height"`
|
||||||
|
}
|
||||||
|
|
||||||
// StoreRename defines a name change of a sub-store.
|
// StoreRename defines a name change of a sub-store.
|
||||||
// All data previously under a PrefixStore with OldKey will be copied
|
// All data previously under a PrefixStore with OldKey will be copied
|
||||||
// to a PrefixStore with NewKey, then deleted from OldKey store.
|
// to a PrefixStore with NewKey, then deleted from OldKey store.
|
||||||
|
|
|
@ -5,9 +5,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/types"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,11 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// create a decimal from a decimal string (ex. "1234.5678")
|
// create a decimal from a decimal string (ex. "1234.5678")
|
||||||
|
|
|
@ -2,7 +2,6 @@ package version
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
@ -21,29 +20,31 @@ func init() {
|
||||||
var Cmd = &cobra.Command{
|
var Cmd = &cobra.Command{
|
||||||
Use: "version",
|
Use: "version",
|
||||||
Short: "Print the app version",
|
Short: "Print the app version",
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
RunE: runVersionCmd,
|
||||||
verInfo := NewInfo()
|
}
|
||||||
|
|
||||||
if !viper.GetBool(flagLong) {
|
func runVersionCmd(cmd *cobra.Command, args []string) error {
|
||||||
fmt.Println(verInfo.Version)
|
verInfo := NewInfo()
|
||||||
return nil
|
|
||||||
}
|
if !viper.GetBool(flagLong) {
|
||||||
|
cmd.Println(verInfo.Version)
|
||||||
var bz []byte
|
return nil
|
||||||
var err error
|
}
|
||||||
|
|
||||||
switch viper.GetString(cli.OutputFlag) {
|
var bz []byte
|
||||||
case "json":
|
var err error
|
||||||
bz, err = json.Marshal(verInfo)
|
|
||||||
default:
|
switch viper.GetString(cli.OutputFlag) {
|
||||||
bz, err = yaml.Marshal(&verInfo)
|
case "json":
|
||||||
}
|
bz, err = json.Marshal(verInfo)
|
||||||
|
default:
|
||||||
if err != nil {
|
bz, err = yaml.Marshal(&verInfo)
|
||||||
return err
|
}
|
||||||
}
|
|
||||||
|
if err != nil {
|
||||||
_, err = fmt.Println(string(bz))
|
return err
|
||||||
return err
|
}
|
||||||
},
|
|
||||||
|
cmd.Println(string(bz))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/tendermint/tendermint/libs/cli"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/tests"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewInfo(t *testing.T) {
|
||||||
|
info := NewInfo()
|
||||||
|
want := fmt.Sprintf(`:
|
||||||
|
git commit:
|
||||||
|
build tags:
|
||||||
|
%s`, fmt.Sprintf("go version %s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH))
|
||||||
|
require.Equal(t, want, info.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInfo_String(t *testing.T) {
|
||||||
|
info := Info{
|
||||||
|
Name: "testapp",
|
||||||
|
ServerName: "testappd",
|
||||||
|
ClientName: "testappcli",
|
||||||
|
Version: "1.0.0",
|
||||||
|
GitCommit: "1b78457135a4104bc3af97f20654d49e2ea87454",
|
||||||
|
BuildTags: "netgo,ledger",
|
||||||
|
GoVersion: "go version go1.14 linux/amd64",
|
||||||
|
}
|
||||||
|
want := fmt.Sprintf(`testapp: 1.0.0
|
||||||
|
git commit: 1b78457135a4104bc3af97f20654d49e2ea87454
|
||||||
|
build tags: netgo,ledger
|
||||||
|
go version go1.14 linux/amd64`)
|
||||||
|
require.Equal(t, want, info.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_runVersionCmd(t *testing.T) {
|
||||||
|
require.NotNil(t, Cmd)
|
||||||
|
_, mockOut, _ := tests.ApplyMockIO(Cmd)
|
||||||
|
|
||||||
|
viper.Set(cli.OutputFlag, "")
|
||||||
|
viper.Set(flagLong, false)
|
||||||
|
require.NoError(t, runVersionCmd(Cmd, nil))
|
||||||
|
assert.Equal(t, "\n", mockOut.String())
|
||||||
|
mockOut.Reset()
|
||||||
|
|
||||||
|
viper.Set(cli.OutputFlag, "json")
|
||||||
|
viper.Set(flagLong, true)
|
||||||
|
info := NewInfo()
|
||||||
|
stringInfo, err := json.Marshal(info)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, runVersionCmd(Cmd, nil))
|
||||||
|
assert.Equal(t, string(stringInfo)+"\n", mockOut.String())
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
package rest
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterRoutes - Central function to define routes that get registered by the main application
|
// RegisterRoutes - Central function to define routes that get registered by the main application
|
||||||
|
|
|
@ -3,9 +3,10 @@ package types_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func cloneAppend(bz []byte, tail []byte) (res []byte) {
|
func cloneAppend(bz []byte, tail []byte) (res []byte) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ var (
|
||||||
|
|
||||||
func createTestApp() (*simapp.SimApp, sdk.Context, []sdk.AccAddress) {
|
func createTestApp() (*simapp.SimApp, sdk.Context, []sdk.AccAddress) {
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 1)
|
app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 1)
|
||||||
ctx := app.NewContext(true, abci.Header{})
|
ctx := app.NewContext(true, abci.Header{})
|
||||||
|
|
||||||
constantFee := sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)
|
constantFee := sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
func createTestApp() *simapp.SimApp {
|
func createTestApp() *simapp.SimApp {
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 5)
|
app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5)
|
||||||
// init chain must be called to stop deliverState from being nil
|
// init chain must be called to stop deliverState from being nil
|
||||||
genesisState := simapp.NewDefaultGenesisState()
|
genesisState := simapp.NewDefaultGenesisState()
|
||||||
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
|
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
|
||||||
|
|
|
@ -63,7 +63,7 @@ func TestImportExportQueues(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
app2 := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0)
|
app2 := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 0)
|
||||||
|
|
||||||
app2.InitChain(
|
app2.InitChain(
|
||||||
abci.RequestInitChain{
|
abci.RequestInitChain{
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package keeper_test
|
package keeper_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
dbm "github.com/tendermint/tm-db"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/store"
|
"github.com/cosmos/cosmos-sdk/store"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
|
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
|
||||||
"github.com/cosmos/cosmos-sdk/x/params/types/proposal"
|
"github.com/cosmos/cosmos-sdk/x/params/types/proposal"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
|
||||||
dbm "github.com/tendermint/tm-db"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func testComponents() (codec.Marshaler, sdk.Context, sdk.StoreKey, sdk.StoreKey, paramskeeper.Keeper) {
|
func testComponents() (codec.Marshaler, sdk.Context, sdk.StoreKey, sdk.StoreKey, paramskeeper.Keeper) {
|
||||||
|
|
|
@ -4,10 +4,11 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/params/types"
|
"github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateNoOp(_ interface{}) error { return nil }
|
func validateNoOp(_ interface{}) error { return nil }
|
||||||
|
|
|
@ -4,8 +4,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/params/types"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestKeyTable(t *testing.T) {
|
func TestKeyTable(t *testing.T) {
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
package staking_test
|
package staking_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
"github.com/tendermint/tendermint/crypto"
|
"github.com/tendermint/tendermint/crypto"
|
||||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
|
cdc "github.com/cosmos/cosmos-sdk/simapp/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,16 +20,10 @@ var (
|
||||||
addr1 = sdk.AccAddress(priv1.PubKey().Address())
|
addr1 = sdk.AccAddress(priv1.PubKey().Address())
|
||||||
priv2 = secp256k1.GenPrivKey()
|
priv2 = secp256k1.GenPrivKey()
|
||||||
addr2 = sdk.AccAddress(priv2.PubKey().Address())
|
addr2 = sdk.AccAddress(priv2.PubKey().Address())
|
||||||
addr3 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
|
|
||||||
priv4 = secp256k1.GenPrivKey()
|
|
||||||
addr4 = sdk.AccAddress(priv4.PubKey().Address())
|
|
||||||
coins = sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(10))}
|
|
||||||
fee = auth.NewStdFee(
|
|
||||||
100000,
|
|
||||||
sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(0))},
|
|
||||||
)
|
|
||||||
|
|
||||||
commissionRates = staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
commissionRates = staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
||||||
|
|
||||||
|
PKs = simapp.CreateTestPubKeys(500)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) staking.MsgCreateValidator {
|
func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) staking.MsgCreateValidator {
|
||||||
|
@ -38,3 +36,31 @@ func NewTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk.
|
||||||
amount := sdk.NewCoin(sdk.DefaultBondDenom, amt)
|
amount := sdk.NewCoin(sdk.DefaultBondDenom, amt)
|
||||||
return staking.NewMsgDelegate(delAddr, valAddr, amount)
|
return staking.NewMsgDelegate(delAddr, valAddr, amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getBaseSimappWithCustomKeeper Returns a simapp with custom StakingKeeper
|
||||||
|
// to avoid messing with the hooks.
|
||||||
|
func getBaseSimappWithCustomKeeper() (*codec.Codec, *simapp.SimApp, sdk.Context) {
|
||||||
|
app := simapp.Setup(false)
|
||||||
|
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
|
||||||
|
appCodec := cdc.NewAppCodec(codec.New())
|
||||||
|
|
||||||
|
app.StakingKeeper = keeper.NewKeeper(
|
||||||
|
appCodec,
|
||||||
|
app.GetKey(staking.StoreKey),
|
||||||
|
app.BankKeeper,
|
||||||
|
app.SupplyKeeper,
|
||||||
|
app.GetSubspace(staking.ModuleName),
|
||||||
|
)
|
||||||
|
app.StakingKeeper.SetParams(ctx, types.DefaultParams())
|
||||||
|
|
||||||
|
return codec.New(), app, ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateAddresses generates numAddrs of normal AccAddrs and ValAddrs
|
||||||
|
func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int, accAmount int64) ([]sdk.AccAddress, []sdk.ValAddress) {
|
||||||
|
addrDels := simapp.AddTestAddrsIncremental(app, ctx, numAddrs, sdk.NewInt(accAmount))
|
||||||
|
addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
|
||||||
|
|
||||||
|
return addrDels, addrVals
|
||||||
|
}
|
||||||
|
|
|
@ -1,64 +1,83 @@
|
||||||
package staking
|
package staking_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
keep "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func bootstrapGenesisTest(t *testing.T, power int64, numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) {
|
||||||
|
_, app, ctx := getBaseSimappWithCustomKeeper()
|
||||||
|
|
||||||
|
addrDels, addrVals := generateAddresses(app, ctx, numAddrs, 10000)
|
||||||
|
|
||||||
|
amt := sdk.TokensFromConsensusPower(power)
|
||||||
|
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels)))))
|
||||||
|
|
||||||
|
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
|
err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply)
|
||||||
|
require.NoError(t, err)
|
||||||
|
app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool)
|
||||||
|
|
||||||
|
app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
|
||||||
|
|
||||||
|
return app, ctx, addrDels, addrVals
|
||||||
|
}
|
||||||
|
|
||||||
func TestInitGenesis(t *testing.T) {
|
func TestInitGenesis(t *testing.T) {
|
||||||
ctx, accKeeper, bk, keeper, supplyKeeper := keep.CreateTestInput(t, false, 1000)
|
app, ctx, addrs, _ := bootstrapGenesisTest(t, 1000, 10)
|
||||||
|
|
||||||
valTokens := sdk.TokensFromConsensusPower(1)
|
valTokens := sdk.TokensFromConsensusPower(1)
|
||||||
|
|
||||||
params := keeper.GetParams(ctx)
|
params := app.StakingKeeper.GetParams(ctx)
|
||||||
validators := make([]Validator, 2)
|
validators := make([]types.Validator, 2)
|
||||||
var delegations []Delegation
|
var delegations []types.Delegation
|
||||||
|
|
||||||
pk0, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, keep.PKs[0])
|
pk0, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, PKs[0])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pk1, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, keep.PKs[1])
|
pk1, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, PKs[1])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// initialize the validators
|
// initialize the validators
|
||||||
validators[0].OperatorAddress = sdk.ValAddress(keep.Addrs[0])
|
validators[0].OperatorAddress = sdk.ValAddress(addrs[0])
|
||||||
validators[0].ConsensusPubkey = pk0
|
validators[0].ConsensusPubkey = pk0
|
||||||
validators[0].Description = NewDescription("hoop", "", "", "", "")
|
validators[0].Description = types.NewDescription("hoop", "", "", "", "")
|
||||||
validators[0].Status = sdk.Bonded
|
validators[0].Status = sdk.Bonded
|
||||||
validators[0].Tokens = valTokens
|
validators[0].Tokens = valTokens
|
||||||
validators[0].DelegatorShares = valTokens.ToDec()
|
validators[0].DelegatorShares = valTokens.ToDec()
|
||||||
validators[1].OperatorAddress = sdk.ValAddress(keep.Addrs[1])
|
validators[1].OperatorAddress = sdk.ValAddress(addrs[1])
|
||||||
validators[1].ConsensusPubkey = pk1
|
validators[1].ConsensusPubkey = pk1
|
||||||
validators[1].Description = NewDescription("bloop", "", "", "", "")
|
validators[1].Description = types.NewDescription("bloop", "", "", "", "")
|
||||||
validators[1].Status = sdk.Bonded
|
validators[1].Status = sdk.Bonded
|
||||||
validators[1].Tokens = valTokens
|
validators[1].Tokens = valTokens
|
||||||
validators[1].DelegatorShares = valTokens.ToDec()
|
validators[1].DelegatorShares = valTokens.ToDec()
|
||||||
|
|
||||||
genesisState := types.NewGenesisState(params, validators, delegations)
|
genesisState := types.NewGenesisState(params, validators, delegations)
|
||||||
vals := InitGenesis(ctx, keeper, accKeeper, bk, supplyKeeper, genesisState)
|
vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.SupplyKeeper, genesisState)
|
||||||
|
|
||||||
actualGenesis := ExportGenesis(ctx, keeper)
|
actualGenesis := staking.ExportGenesis(ctx, app.StakingKeeper)
|
||||||
require.Equal(t, genesisState.Params, actualGenesis.Params)
|
require.Equal(t, genesisState.Params, actualGenesis.Params)
|
||||||
require.Equal(t, genesisState.Delegations, actualGenesis.Delegations)
|
require.Equal(t, genesisState.Delegations, actualGenesis.Delegations)
|
||||||
require.EqualValues(t, keeper.GetAllValidators(ctx), actualGenesis.Validators)
|
require.EqualValues(t, app.StakingKeeper.GetAllValidators(ctx), actualGenesis.Validators)
|
||||||
|
|
||||||
// now make sure the validators are bonded and intra-tx counters are correct
|
// now make sure the validators are bonded and intra-tx counters are correct
|
||||||
resVal, found := keeper.GetValidator(ctx, sdk.ValAddress(keep.Addrs[0]))
|
resVal, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[0]))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, sdk.Bonded, resVal.Status)
|
require.Equal(t, sdk.Bonded, resVal.Status)
|
||||||
|
|
||||||
resVal, found = keeper.GetValidator(ctx, sdk.ValAddress(keep.Addrs[1]))
|
resVal, found = app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[1]))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, sdk.Bonded, resVal.Status)
|
require.Equal(t, sdk.Bonded, resVal.Status)
|
||||||
|
|
||||||
|
@ -74,15 +93,15 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
|
||||||
size := 200
|
size := 200
|
||||||
require.True(t, size > 100)
|
require.True(t, size > 100)
|
||||||
|
|
||||||
ctx, accKeeper, bk, keeper, supplyKeeper := keep.CreateTestInput(t, false, 1000)
|
app, ctx, addrs, _ := bootstrapGenesisTest(t, 1000, 200)
|
||||||
|
|
||||||
params := keeper.GetParams(ctx)
|
params := app.StakingKeeper.GetParams(ctx)
|
||||||
delegations := []Delegation{}
|
delegations := []types.Delegation{}
|
||||||
validators := make([]Validator, size)
|
validators := make([]types.Validator, size)
|
||||||
|
|
||||||
for i := range validators {
|
for i := range validators {
|
||||||
validators[i] = NewValidator(sdk.ValAddress(keep.Addrs[i]),
|
validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]),
|
||||||
keep.PKs[i], NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""))
|
PKs[i], types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""))
|
||||||
|
|
||||||
validators[i].Status = sdk.Bonded
|
validators[i].Status = sdk.Bonded
|
||||||
|
|
||||||
|
@ -95,7 +114,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
genesisState := types.NewGenesisState(params, validators, delegations)
|
genesisState := types.NewGenesisState(params, validators, delegations)
|
||||||
vals := InitGenesis(ctx, keeper, accKeeper, bk, supplyKeeper, genesisState)
|
vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.SupplyKeeper, genesisState)
|
||||||
|
|
||||||
abcivals := make([]abci.ValidatorUpdate, 100)
|
abcivals := make([]abci.ValidatorUpdate, 100)
|
||||||
for i, val := range validators[:100] {
|
for i, val := range validators[:100] {
|
||||||
|
@ -140,9 +159,9 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
genesisState := types.DefaultGenesisState()
|
genesisState := types.DefaultGenesisState()
|
||||||
tt.mutate(&genesisState)
|
tt.mutate(&genesisState)
|
||||||
if tt.wantErr {
|
if tt.wantErr {
|
||||||
assert.Error(t, ValidateGenesis(genesisState))
|
assert.Error(t, staking.ValidateGenesis(genesisState))
|
||||||
} else {
|
} else {
|
||||||
assert.NoError(t, ValidateGenesis(genesisState))
|
assert.NoError(t, staking.ValidateGenesis(genesisState))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
||||||
|
package keeper_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
|
cdc "github.com/cosmos/cosmos-sdk/simapp/codec"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
PKs = simapp.CreateTestPubKeys(500)
|
||||||
|
)
|
||||||
|
|
||||||
|
// createTestInput Returns a simapp with custom StakingKeeper
|
||||||
|
// to avoid messing with the hooks.
|
||||||
|
func createTestInput() (*codec.Codec, *simapp.SimApp, sdk.Context) {
|
||||||
|
app := simapp.Setup(false)
|
||||||
|
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
|
||||||
|
appCodec := cdc.NewAppCodec(codec.New())
|
||||||
|
|
||||||
|
app.StakingKeeper = keeper.NewKeeper(
|
||||||
|
appCodec,
|
||||||
|
app.GetKey(staking.StoreKey),
|
||||||
|
app.BankKeeper,
|
||||||
|
app.SupplyKeeper,
|
||||||
|
app.GetSubspace(staking.ModuleName),
|
||||||
|
)
|
||||||
|
|
||||||
|
return codec.New(), app, ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
// intended to be used with require/assert: require.True(ValEq(...))
|
||||||
|
func ValEq(t *testing.T, exp, got types.Validator) (*testing.T, bool, string, types.Validator, types.Validator) {
|
||||||
|
return t, exp.MinEqual(got), "expected:\n%v\ngot:\n%v", exp, got
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateAddresses generates numAddrs of normal AccAddrs and ValAddrs
|
||||||
|
func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int) ([]sdk.AccAddress, []sdk.ValAddress) {
|
||||||
|
addrDels := simapp.AddTestAddrsIncremental(app, ctx, numAddrs, sdk.NewInt(10000))
|
||||||
|
addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
|
||||||
|
|
||||||
|
return addrDels, addrVals
|
||||||
|
}
|
|
@ -548,7 +548,7 @@ func (k Keeper) Delegate(
|
||||||
}
|
}
|
||||||
|
|
||||||
// unbond a particular delegation and perform associated store operations
|
// unbond a particular delegation and perform associated store operations
|
||||||
func (k Keeper) unbond(
|
func (k Keeper) Unbond(
|
||||||
ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec,
|
ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec,
|
||||||
) (amount sdk.Int, err error) {
|
) (amount sdk.Int, err error) {
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ func (k Keeper) Undelegate(
|
||||||
return time.Time{}, types.ErrMaxUnbondingDelegationEntries
|
return time.Time{}, types.ErrMaxUnbondingDelegationEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
returnAmount, err := k.unbond(ctx, delAddr, valAddr, sharesAmount)
|
returnAmount, err := k.Unbond(ctx, delAddr, valAddr, sharesAmount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, err
|
return time.Time{}, err
|
||||||
}
|
}
|
||||||
|
@ -751,7 +751,7 @@ func (k Keeper) BeginRedelegation(
|
||||||
return time.Time{}, types.ErrMaxRedelegationEntries
|
return time.Time{}, types.ErrMaxRedelegationEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
returnAmount, err := k.unbond(ctx, delAddr, valSrcAddr, sharesAmount)
|
returnAmount, err := k.Unbond(ctx, delAddr, valSrcAddr, sharesAmount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, err
|
return time.Time{}, err
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,13 @@
|
||||||
package keeper
|
package keeper_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -12,7 +15,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHistoricalInfo(t *testing.T) {
|
func TestHistoricalInfo(t *testing.T) {
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10)
|
_, app, ctx := createTestInput()
|
||||||
|
|
||||||
|
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0))
|
||||||
|
addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
|
||||||
|
|
||||||
validators := make([]types.Validator, len(addrVals))
|
validators := make([]types.Validator, len(addrVals))
|
||||||
|
|
||||||
for i, valAddr := range addrVals {
|
for i, valAddr := range addrVals {
|
||||||
|
@ -21,27 +28,30 @@ func TestHistoricalInfo(t *testing.T) {
|
||||||
|
|
||||||
hi := types.NewHistoricalInfo(ctx.BlockHeader(), validators)
|
hi := types.NewHistoricalInfo(ctx.BlockHeader(), validators)
|
||||||
|
|
||||||
keeper.SetHistoricalInfo(ctx, 2, hi)
|
app.StakingKeeper.SetHistoricalInfo(ctx, 2, hi)
|
||||||
|
|
||||||
recv, found := keeper.GetHistoricalInfo(ctx, 2)
|
recv, found := app.StakingKeeper.GetHistoricalInfo(ctx, 2)
|
||||||
require.True(t, found, "HistoricalInfo not found after set")
|
require.True(t, found, "HistoricalInfo not found after set")
|
||||||
require.Equal(t, hi, recv, "HistoricalInfo not equal")
|
require.Equal(t, hi, recv, "HistoricalInfo not equal")
|
||||||
require.True(t, sort.IsSorted(types.Validators(recv.Valset)), "HistoricalInfo validators is not sorted")
|
require.True(t, sort.IsSorted(types.Validators(recv.Valset)), "HistoricalInfo validators is not sorted")
|
||||||
|
|
||||||
keeper.DeleteHistoricalInfo(ctx, 2)
|
app.StakingKeeper.DeleteHistoricalInfo(ctx, 2)
|
||||||
|
|
||||||
recv, found = keeper.GetHistoricalInfo(ctx, 2)
|
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 2)
|
||||||
require.False(t, found, "HistoricalInfo found after delete")
|
require.False(t, found, "HistoricalInfo found after delete")
|
||||||
require.Equal(t, types.HistoricalInfo{}, recv, "HistoricalInfo is not empty")
|
require.Equal(t, types.HistoricalInfo{}, recv, "HistoricalInfo is not empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackHistoricalInfo(t *testing.T) {
|
func TestTrackHistoricalInfo(t *testing.T) {
|
||||||
ctx, _, _, k, _ := CreateTestInput(t, false, 10)
|
_, app, ctx := createTestInput()
|
||||||
|
|
||||||
|
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0))
|
||||||
|
addrVals := simapp.ConvertAddrsToValAddrs(addrDels)
|
||||||
|
|
||||||
// set historical entries in params to 5
|
// set historical entries in params to 5
|
||||||
params := types.DefaultParams()
|
params := types.DefaultParams()
|
||||||
params.HistoricalEntries = 5
|
params.HistoricalEntries = 5
|
||||||
k.SetParams(ctx, params)
|
app.StakingKeeper.SetParams(ctx, params)
|
||||||
|
|
||||||
// set historical info at 5, 4 which should be pruned
|
// set historical info at 5, 4 which should be pruned
|
||||||
// and check that it has been stored
|
// and check that it has been stored
|
||||||
|
@ -54,29 +64,29 @@ func TestTrackHistoricalInfo(t *testing.T) {
|
||||||
Height: 5,
|
Height: 5,
|
||||||
}
|
}
|
||||||
valSet := []types.Validator{
|
valSet := []types.Validator{
|
||||||
types.NewValidator(sdk.ValAddress(Addrs[0]), PKs[0], types.Description{}),
|
types.NewValidator(addrVals[0], PKs[0], types.Description{}),
|
||||||
types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}),
|
types.NewValidator(addrVals[1], PKs[1], types.Description{}),
|
||||||
}
|
}
|
||||||
hi4 := types.NewHistoricalInfo(h4, valSet)
|
hi4 := types.NewHistoricalInfo(h4, valSet)
|
||||||
hi5 := types.NewHistoricalInfo(h5, valSet)
|
hi5 := types.NewHistoricalInfo(h5, valSet)
|
||||||
k.SetHistoricalInfo(ctx, 4, hi4)
|
app.StakingKeeper.SetHistoricalInfo(ctx, 4, hi4)
|
||||||
k.SetHistoricalInfo(ctx, 5, hi5)
|
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi5)
|
||||||
recv, found := k.GetHistoricalInfo(ctx, 4)
|
recv, found := app.StakingKeeper.GetHistoricalInfo(ctx, 4)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, hi4, recv)
|
require.Equal(t, hi4, recv)
|
||||||
recv, found = k.GetHistoricalInfo(ctx, 5)
|
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, hi5, recv)
|
require.Equal(t, hi5, recv)
|
||||||
|
|
||||||
// Set last validators in keeper
|
// Set last validators in keeper
|
||||||
val1 := types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{})
|
val1 := types.NewValidator(addrVals[2], PKs[2], types.Description{})
|
||||||
k.SetValidator(ctx, val1)
|
app.StakingKeeper.SetValidator(ctx, val1)
|
||||||
k.SetLastValidatorPower(ctx, val1.OperatorAddress, 10)
|
app.StakingKeeper.SetLastValidatorPower(ctx, val1.OperatorAddress, 10)
|
||||||
val2 := types.NewValidator(sdk.ValAddress(Addrs[3]), PKs[3], types.Description{})
|
val2 := types.NewValidator(addrVals[3], PKs[3], types.Description{})
|
||||||
vals := []types.Validator{val1, val2}
|
vals := []types.Validator{val1, val2}
|
||||||
sort.Sort(types.Validators(vals))
|
sort.Sort(types.Validators(vals))
|
||||||
k.SetValidator(ctx, val2)
|
app.StakingKeeper.SetValidator(ctx, val2)
|
||||||
k.SetLastValidatorPower(ctx, val2.OperatorAddress, 8)
|
app.StakingKeeper.SetLastValidatorPower(ctx, val2.OperatorAddress, 8)
|
||||||
|
|
||||||
// Set Header for BeginBlock context
|
// Set Header for BeginBlock context
|
||||||
header := abci.Header{
|
header := abci.Header{
|
||||||
|
@ -85,22 +95,22 @@ func TestTrackHistoricalInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
ctx = ctx.WithBlockHeader(header)
|
ctx = ctx.WithBlockHeader(header)
|
||||||
|
|
||||||
k.TrackHistoricalInfo(ctx)
|
app.StakingKeeper.TrackHistoricalInfo(ctx)
|
||||||
|
|
||||||
// Check HistoricalInfo at height 10 is persisted
|
// Check HistoricalInfo at height 10 is persisted
|
||||||
expected := types.HistoricalInfo{
|
expected := types.HistoricalInfo{
|
||||||
Header: header,
|
Header: header,
|
||||||
Valset: vals,
|
Valset: vals,
|
||||||
}
|
}
|
||||||
recv, found = k.GetHistoricalInfo(ctx, 10)
|
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 10)
|
||||||
require.True(t, found, "GetHistoricalInfo failed after BeginBlock")
|
require.True(t, found, "GetHistoricalInfo failed after BeginBlock")
|
||||||
require.Equal(t, expected, recv, "GetHistoricalInfo returned eunexpected result")
|
require.Equal(t, expected, recv, "GetHistoricalInfo returned eunexpected result")
|
||||||
|
|
||||||
// Check HistoricalInfo at height 5, 4 is pruned
|
// Check HistoricalInfo at height 5, 4 is pruned
|
||||||
recv, found = k.GetHistoricalInfo(ctx, 4)
|
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 4)
|
||||||
require.False(t, found, "GetHistoricalInfo did not prune earlier height")
|
require.False(t, found, "GetHistoricalInfo did not prune earlier height")
|
||||||
require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune")
|
require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune")
|
||||||
recv, found = k.GetHistoricalInfo(ctx, 5)
|
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5)
|
||||||
require.False(t, found, "GetHistoricalInfo did not prune first prune height")
|
require.False(t, found, "GetHistoricalInfo did not prune first prune height")
|
||||||
require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune")
|
require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune")
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,10 @@ func NewKeeper(
|
||||||
cdc codec.Marshaler, key sdk.StoreKey, bk types.BankKeeper, sk types.SupplyKeeper, ps paramtypes.Subspace,
|
cdc codec.Marshaler, key sdk.StoreKey, bk types.BankKeeper, sk types.SupplyKeeper, ps paramtypes.Subspace,
|
||||||
) Keeper {
|
) Keeper {
|
||||||
|
|
||||||
|
if !ps.HasKeyTable() {
|
||||||
|
ps = ps.WithKeyTable(ParamKeyTable())
|
||||||
|
}
|
||||||
|
|
||||||
// ensure bonded and not bonded module accounts are set
|
// ensure bonded and not bonded module accounts are set
|
||||||
if addr := sk.GetModuleAddress(types.BondedPoolName); addr == nil {
|
if addr := sk.GetModuleAddress(types.BondedPoolName); addr == nil {
|
||||||
panic(fmt.Sprintf("%s module account has not been set", types.BondedPoolName))
|
panic(fmt.Sprintf("%s module account has not been set", types.BondedPoolName))
|
||||||
|
@ -51,7 +55,7 @@ func NewKeeper(
|
||||||
cdc: cdc,
|
cdc: cdc,
|
||||||
bankKeeper: bk,
|
bankKeeper: bk,
|
||||||
supplyKeeper: sk,
|
supplyKeeper: sk,
|
||||||
paramstore: ps.WithKeyTable(ParamKeyTable()),
|
paramstore: ps,
|
||||||
hooks: nil,
|
hooks: nil,
|
||||||
validatorCache: make(map[string]cachedValidator, aminoCacheSize),
|
validatorCache: make(map[string]cachedValidator, aminoCacheSize),
|
||||||
validatorCacheList: list.New(),
|
validatorCacheList: list.New(),
|
||||||
|
|
|
@ -1,24 +1,28 @@
|
||||||
package keeper
|
package keeper_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParams(t *testing.T) {
|
func TestParams(t *testing.T) {
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, 0)
|
app := simapp.Setup(false)
|
||||||
|
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
|
||||||
expParams := types.DefaultParams()
|
expParams := types.DefaultParams()
|
||||||
|
|
||||||
//check that the empty keeper loads the default
|
//check that the empty keeper loads the default
|
||||||
resParams := keeper.GetParams(ctx)
|
resParams := app.StakingKeeper.GetParams(ctx)
|
||||||
require.True(t, expParams.Equal(resParams))
|
require.True(t, expParams.Equal(resParams))
|
||||||
|
|
||||||
//modify a params, save, and retrieve
|
//modify a params, save, and retrieve
|
||||||
expParams.MaxValidators = 777
|
expParams.MaxValidators = 777
|
||||||
keeper.SetParams(ctx, expParams)
|
app.StakingKeeper.SetParams(ctx, expParams)
|
||||||
resParams = keeper.GetParams(ctx)
|
resParams = app.StakingKeeper.GetParams(ctx)
|
||||||
require.True(t, expParams.Equal(resParams))
|
require.True(t, expParams.Equal(resParams))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
package keeper
|
package keeper_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
addrAcc1, addrAcc2 = Addrs[0], Addrs[1]
|
|
||||||
addrVal1, addrVal2 = sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1])
|
|
||||||
pk1, pk2 = PKs[0], PKs[1]
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNewQuerier(t *testing.T) {
|
func TestNewQuerier(t *testing.T) {
|
||||||
cdc := codec.New()
|
cdc, app, ctx := createTestInput()
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000)
|
|
||||||
|
addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.NewInt(10000))
|
||||||
|
_, addrAcc2 := addrs[0], addrs[1]
|
||||||
|
addrVal1, _ := sdk.ValAddress(addrs[0]), sdk.ValAddress(addrs[1])
|
||||||
|
|
||||||
// Create Validators
|
// Create Validators
|
||||||
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8)}
|
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8)}
|
||||||
var validators [2]types.Validator
|
var validators [2]types.Validator
|
||||||
for i, amt := range amts {
|
for i, amt := range amts {
|
||||||
validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{})
|
validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{})
|
||||||
validators[i], _ = validators[i].AddTokensFromDel(amt)
|
validators[i], _ = validators[i].AddTokensFromDel(amt)
|
||||||
keeper.SetValidator(ctx, validators[i])
|
app.StakingKeeper.SetValidator(ctx, validators[i])
|
||||||
keeper.SetValidatorByPowerIndex(ctx, validators[i])
|
app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
header := abci.Header{
|
header := abci.Header{
|
||||||
|
@ -36,14 +36,14 @@ func TestNewQuerier(t *testing.T) {
|
||||||
Height: 5,
|
Height: 5,
|
||||||
}
|
}
|
||||||
hi := types.NewHistoricalInfo(header, validators[:])
|
hi := types.NewHistoricalInfo(header, validators[:])
|
||||||
keeper.SetHistoricalInfo(ctx, 5, hi)
|
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi)
|
||||||
|
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: "",
|
Path: "",
|
||||||
Data: []byte{},
|
Data: []byte{},
|
||||||
}
|
}
|
||||||
|
|
||||||
querier := NewQuerier(keeper)
|
querier := staking.NewQuerier(app.StakingKeeper)
|
||||||
|
|
||||||
bz, err := querier(ctx, []string{"other"}, query)
|
bz, err := querier(ctx, []string{"other"}, query)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
@ -106,50 +106,54 @@ func TestNewQuerier(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQueryParametersPool(t *testing.T) {
|
func TestQueryParametersPool(t *testing.T) {
|
||||||
cdc := codec.New()
|
cdc, app, ctx := createTestInput()
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000)
|
querier := staking.NewQuerier(app.StakingKeeper)
|
||||||
|
|
||||||
bondDenom := sdk.DefaultBondDenom
|
bondDenom := sdk.DefaultBondDenom
|
||||||
|
|
||||||
res, err := queryParameters(ctx, keeper)
|
res, err := querier(ctx, []string{staking.QueryParameters}, abci.RequestQuery{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var params types.Params
|
var params types.Params
|
||||||
errRes := cdc.UnmarshalJSON(res, ¶ms)
|
errRes := cdc.UnmarshalJSON(res, ¶ms)
|
||||||
require.NoError(t, errRes)
|
require.NoError(t, errRes)
|
||||||
require.Equal(t, keeper.GetParams(ctx), params)
|
require.Equal(t, app.StakingKeeper.GetParams(ctx), params)
|
||||||
|
|
||||||
res, err = queryPool(ctx, keeper)
|
res, err = querier(ctx, []string{staking.QueryPool}, abci.RequestQuery{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var pool types.Pool
|
var pool types.Pool
|
||||||
bondedPool := keeper.GetBondedPool(ctx)
|
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||||
notBondedPool := keeper.GetNotBondedPool(ctx)
|
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
require.NoError(t, cdc.UnmarshalJSON(res, &pool))
|
require.NoError(t, cdc.UnmarshalJSON(res, &pool))
|
||||||
require.Equal(t, keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, pool.NotBondedTokens)
|
require.Equal(t, app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, pool.NotBondedTokens)
|
||||||
require.Equal(t, keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, pool.BondedTokens)
|
require.Equal(t, app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, pool.BondedTokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQueryValidators(t *testing.T) {
|
func TestQueryValidators(t *testing.T) {
|
||||||
cdc := codec.New()
|
cdc, app, ctx := createTestInput()
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
|
params := app.StakingKeeper.GetParams(ctx)
|
||||||
params := keeper.GetParams(ctx)
|
querier := staking.NewQuerier(app.StakingKeeper)
|
||||||
|
|
||||||
|
addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.TokensFromConsensusPower(10000))
|
||||||
|
|
||||||
// Create Validators
|
// Create Validators
|
||||||
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)}
|
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)}
|
||||||
status := []sdk.BondStatus{sdk.Bonded, sdk.Unbonded, sdk.Unbonding}
|
status := []sdk.BondStatus{sdk.Bonded, sdk.Unbonded, sdk.Unbonding}
|
||||||
var validators [3]types.Validator
|
var validators [3]types.Validator
|
||||||
for i, amt := range amts {
|
for i, amt := range amts {
|
||||||
validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{})
|
validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{})
|
||||||
validators[i], _ = validators[i].AddTokensFromDel(amt)
|
validators[i], _ = validators[i].AddTokensFromDel(amt)
|
||||||
validators[i] = validators[i].UpdateStatus(status[i])
|
validators[i] = validators[i].UpdateStatus(status[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
keeper.SetValidator(ctx, validators[0])
|
app.StakingKeeper.SetValidator(ctx, validators[0])
|
||||||
keeper.SetValidator(ctx, validators[1])
|
app.StakingKeeper.SetValidator(ctx, validators[1])
|
||||||
keeper.SetValidator(ctx, validators[2])
|
app.StakingKeeper.SetValidator(ctx, validators[2])
|
||||||
|
|
||||||
// Query Validators
|
// Query Validators
|
||||||
queriedValidators := keeper.GetValidators(ctx, params.MaxValidators)
|
queriedValidators := app.StakingKeeper.GetValidators(ctx, params.MaxValidators)
|
||||||
|
require.Len(t, queriedValidators, 3)
|
||||||
|
|
||||||
for i, s := range status {
|
for i, s := range status {
|
||||||
queryValsParams := types.NewQueryValidatorsParams(1, int(params.MaxValidators), s.String())
|
queryValsParams := types.NewQueryValidatorsParams(1, int(params.MaxValidators), s.String())
|
||||||
|
@ -161,7 +165,7 @@ func TestQueryValidators(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := queryValidators(ctx, req, keeper)
|
res, err := querier(ctx, []string{types.QueryValidators}, req)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var validatorsResp []types.Validator
|
var validatorsResp []types.Validator
|
||||||
|
@ -170,47 +174,56 @@ func TestQueryValidators(t *testing.T) {
|
||||||
|
|
||||||
require.Equal(t, 1, len(validatorsResp))
|
require.Equal(t, 1, len(validatorsResp))
|
||||||
require.ElementsMatch(t, validators[i].OperatorAddress, validatorsResp[0].OperatorAddress)
|
require.ElementsMatch(t, validators[i].OperatorAddress, validatorsResp[0].OperatorAddress)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query each validator
|
// Query each validator
|
||||||
queryParams := types.NewQueryValidatorParams(addrVal1)
|
for _, validator := range validators {
|
||||||
bz, err := cdc.MarshalJSON(queryParams)
|
queryParams := types.NewQueryValidatorParams(validator.OperatorAddress)
|
||||||
require.NoError(t, err)
|
bz, err := cdc.MarshalJSON(queryParams)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: "/custom/staking/validator",
|
Path: "/custom/staking/validator",
|
||||||
Data: bz,
|
Data: bz,
|
||||||
|
}
|
||||||
|
res, err := querier(ctx, []string{types.QueryValidator}, query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var queriedValidator types.Validator
|
||||||
|
err = cdc.UnmarshalJSON(res, &queriedValidator)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, validator, queriedValidator)
|
||||||
}
|
}
|
||||||
res, err := queryValidator(ctx, query, keeper)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
var validator types.Validator
|
|
||||||
err = cdc.UnmarshalJSON(res, &validator)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Equal(t, queriedValidators[0], validator)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQueryDelegation(t *testing.T) {
|
func TestQueryDelegation(t *testing.T) {
|
||||||
cdc := codec.New()
|
cdc, app, ctx := createTestInput()
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
|
params := app.StakingKeeper.GetParams(ctx)
|
||||||
params := keeper.GetParams(ctx)
|
querier := staking.NewQuerier(app.StakingKeeper)
|
||||||
|
|
||||||
|
addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000))
|
||||||
|
addrAcc1, addrAcc2 := addrs[0], addrs[1]
|
||||||
|
addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2)
|
||||||
|
|
||||||
|
pubKeys := simapp.CreateTestPubKeys(2)
|
||||||
|
pk1, pk2 := pubKeys[0], pubKeys[1]
|
||||||
|
|
||||||
// Create Validators and Delegation
|
// Create Validators and Delegation
|
||||||
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
|
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
|
||||||
keeper.SetValidator(ctx, val1)
|
app.StakingKeeper.SetValidator(ctx, val1)
|
||||||
keeper.SetValidatorByPowerIndex(ctx, val1)
|
app.StakingKeeper.SetValidatorByPowerIndex(ctx, val1)
|
||||||
|
|
||||||
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
|
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
|
||||||
keeper.SetValidator(ctx, val2)
|
app.StakingKeeper.SetValidator(ctx, val2)
|
||||||
keeper.SetValidatorByPowerIndex(ctx, val2)
|
app.StakingKeeper.SetValidatorByPowerIndex(ctx, val2)
|
||||||
|
|
||||||
delTokens := sdk.TokensFromConsensusPower(20)
|
delTokens := sdk.TokensFromConsensusPower(20)
|
||||||
keeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true)
|
_, err := app.StakingKeeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
// apply TM updates
|
// apply TM updates
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
// Query Delegator bonded validators
|
// Query Delegator bonded validators
|
||||||
queryParams := types.NewQueryDelegatorParams(addrAcc2)
|
queryParams := types.NewQueryDelegatorParams(addrAcc2)
|
||||||
|
@ -222,9 +235,9 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
delValidators := keeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators)
|
delValidators := app.StakingKeeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators)
|
||||||
|
|
||||||
res, err := queryDelegatorValidators(ctx, query, keeper)
|
res, err := querier(ctx, []string{types.QueryDelegatorValidators}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var validatorsResp []types.Validator
|
var validatorsResp []types.Validator
|
||||||
|
@ -237,7 +250,7 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
// error unknown request
|
// error unknown request
|
||||||
query.Data = bz[:len(bz)-1]
|
query.Data = bz[:len(bz)-1]
|
||||||
|
|
||||||
_, err = queryDelegatorValidators(ctx, query, keeper)
|
_, err = querier(ctx, []string{types.QueryDelegatorValidators}, query)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// Query bonded validator
|
// Query bonded validator
|
||||||
|
@ -250,7 +263,7 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err = queryDelegatorValidator(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var validator types.Validator
|
var validator types.Validator
|
||||||
|
@ -262,7 +275,7 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
// error unknown request
|
// error unknown request
|
||||||
query.Data = bz[:len(bz)-1]
|
query.Data = bz[:len(bz)-1]
|
||||||
|
|
||||||
_, err = queryDelegatorValidator(ctx, query, keeper)
|
_, err = querier(ctx, []string{types.QueryDelegatorValidator}, query)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// Query delegation
|
// Query delegation
|
||||||
|
@ -272,10 +285,10 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
delegation, found := keeper.GetDelegation(ctx, addrAcc2, addrVal1)
|
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc2, addrVal1)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
res, err = queryDelegation(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryDelegation}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var delegationRes types.DelegationResponse
|
var delegationRes types.DelegationResponse
|
||||||
|
@ -292,7 +305,7 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err = queryDelegatorDelegations(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryDelegatorDelegations}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var delegatorDelegations types.DelegationResponses
|
var delegatorDelegations types.DelegationResponses
|
||||||
|
@ -306,11 +319,10 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
// error unknown request
|
// error unknown request
|
||||||
query.Data = bz[:len(bz)-1]
|
query.Data = bz[:len(bz)-1]
|
||||||
|
|
||||||
_, err = queryDelegation(ctx, query, keeper)
|
_, err = querier(ctx, []string{types.QueryDelegation}, query)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// Query validator delegations
|
// Query validator delegations
|
||||||
|
|
||||||
bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1))
|
bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1))
|
||||||
require.NoError(t, errRes)
|
require.NoError(t, errRes)
|
||||||
|
|
||||||
|
@ -319,7 +331,7 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err = queryValidatorDelegations(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryValidatorDelegations}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var delegationsRes types.DelegationResponses
|
var delegationsRes types.DelegationResponses
|
||||||
|
@ -330,9 +342,9 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress)
|
require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress)
|
||||||
require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance)
|
require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance)
|
||||||
|
|
||||||
// Query unbonging delegation
|
// Query unbonding delegation
|
||||||
unbondingTokens := sdk.TokensFromConsensusPower(10)
|
unbondingTokens := sdk.TokensFromConsensusPower(10)
|
||||||
_, err = keeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec())
|
_, err = app.StakingKeeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1)
|
queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1)
|
||||||
|
@ -344,10 +356,10 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
unbond, found := keeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1)
|
unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
res, err = queryUnbondingDelegation(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var unbondRes types.UnbondingDelegation
|
var unbondRes types.UnbondingDelegation
|
||||||
|
@ -359,7 +371,7 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
// error unknown request
|
// error unknown request
|
||||||
query.Data = bz[:len(bz)-1]
|
query.Data = bz[:len(bz)-1]
|
||||||
|
|
||||||
_, err = queryUnbondingDelegation(ctx, query, keeper)
|
_, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// Query Delegator Delegations
|
// Query Delegator Delegations
|
||||||
|
@ -369,7 +381,7 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var delegatorUbds []types.UnbondingDelegation
|
var delegatorUbds []types.UnbondingDelegation
|
||||||
|
@ -380,15 +392,15 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
// error unknown request
|
// error unknown request
|
||||||
query.Data = bz[:len(bz)-1]
|
query.Data = bz[:len(bz)-1]
|
||||||
|
|
||||||
_, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
|
_, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// Query redelegation
|
// Query redelegation
|
||||||
redelegationTokens := sdk.TokensFromConsensusPower(10)
|
redelegationTokens := sdk.TokensFromConsensusPower(10)
|
||||||
_, err = keeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress,
|
_, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress,
|
||||||
val2.OperatorAddress, redelegationTokens.ToDec())
|
val2.OperatorAddress, redelegationTokens.ToDec())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress)
|
redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress))
|
bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress))
|
||||||
|
@ -399,7 +411,7 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err = queryRedelegations(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryRedelegations}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var redelRes types.RedelegationResponses
|
var redelRes types.RedelegationResponses
|
||||||
|
@ -413,24 +425,28 @@ func TestQueryDelegation(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQueryRedelegations(t *testing.T) {
|
func TestQueryRedelegations(t *testing.T) {
|
||||||
cdc := codec.New()
|
cdc, app, ctx := createTestInput()
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
|
querier := staking.NewQuerier(app.StakingKeeper)
|
||||||
|
|
||||||
|
addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000))
|
||||||
|
addrAcc1, addrAcc2 := addrs[0], addrs[1]
|
||||||
|
addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2)
|
||||||
|
|
||||||
// Create Validators and Delegation
|
// Create Validators and Delegation
|
||||||
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
|
val1 := types.NewValidator(addrVal1, PKs[0], types.Description{})
|
||||||
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
|
val2 := types.NewValidator(addrVal2, PKs[1], types.Description{})
|
||||||
keeper.SetValidator(ctx, val1)
|
app.StakingKeeper.SetValidator(ctx, val1)
|
||||||
keeper.SetValidator(ctx, val2)
|
app.StakingKeeper.SetValidator(ctx, val2)
|
||||||
|
|
||||||
delAmount := sdk.TokensFromConsensusPower(100)
|
delAmount := sdk.TokensFromConsensusPower(100)
|
||||||
keeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true)
|
app.StakingKeeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true)
|
||||||
_ = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
_ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
rdAmount := sdk.TokensFromConsensusPower(20)
|
rdAmount := sdk.TokensFromConsensusPower(20)
|
||||||
keeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec())
|
app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec())
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress)
|
redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
// delegator redelegations
|
// delegator redelegations
|
||||||
|
@ -443,7 +459,7 @@ func TestQueryRedelegations(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := queryRedelegations(ctx, query, keeper)
|
res, err := querier(ctx, []string{types.QueryRedelegations}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var redelRes types.RedelegationResponses
|
var redelRes types.RedelegationResponses
|
||||||
|
@ -465,7 +481,7 @@ func TestQueryRedelegations(t *testing.T) {
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err = queryRedelegations(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryRedelegations}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
errRes = cdc.UnmarshalJSON(res, &redelRes)
|
errRes = cdc.UnmarshalJSON(res, &redelRes)
|
||||||
|
@ -478,26 +494,30 @@ func TestQueryRedelegations(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQueryUnbondingDelegation(t *testing.T) {
|
func TestQueryUnbondingDelegation(t *testing.T) {
|
||||||
cdc := codec.New()
|
cdc, app, ctx := createTestInput()
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
|
querier := staking.NewQuerier(app.StakingKeeper)
|
||||||
|
|
||||||
|
addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000))
|
||||||
|
addrAcc1, addrAcc2 := addrs[0], addrs[1]
|
||||||
|
addrVal1 := sdk.ValAddress(addrAcc1)
|
||||||
|
|
||||||
// Create Validators and Delegation
|
// Create Validators and Delegation
|
||||||
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
|
val1 := types.NewValidator(addrVal1, PKs[0], types.Description{})
|
||||||
keeper.SetValidator(ctx, val1)
|
app.StakingKeeper.SetValidator(ctx, val1)
|
||||||
|
|
||||||
// delegate
|
// delegate
|
||||||
delAmount := sdk.TokensFromConsensusPower(100)
|
delAmount := sdk.TokensFromConsensusPower(100)
|
||||||
_, err := keeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true)
|
_, err := app.StakingKeeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_ = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
_ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
// undelegate
|
// undelegate
|
||||||
undelAmount := sdk.TokensFromConsensusPower(20)
|
undelAmount := sdk.TokensFromConsensusPower(20)
|
||||||
_, err = keeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec())
|
_, err = app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
_, found := keeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress)
|
_, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -510,7 +530,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
|
||||||
Path: "/custom/staking/unbondingDelegation",
|
Path: "/custom/staking/unbondingDelegation",
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
res, err := queryUnbondingDelegation(ctx, query, keeper)
|
res, err := querier(ctx, []string{types.QueryUnbondingDelegation}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, res)
|
require.NotNil(t, res)
|
||||||
var ubDel types.UnbondingDelegation
|
var ubDel types.UnbondingDelegation
|
||||||
|
@ -529,7 +549,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
|
||||||
Path: "/custom/staking/unbondingDelegation",
|
Path: "/custom/staking/unbondingDelegation",
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
_, err = queryUnbondingDelegation(ctx, query, keeper)
|
_, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -542,7 +562,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
|
||||||
Path: "/custom/staking/delegatorUnbondingDelegations",
|
Path: "/custom/staking/delegatorUnbondingDelegations",
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, res)
|
require.NotNil(t, res)
|
||||||
var ubDels []types.UnbondingDelegation
|
var ubDels []types.UnbondingDelegation
|
||||||
|
@ -561,7 +581,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
|
||||||
Path: "/custom/staking/delegatorUnbondingDelegations",
|
Path: "/custom/staking/delegatorUnbondingDelegations",
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, res)
|
require.NotNil(t, res)
|
||||||
require.NoError(t, cdc.UnmarshalJSON(res, &ubDels))
|
require.NoError(t, cdc.UnmarshalJSON(res, &ubDels))
|
||||||
|
@ -569,22 +589,26 @@ func TestQueryUnbondingDelegation(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQueryHistoricalInfo(t *testing.T) {
|
func TestQueryHistoricalInfo(t *testing.T) {
|
||||||
cdc := codec.New()
|
cdc, app, ctx := createTestInput()
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
|
querier := staking.NewQuerier(app.StakingKeeper)
|
||||||
|
|
||||||
|
addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000))
|
||||||
|
addrAcc1, addrAcc2 := addrs[0], addrs[1]
|
||||||
|
addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2)
|
||||||
|
|
||||||
// Create Validators and Delegation
|
// Create Validators and Delegation
|
||||||
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
|
val1 := types.NewValidator(addrVal1, PKs[0], types.Description{})
|
||||||
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
|
val2 := types.NewValidator(addrVal2, PKs[1], types.Description{})
|
||||||
vals := []types.Validator{val1, val2}
|
vals := []types.Validator{val1, val2}
|
||||||
keeper.SetValidator(ctx, val1)
|
app.StakingKeeper.SetValidator(ctx, val1)
|
||||||
keeper.SetValidator(ctx, val2)
|
app.StakingKeeper.SetValidator(ctx, val2)
|
||||||
|
|
||||||
header := abci.Header{
|
header := abci.Header{
|
||||||
ChainID: "HelloChain",
|
ChainID: "HelloChain",
|
||||||
Height: 5,
|
Height: 5,
|
||||||
}
|
}
|
||||||
hi := types.NewHistoricalInfo(header, vals)
|
hi := types.NewHistoricalInfo(header, vals)
|
||||||
keeper.SetHistoricalInfo(ctx, 5, hi)
|
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi)
|
||||||
|
|
||||||
queryHistoricalParams := types.NewQueryHistoricalInfoParams(4)
|
queryHistoricalParams := types.NewQueryHistoricalInfoParams(4)
|
||||||
bz, errRes := cdc.MarshalJSON(queryHistoricalParams)
|
bz, errRes := cdc.MarshalJSON(queryHistoricalParams)
|
||||||
|
@ -593,7 +617,7 @@ func TestQueryHistoricalInfo(t *testing.T) {
|
||||||
Path: "/custom/staking/historicalInfo",
|
Path: "/custom/staking/historicalInfo",
|
||||||
Data: bz,
|
Data: bz,
|
||||||
}
|
}
|
||||||
res, err := queryHistoricalInfo(ctx, query, keeper)
|
res, err := querier(ctx, []string{types.QueryHistoricalInfo}, query)
|
||||||
require.Error(t, err, "Invalid query passed")
|
require.Error(t, err, "Invalid query passed")
|
||||||
require.Nil(t, res, "Invalid query returned non-nil result")
|
require.Nil(t, res, "Invalid query returned non-nil result")
|
||||||
|
|
||||||
|
@ -601,7 +625,7 @@ func TestQueryHistoricalInfo(t *testing.T) {
|
||||||
bz, errRes = cdc.MarshalJSON(queryHistoricalParams)
|
bz, errRes = cdc.MarshalJSON(queryHistoricalParams)
|
||||||
require.NoError(t, errRes)
|
require.NoError(t, errRes)
|
||||||
query.Data = bz
|
query.Data = bz
|
||||||
res, err = queryHistoricalInfo(ctx, query, keeper)
|
res, err = querier(ctx, []string{types.QueryHistoricalInfo}, query)
|
||||||
require.NoError(t, err, "Valid query passed")
|
require.NoError(t, err, "Valid query passed")
|
||||||
require.NotNil(t, res, "Valid query returned nil result")
|
require.NotNil(t, res, "Valid query returned nil result")
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||||
// Iterate through unbonding delegations from slashed validator
|
// Iterate through unbonding delegations from slashed validator
|
||||||
unbondingDelegations := k.GetUnbondingDelegationsFromValidator(ctx, operatorAddress)
|
unbondingDelegations := k.GetUnbondingDelegationsFromValidator(ctx, operatorAddress)
|
||||||
for _, unbondingDelegation := range unbondingDelegations {
|
for _, unbondingDelegation := range unbondingDelegations {
|
||||||
amountSlashed := k.slashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor)
|
amountSlashed := k.SlashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor)
|
||||||
if amountSlashed.IsZero() {
|
if amountSlashed.IsZero() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||||
// Iterate through redelegations from slashed source validator
|
// Iterate through redelegations from slashed source validator
|
||||||
redelegations := k.GetRedelegationsFromSrcValidator(ctx, operatorAddress)
|
redelegations := k.GetRedelegationsFromSrcValidator(ctx, operatorAddress)
|
||||||
for _, redelegation := range redelegations {
|
for _, redelegation := range redelegations {
|
||||||
amountSlashed := k.slashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor)
|
amountSlashed := k.SlashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor)
|
||||||
if amountSlashed.IsZero() {
|
if amountSlashed.IsZero() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress) {
|
||||||
// the unbonding delegation had enough stake to slash
|
// the unbonding delegation had enough stake to slash
|
||||||
// (the amount actually slashed may be less if there's
|
// (the amount actually slashed may be less if there's
|
||||||
// insufficient stake remaining)
|
// insufficient stake remaining)
|
||||||
func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation types.UnbondingDelegation,
|
func (k Keeper) SlashUnbondingDelegation(ctx sdk.Context, unbondingDelegation types.UnbondingDelegation,
|
||||||
infractionHeight int64, slashFactor sdk.Dec) (totalSlashAmount sdk.Int) {
|
infractionHeight int64, slashFactor sdk.Dec) (totalSlashAmount sdk.Int) {
|
||||||
|
|
||||||
now := ctx.BlockHeader().Time
|
now := ctx.BlockHeader().Time
|
||||||
|
@ -215,7 +215,7 @@ func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty
|
||||||
// (the amount actually slashed may be less if there's
|
// (the amount actually slashed may be less if there's
|
||||||
// insufficient stake remaining)
|
// insufficient stake remaining)
|
||||||
// NOTE this is only slashing for prior infractions from the source validator
|
// NOTE this is only slashing for prior infractions from the source validator
|
||||||
func (k Keeper) slashRedelegation(ctx sdk.Context, srcValidator types.Validator, redelegation types.Redelegation,
|
func (k Keeper) SlashRedelegation(ctx sdk.Context, srcValidator types.Validator, redelegation types.Redelegation,
|
||||||
infractionHeight int64, slashFactor sdk.Dec) (totalSlashAmount sdk.Int) {
|
infractionHeight int64, slashFactor sdk.Dec) (totalSlashAmount sdk.Int) {
|
||||||
|
|
||||||
now := ctx.BlockHeader().Time
|
now := ctx.BlockHeader().Time
|
||||||
|
@ -254,7 +254,7 @@ func (k Keeper) slashRedelegation(ctx sdk.Context, srcValidator types.Validator,
|
||||||
sharesToUnbond = delegation.Shares
|
sharesToUnbond = delegation.Shares
|
||||||
}
|
}
|
||||||
|
|
||||||
tokensToBurn, err := k.unbond(ctx, redelegation.DelegatorAddress, redelegation.ValidatorDstAddress, sharesToUnbond)
|
tokensToBurn, err := k.Unbond(ctx, redelegation.DelegatorAddress, redelegation.ValidatorDstAddress, sharesToUnbond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("error unbonding delegator: %v", err))
|
panic(fmt.Errorf("error unbonding delegator: %v", err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,72 +1,83 @@
|
||||||
package keeper
|
package keeper_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO integrate with test_common.go helper (CreateTestInput)
|
// bootstrapSlashTest creates 3 validators and bootstrap the app.
|
||||||
// setup helper function - creates two validators
|
func bootstrapSlashTest(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) {
|
||||||
func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) {
|
_, app, ctx := createTestInput()
|
||||||
// setup
|
|
||||||
ctx, _, _, keeper, _ := CreateTestInput(t, false, power)
|
addrDels, addrVals := generateAddresses(app, ctx, 100)
|
||||||
params := keeper.GetParams(ctx)
|
|
||||||
numVals := int64(3)
|
|
||||||
amt := sdk.TokensFromConsensusPower(power)
|
amt := sdk.TokensFromConsensusPower(power)
|
||||||
bondedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), amt.MulRaw(numVals)))
|
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels)))))
|
||||||
|
|
||||||
bondedPool := keeper.GetBondedPool(ctx)
|
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins))
|
err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply)
|
||||||
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
|
require.NoError(t, err)
|
||||||
|
app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool)
|
||||||
|
|
||||||
|
numVals := int64(3)
|
||||||
|
bondedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(numVals)))
|
||||||
|
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||||
|
err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins)
|
||||||
|
require.NoError(t, err)
|
||||||
|
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
|
||||||
|
|
||||||
|
app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
|
||||||
|
|
||||||
// add numVals validators
|
|
||||||
for i := int64(0); i < numVals; i++ {
|
for i := int64(0); i < numVals; i++ {
|
||||||
validator := types.NewValidator(addrVals[i], PKs[i], types.Description{})
|
validator := types.NewValidator(addrVals[i], PKs[i], types.Description{})
|
||||||
validator, _ = validator.AddTokensFromDel(amt)
|
validator, _ = validator.AddTokensFromDel(amt)
|
||||||
validator = TestingUpdateValidator(keeper, ctx, validator, true)
|
validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
|
||||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx, keeper, params
|
return app, ctx, addrDels, addrVals
|
||||||
}
|
}
|
||||||
|
|
||||||
//_________________________________________________________________________________
|
|
||||||
|
|
||||||
// tests Jail, Unjail
|
// tests Jail, Unjail
|
||||||
func TestRevocation(t *testing.T) {
|
func TestRevocation(t *testing.T) {
|
||||||
// setup
|
app, ctx, _, addrVals := bootstrapSlashTest(t, 5)
|
||||||
ctx, keeper, _ := setupHelper(t, 10)
|
|
||||||
addr := addrVals[0]
|
|
||||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||||
|
|
||||||
// initial state
|
// initial state
|
||||||
val, found := keeper.GetValidator(ctx, addr)
|
val, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.False(t, val.IsJailed())
|
require.False(t, val.IsJailed())
|
||||||
|
|
||||||
// test jail
|
// test jail
|
||||||
keeper.Jail(ctx, consAddr)
|
app.StakingKeeper.Jail(ctx, consAddr)
|
||||||
val, found = keeper.GetValidator(ctx, addr)
|
val, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.True(t, val.IsJailed())
|
require.True(t, val.IsJailed())
|
||||||
|
|
||||||
// test unjail
|
// test unjail
|
||||||
keeper.Unjail(ctx, consAddr)
|
app.StakingKeeper.Unjail(ctx, consAddr)
|
||||||
val, found = keeper.GetValidator(ctx, addr)
|
val, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.False(t, val.IsJailed())
|
require.False(t, val.IsJailed())
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests slashUnbondingDelegation
|
// tests slashUnbondingDelegation
|
||||||
func TestSlashUnbondingDelegation(t *testing.T) {
|
func TestSlashUnbondingDelegation(t *testing.T) {
|
||||||
ctx, keeper, _ := setupHelper(t, 10)
|
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
|
||||||
|
|
||||||
fraction := sdk.NewDecWithPrec(5, 1)
|
fraction := sdk.NewDecWithPrec(5, 1)
|
||||||
|
|
||||||
// set an unbonding delegation with expiration timestamp (beyond which the
|
// set an unbonding delegation with expiration timestamp (beyond which the
|
||||||
|
@ -74,26 +85,26 @@ func TestSlashUnbondingDelegation(t *testing.T) {
|
||||||
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0,
|
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0,
|
||||||
time.Unix(5, 0), sdk.NewInt(10))
|
time.Unix(5, 0), sdk.NewInt(10))
|
||||||
|
|
||||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||||
|
|
||||||
// unbonding started prior to the infraction height, stakw didn't contribute
|
// unbonding started prior to the infraction height, stakw didn't contribute
|
||||||
slashAmount := keeper.slashUnbondingDelegation(ctx, ubd, 1, fraction)
|
slashAmount := app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 1, fraction)
|
||||||
require.Equal(t, int64(0), slashAmount.Int64())
|
require.Equal(t, int64(0), slashAmount.Int64())
|
||||||
|
|
||||||
// after the expiration time, no longer eligible for slashing
|
// after the expiration time, no longer eligible for slashing
|
||||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
||||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||||
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
|
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
|
||||||
require.Equal(t, int64(0), slashAmount.Int64())
|
require.Equal(t, int64(0), slashAmount.Int64())
|
||||||
|
|
||||||
// test valid slash, before expiration timestamp and to which stake contributed
|
// test valid slash, before expiration timestamp and to which stake contributed
|
||||||
notBondedPool := keeper.GetNotBondedPool(ctx)
|
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
oldUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
|
oldUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
|
||||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
|
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
|
||||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||||
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
|
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
|
||||||
require.Equal(t, int64(5), slashAmount.Int64())
|
require.Equal(t, int64(5), slashAmount.Int64())
|
||||||
ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
ubd, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, ubd.Entries, 1)
|
require.Len(t, ubd.Entries, 1)
|
||||||
|
|
||||||
|
@ -102,153 +113,157 @@ func TestSlashUnbondingDelegation(t *testing.T) {
|
||||||
|
|
||||||
// balance decreased
|
// balance decreased
|
||||||
require.Equal(t, sdk.NewInt(5), ubd.Entries[0].Balance)
|
require.Equal(t, sdk.NewInt(5), ubd.Entries[0].Balance)
|
||||||
newUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
|
newUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
|
||||||
diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances)
|
diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances)
|
||||||
require.Equal(t, int64(5), diffTokens.AmountOf(keeper.BondDenom(ctx)).Int64())
|
require.Equal(t, int64(5), diffTokens.AmountOf(app.StakingKeeper.BondDenom(ctx)).Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests slashRedelegation
|
// tests slashRedelegation
|
||||||
func TestSlashRedelegation(t *testing.T) {
|
func TestSlashRedelegation(t *testing.T) {
|
||||||
ctx, keeper, _ := setupHelper(t, 10)
|
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
|
||||||
fraction := sdk.NewDecWithPrec(5, 1)
|
fraction := sdk.NewDecWithPrec(5, 1)
|
||||||
|
|
||||||
// add bonded tokens to pool for (re)delegations
|
// add bonded tokens to pool for (re)delegations
|
||||||
startCoins := sdk.NewCoins(sdk.NewInt64Coin(keeper.BondDenom(ctx), 15))
|
startCoins := sdk.NewCoins(sdk.NewInt64Coin(app.StakingKeeper.BondDenom(ctx), 15))
|
||||||
bondedPool := keeper.GetBondedPool(ctx)
|
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||||
balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
balances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
|
|
||||||
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...)))
|
require.NoError(t, app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...)))
|
||||||
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
|
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
|
||||||
|
|
||||||
// set a redelegation with an expiration timestamp beyond which the
|
// set a redelegation with an expiration timestamp beyond which the
|
||||||
// redelegation shouldn't be slashed
|
// redelegation shouldn't be slashed
|
||||||
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0,
|
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0,
|
||||||
time.Unix(5, 0), sdk.NewInt(10), sdk.NewDec(10))
|
time.Unix(5, 0), sdk.NewInt(10), sdk.NewDec(10))
|
||||||
|
|
||||||
keeper.SetRedelegation(ctx, rd)
|
app.StakingKeeper.SetRedelegation(ctx, rd)
|
||||||
|
|
||||||
// set the associated delegation
|
// set the associated delegation
|
||||||
del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDec(10))
|
del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDec(10))
|
||||||
keeper.SetDelegation(ctx, del)
|
app.StakingKeeper.SetDelegation(ctx, del)
|
||||||
|
|
||||||
// started redelegating prior to the current height, stake didn't contribute to infraction
|
// started redelegating prior to the current height, stake didn't contribute to infraction
|
||||||
validator, found := keeper.GetValidator(ctx, addrVals[1])
|
validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
slashAmount := keeper.slashRedelegation(ctx, validator, rd, 1, fraction)
|
slashAmount := app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 1, fraction)
|
||||||
require.Equal(t, int64(0), slashAmount.Int64())
|
require.Equal(t, int64(0), slashAmount.Int64())
|
||||||
|
|
||||||
// after the expiration time, no longer eligible for slashing
|
// after the expiration time, no longer eligible for slashing
|
||||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
||||||
keeper.SetRedelegation(ctx, rd)
|
app.StakingKeeper.SetRedelegation(ctx, rd)
|
||||||
validator, found = keeper.GetValidator(ctx, addrVals[1])
|
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction)
|
slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction)
|
||||||
require.Equal(t, int64(0), slashAmount.Int64())
|
require.Equal(t, int64(0), slashAmount.Int64())
|
||||||
|
|
||||||
balances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
balances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
|
|
||||||
// test valid slash, before expiration timestamp and to which stake contributed
|
// test valid slash, before expiration timestamp and to which stake contributed
|
||||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
|
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
|
||||||
keeper.SetRedelegation(ctx, rd)
|
app.StakingKeeper.SetRedelegation(ctx, rd)
|
||||||
validator, found = keeper.GetValidator(ctx, addrVals[1])
|
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction)
|
slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction)
|
||||||
require.Equal(t, int64(5), slashAmount.Int64())
|
require.Equal(t, int64(5), slashAmount.Int64())
|
||||||
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, rd.Entries, 1)
|
require.Len(t, rd.Entries, 1)
|
||||||
|
|
||||||
// end block
|
// end block
|
||||||
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
require.Equal(t, 1, len(updates))
|
require.Equal(t, 1, len(updates))
|
||||||
|
|
||||||
// initialbalance unchanged
|
// initialbalance unchanged
|
||||||
require.Equal(t, sdk.NewInt(10), rd.Entries[0].InitialBalance)
|
require.Equal(t, sdk.NewInt(10), rd.Entries[0].InitialBalance)
|
||||||
|
|
||||||
// shares decreased
|
// shares decreased
|
||||||
del, found = keeper.GetDelegation(ctx, addrDels[0], addrVals[1])
|
del, found = app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(5), del.Shares.RoundInt64())
|
require.Equal(t, int64(5), del.Shares.RoundInt64())
|
||||||
|
|
||||||
// pool bonded tokens should decrease
|
// pool bonded tokens should decrease
|
||||||
burnedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), slashAmount))
|
burnedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), slashAmount))
|
||||||
require.Equal(t, balances.Sub(burnedCoins), keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()))
|
require.Equal(t, balances.Sub(burnedCoins), app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests Slash at a future height (must panic)
|
// tests Slash at a future height (must panic)
|
||||||
func TestSlashAtFutureHeight(t *testing.T) {
|
func TestSlashAtFutureHeight(t *testing.T) {
|
||||||
ctx, keeper, _ := setupHelper(t, 10)
|
app, ctx, _, _ := bootstrapSlashTest(t, 10)
|
||||||
|
|
||||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||||
fraction := sdk.NewDecWithPrec(5, 1)
|
fraction := sdk.NewDecWithPrec(5, 1)
|
||||||
require.Panics(t, func() { keeper.Slash(ctx, consAddr, 1, 10, fraction) })
|
require.Panics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 1, 10, fraction) })
|
||||||
}
|
}
|
||||||
|
|
||||||
// test slash at a negative height
|
// test slash at a negative height
|
||||||
// this just represents pre-genesis and should have the same effect as slashing at height 0
|
// this just represents pre-genesis and should have the same effect as slashing at height 0
|
||||||
func TestSlashAtNegativeHeight(t *testing.T) {
|
func TestSlashAtNegativeHeight(t *testing.T) {
|
||||||
ctx, keeper, _ := setupHelper(t, 10)
|
app, ctx, _, _ := bootstrapSlashTest(t, 10)
|
||||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||||
fraction := sdk.NewDecWithPrec(5, 1)
|
fraction := sdk.NewDecWithPrec(5, 1)
|
||||||
|
|
||||||
bondedPool := keeper.GetBondedPool(ctx)
|
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||||
oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
|
|
||||||
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
keeper.Slash(ctx, consAddr, -2, 10, fraction)
|
app.StakingKeeper.Slash(ctx, consAddr, -2, 10, fraction)
|
||||||
|
|
||||||
// read updated state
|
// read updated state
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
// end block
|
// end block
|
||||||
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates)
|
require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates)
|
||||||
|
|
||||||
validator = keeper.mustGetValidator(ctx, validator.OperatorAddress)
|
validator, found = app.StakingKeeper.GetValidator(ctx, validator.OperatorAddress)
|
||||||
|
require.True(t, found)
|
||||||
// power decreased
|
// power decreased
|
||||||
require.Equal(t, int64(5), validator.GetConsensusPower())
|
require.Equal(t, int64(5), validator.GetConsensusPower())
|
||||||
|
|
||||||
// pool bonded shares decreased
|
// pool bonded shares decreased
|
||||||
newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
|
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
|
||||||
require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String())
|
require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests Slash at the current height
|
// tests Slash at the current height
|
||||||
func TestSlashValidatorAtCurrentHeight(t *testing.T) {
|
func TestSlashValidatorAtCurrentHeight(t *testing.T) {
|
||||||
ctx, keeper, _ := setupHelper(t, 10)
|
app, ctx, _, _ := bootstrapSlashTest(t, 10)
|
||||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||||
fraction := sdk.NewDecWithPrec(5, 1)
|
fraction := sdk.NewDecWithPrec(5, 1)
|
||||||
|
|
||||||
bondedPool := keeper.GetBondedPool(ctx)
|
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||||
oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
|
|
||||||
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
keeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
|
app.StakingKeeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
|
||||||
|
|
||||||
// read updated state
|
// read updated state
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
// end block
|
// end block
|
||||||
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates)
|
require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates)
|
||||||
|
|
||||||
validator = keeper.mustGetValidator(ctx, validator.OperatorAddress)
|
validator, found = app.StakingKeeper.GetValidator(ctx, validator.OperatorAddress)
|
||||||
|
assert.True(t, found)
|
||||||
// power decreased
|
// power decreased
|
||||||
require.Equal(t, int64(5), validator.GetConsensusPower())
|
require.Equal(t, int64(5), validator.GetConsensusPower())
|
||||||
|
|
||||||
// pool bonded shares decreased
|
// pool bonded shares decreased
|
||||||
newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
|
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
|
||||||
require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String())
|
require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests Slash at a previous height with an unbonding delegation
|
// tests Slash at a previous height with an unbonding delegation
|
||||||
func TestSlashWithUnbondingDelegation(t *testing.T) {
|
func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
ctx, keeper, _ := setupHelper(t, 10)
|
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
|
||||||
|
|
||||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||||
fraction := sdk.NewDecWithPrec(5, 1)
|
fraction := sdk.NewDecWithPrec(5, 1)
|
||||||
|
|
||||||
|
@ -257,23 +272,23 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
ubdTokens := sdk.TokensFromConsensusPower(4)
|
ubdTokens := sdk.TokensFromConsensusPower(4)
|
||||||
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
|
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
|
||||||
time.Unix(0, 0), ubdTokens)
|
time.Unix(0, 0), ubdTokens)
|
||||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||||
|
|
||||||
// slash validator for the first time
|
// slash validator for the first time
|
||||||
ctx = ctx.WithBlockHeight(12)
|
ctx = ctx.WithBlockHeight(12)
|
||||||
bondedPool := keeper.GetBondedPool(ctx)
|
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||||
oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
|
|
||||||
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
keeper.Slash(ctx, consAddr, 10, 10, fraction)
|
app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction)
|
||||||
|
|
||||||
// end block
|
// end block
|
||||||
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
require.Equal(t, 1, len(updates))
|
require.Equal(t, 1, len(updates))
|
||||||
|
|
||||||
// read updating unbonding delegation
|
// read updating unbonding delegation
|
||||||
ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, ubd.Entries, 1)
|
require.Len(t, ubd.Entries, 1)
|
||||||
|
|
||||||
|
@ -281,12 +296,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
require.Equal(t, sdk.TokensFromConsensusPower(2), ubd.Entries[0].Balance)
|
require.Equal(t, sdk.TokensFromConsensusPower(2), ubd.Entries[0].Balance)
|
||||||
|
|
||||||
// bonded tokens burned
|
// bonded tokens burned
|
||||||
newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
|
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
|
||||||
require.Equal(t, sdk.TokensFromConsensusPower(3), diffTokens)
|
require.Equal(t, sdk.TokensFromConsensusPower(3), diffTokens)
|
||||||
|
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
// power decreased by 3 - 6 stake originally bonded at the time of infraction
|
// power decreased by 3 - 6 stake originally bonded at the time of infraction
|
||||||
|
@ -297,9 +312,9 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
|
|
||||||
// slash validator again
|
// slash validator again
|
||||||
ctx = ctx.WithBlockHeight(13)
|
ctx = ctx.WithBlockHeight(13)
|
||||||
keeper.Slash(ctx, consAddr, 9, 10, fraction)
|
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
|
||||||
|
|
||||||
ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, ubd.Entries, 1)
|
require.Len(t, ubd.Entries, 1)
|
||||||
|
|
||||||
|
@ -307,12 +322,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
|
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
|
||||||
|
|
||||||
// bonded tokens burned again
|
// bonded tokens burned again
|
||||||
newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
|
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
|
||||||
require.Equal(t, sdk.TokensFromConsensusPower(6), diffTokens)
|
require.Equal(t, sdk.TokensFromConsensusPower(6), diffTokens)
|
||||||
|
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
// power decreased by 3 again
|
// power decreased by 3 again
|
||||||
|
@ -323,9 +338,9 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
// on the unbonding delegation, but it will slash stake bonded since the infraction
|
// on the unbonding delegation, but it will slash stake bonded since the infraction
|
||||||
// this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440
|
// this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440
|
||||||
ctx = ctx.WithBlockHeight(13)
|
ctx = ctx.WithBlockHeight(13)
|
||||||
keeper.Slash(ctx, consAddr, 9, 10, fraction)
|
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
|
||||||
|
|
||||||
ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, ubd.Entries, 1)
|
require.Len(t, ubd.Entries, 1)
|
||||||
|
|
||||||
|
@ -333,12 +348,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
|
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
|
||||||
|
|
||||||
// bonded tokens burned again
|
// bonded tokens burned again
|
||||||
newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
|
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
|
||||||
require.Equal(t, sdk.TokensFromConsensusPower(9), diffTokens)
|
require.Equal(t, sdk.TokensFromConsensusPower(9), diffTokens)
|
||||||
|
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
// power decreased by 3 again
|
// power decreased by 3 again
|
||||||
|
@ -349,9 +364,9 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
// on the unbonding delegation, but it will slash stake bonded since the infraction
|
// on the unbonding delegation, but it will slash stake bonded since the infraction
|
||||||
// this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440
|
// this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440
|
||||||
ctx = ctx.WithBlockHeight(13)
|
ctx = ctx.WithBlockHeight(13)
|
||||||
keeper.Slash(ctx, consAddr, 9, 10, fraction)
|
app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction)
|
||||||
|
|
||||||
ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, ubd.Entries, 1)
|
require.Len(t, ubd.Entries, 1)
|
||||||
|
|
||||||
|
@ -359,76 +374,77 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
|
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
|
||||||
|
|
||||||
// just 1 bonded token burned again since that's all the validator now has
|
// just 1 bonded token burned again since that's all the validator now has
|
||||||
newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
|
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
|
||||||
require.Equal(t, sdk.TokensFromConsensusPower(10), diffTokens)
|
require.Equal(t, sdk.TokensFromConsensusPower(10), diffTokens)
|
||||||
|
|
||||||
// apply TM updates
|
// apply TM updates
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
// read updated validator
|
// read updated validator
|
||||||
// power decreased by 1 again, validator is out of stake
|
// power decreased by 1 again, validator is out of stake
|
||||||
// validator should be in unbonding period
|
// validator should be in unbonding period
|
||||||
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
|
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//_________________________________________________________________________________
|
||||||
// tests Slash at a previous height with a redelegation
|
// tests Slash at a previous height with a redelegation
|
||||||
func TestSlashWithRedelegation(t *testing.T) {
|
func TestSlashWithRedelegation(t *testing.T) {
|
||||||
ctx, keeper, _ := setupHelper(t, 10)
|
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
|
||||||
consAddr := sdk.ConsAddress(PKs[0].Address())
|
consAddr := sdk.ConsAddress(PKs[0].Address())
|
||||||
fraction := sdk.NewDecWithPrec(5, 1)
|
fraction := sdk.NewDecWithPrec(5, 1)
|
||||||
bondDenom := keeper.BondDenom(ctx)
|
bondDenom := app.StakingKeeper.BondDenom(ctx)
|
||||||
|
|
||||||
// set a redelegation
|
// set a redelegation
|
||||||
rdTokens := sdk.TokensFromConsensusPower(6)
|
rdTokens := sdk.TokensFromConsensusPower(6)
|
||||||
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11,
|
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11,
|
||||||
time.Unix(0, 0), rdTokens, rdTokens.ToDec())
|
time.Unix(0, 0), rdTokens, rdTokens.ToDec())
|
||||||
keeper.SetRedelegation(ctx, rd)
|
app.StakingKeeper.SetRedelegation(ctx, rd)
|
||||||
|
|
||||||
// set the associated delegation
|
// set the associated delegation
|
||||||
del := types.NewDelegation(addrDels[0], addrVals[1], rdTokens.ToDec())
|
del := types.NewDelegation(addrDels[0], addrVals[1], rdTokens.ToDec())
|
||||||
keeper.SetDelegation(ctx, del)
|
app.StakingKeeper.SetDelegation(ctx, del)
|
||||||
|
|
||||||
// update bonded tokens
|
// update bonded tokens
|
||||||
bondedPool := keeper.GetBondedPool(ctx)
|
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||||
notBondedPool := keeper.GetNotBondedPool(ctx)
|
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2)))
|
rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2)))
|
||||||
|
|
||||||
balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
balances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
err := keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...))
|
err := app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
|
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
|
||||||
|
|
||||||
oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
||||||
|
|
||||||
// slash validator
|
// slash validator
|
||||||
ctx = ctx.WithBlockHeight(12)
|
ctx = ctx.WithBlockHeight(12)
|
||||||
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, fraction) })
|
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction) })
|
||||||
burnAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt()
|
burnAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt()
|
||||||
|
|
||||||
bondedPool = keeper.GetBondedPool(ctx)
|
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
|
||||||
notBondedPool = keeper.GetNotBondedPool(ctx)
|
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
|
|
||||||
// burn bonded tokens from only from delegations
|
// burn bonded tokens from only from delegations
|
||||||
bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
|
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
|
||||||
|
|
||||||
notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
||||||
oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
|
|
||||||
// read updating redelegation
|
// read updating redelegation
|
||||||
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, rd.Entries, 1)
|
require.Len(t, rd.Entries, 1)
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
// power decreased by 2 - 4 stake originally bonded at the time of infraction
|
// power decreased by 2 - 4 stake originally bonded at the time of infraction
|
||||||
// was still bonded at the time of discovery and was slashed by half, 4 stake
|
// was still bonded at the time of discovery and was slashed by half, 4 stake
|
||||||
|
@ -437,102 +453,102 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||||
require.Equal(t, int64(8), validator.GetConsensusPower())
|
require.Equal(t, int64(8), validator.GetConsensusPower())
|
||||||
|
|
||||||
// slash the validator again
|
// slash the validator again
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
|
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
|
||||||
burnAmount = sdk.TokensFromConsensusPower(7)
|
burnAmount = sdk.TokensFromConsensusPower(7)
|
||||||
|
|
||||||
// read updated pool
|
// read updated pool
|
||||||
bondedPool = keeper.GetBondedPool(ctx)
|
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
|
||||||
notBondedPool = keeper.GetNotBondedPool(ctx)
|
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
|
|
||||||
// seven bonded tokens burned
|
// seven bonded tokens burned
|
||||||
bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
|
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
|
||||||
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
||||||
|
|
||||||
bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
|
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
|
||||||
|
|
||||||
notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
||||||
oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
|
|
||||||
// read updating redelegation
|
// read updating redelegation
|
||||||
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, rd.Entries, 1)
|
require.Len(t, rd.Entries, 1)
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
// power decreased by 4
|
// power decreased by 4
|
||||||
require.Equal(t, int64(4), validator.GetConsensusPower())
|
require.Equal(t, int64(4), validator.GetConsensusPower())
|
||||||
|
|
||||||
// slash the validator again, by 100%
|
// slash the validator again, by 100%
|
||||||
ctx = ctx.WithBlockHeight(12)
|
ctx = ctx.WithBlockHeight(12)
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
|
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
|
||||||
|
|
||||||
burnAmount = sdk.TokensFromConsensusPower(10).ToDec().Mul(sdk.OneDec()).TruncateInt()
|
burnAmount = sdk.TokensFromConsensusPower(10).ToDec().Mul(sdk.OneDec()).TruncateInt()
|
||||||
burnAmount = burnAmount.Sub(sdk.OneDec().MulInt(rdTokens).TruncateInt())
|
burnAmount = burnAmount.Sub(sdk.OneDec().MulInt(rdTokens).TruncateInt())
|
||||||
|
|
||||||
// read updated pool
|
// read updated pool
|
||||||
bondedPool = keeper.GetBondedPool(ctx)
|
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
|
||||||
notBondedPool = keeper.GetNotBondedPool(ctx)
|
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
|
|
||||||
bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
|
require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance))
|
||||||
notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
||||||
oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
|
|
||||||
// read updating redelegation
|
// read updating redelegation
|
||||||
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, rd.Entries, 1)
|
require.Len(t, rd.Entries, 1)
|
||||||
// apply TM updates
|
// apply TM updates
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
// read updated validator
|
// read updated validator
|
||||||
// validator decreased to zero power, should be in unbonding period
|
// validator decreased to zero power, should be in unbonding period
|
||||||
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
|
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
|
||||||
|
|
||||||
// slash the validator again, by 100%
|
// slash the validator again, by 100%
|
||||||
// no stake remains to be slashed
|
// no stake remains to be slashed
|
||||||
ctx = ctx.WithBlockHeight(12)
|
ctx = ctx.WithBlockHeight(12)
|
||||||
// validator still in unbonding period
|
// validator still in unbonding period
|
||||||
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
|
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
|
||||||
|
|
||||||
require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
|
require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) })
|
||||||
|
|
||||||
// read updated pool
|
// read updated pool
|
||||||
bondedPool = keeper.GetBondedPool(ctx)
|
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
|
||||||
notBondedPool = keeper.GetNotBondedPool(ctx)
|
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
|
|
||||||
bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldBonded, bondedPoolBalance))
|
require.True(sdk.IntEq(t, oldBonded, bondedPoolBalance))
|
||||||
notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance))
|
||||||
|
|
||||||
// read updating redelegation
|
// read updating redelegation
|
||||||
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, rd.Entries, 1)
|
require.Len(t, rd.Entries, 1)
|
||||||
// read updated validator
|
// read updated validator
|
||||||
// power still zero, still in unbonding period
|
// power still zero, still in unbonding period
|
||||||
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
|
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests Slash at a previous height with both an unbonding delegation and a redelegation
|
// tests Slash at a previous height with both an unbonding delegation and a redelegation
|
||||||
func TestSlashBoth(t *testing.T) {
|
func TestSlashBoth(t *testing.T) {
|
||||||
ctx, keeper, _ := setupHelper(t, 10)
|
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
|
||||||
fraction := sdk.NewDecWithPrec(5, 1)
|
fraction := sdk.NewDecWithPrec(5, 1)
|
||||||
bondDenom := keeper.BondDenom(ctx)
|
bondDenom := app.StakingKeeper.BondDenom(ctx)
|
||||||
|
|
||||||
// set a redelegation with expiration timestamp beyond which the
|
// set a redelegation with expiration timestamp beyond which the
|
||||||
// redelegation shouldn't be slashed
|
// redelegation shouldn't be slashed
|
||||||
|
@ -540,64 +556,64 @@ func TestSlashBoth(t *testing.T) {
|
||||||
rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11,
|
rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11,
|
||||||
time.Unix(0, 0), rdATokens,
|
time.Unix(0, 0), rdATokens,
|
||||||
rdATokens.ToDec())
|
rdATokens.ToDec())
|
||||||
keeper.SetRedelegation(ctx, rdA)
|
app.StakingKeeper.SetRedelegation(ctx, rdA)
|
||||||
|
|
||||||
// set the associated delegation
|
// set the associated delegation
|
||||||
delA := types.NewDelegation(addrDels[0], addrVals[1], rdATokens.ToDec())
|
delA := types.NewDelegation(addrDels[0], addrVals[1], rdATokens.ToDec())
|
||||||
keeper.SetDelegation(ctx, delA)
|
app.StakingKeeper.SetDelegation(ctx, delA)
|
||||||
|
|
||||||
// set an unbonding delegation with expiration timestamp (beyond which the
|
// set an unbonding delegation with expiration timestamp (beyond which the
|
||||||
// unbonding delegation shouldn't be slashed)
|
// unbonding delegation shouldn't be slashed)
|
||||||
ubdATokens := sdk.TokensFromConsensusPower(4)
|
ubdATokens := sdk.TokensFromConsensusPower(4)
|
||||||
ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
|
ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
|
||||||
time.Unix(0, 0), ubdATokens)
|
time.Unix(0, 0), ubdATokens)
|
||||||
keeper.SetUnbondingDelegation(ctx, ubdA)
|
app.StakingKeeper.SetUnbondingDelegation(ctx, ubdA)
|
||||||
|
|
||||||
bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdATokens.MulRaw(2)))
|
bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdATokens.MulRaw(2)))
|
||||||
notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, ubdATokens))
|
notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, ubdATokens))
|
||||||
|
|
||||||
// update bonded tokens
|
// update bonded tokens
|
||||||
bondedPool := keeper.GetBondedPool(ctx)
|
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||||
notBondedPool := keeper.GetNotBondedPool(ctx)
|
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
|
|
||||||
bondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
bondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
|
||||||
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...)))
|
require.NoError(t, app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...)))
|
||||||
|
|
||||||
notBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
|
notBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
|
||||||
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...)))
|
require.NoError(t, app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...)))
|
||||||
|
|
||||||
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
|
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
|
||||||
keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool)
|
app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool)
|
||||||
|
|
||||||
oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
||||||
// slash validator
|
// slash validator
|
||||||
ctx = ctx.WithBlockHeight(12)
|
ctx = ctx.WithBlockHeight(12)
|
||||||
validator, found := keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
|
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
consAddr0 := sdk.ConsAddress(PKs[0].Address())
|
consAddr0 := sdk.ConsAddress(PKs[0].Address())
|
||||||
keeper.Slash(ctx, consAddr0, 10, 10, fraction)
|
app.StakingKeeper.Slash(ctx, consAddr0, 10, 10, fraction)
|
||||||
|
|
||||||
burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt()
|
burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt()
|
||||||
burnedBondAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt()
|
burnedBondAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt()
|
||||||
burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount)
|
burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount)
|
||||||
|
|
||||||
// read updated pool
|
// read updated pool
|
||||||
bondedPool = keeper.GetBondedPool(ctx)
|
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
|
||||||
notBondedPool = keeper.GetNotBondedPool(ctx)
|
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
|
||||||
|
|
||||||
bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldBonded.Sub(burnedBondAmount), bondedPoolBalance))
|
require.True(sdk.IntEq(t, oldBonded.Sub(burnedBondAmount), bondedPoolBalance))
|
||||||
|
|
||||||
notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
|
||||||
require.True(sdk.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance))
|
require.True(sdk.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance))
|
||||||
|
|
||||||
// read updating redelegation
|
// read updating redelegation
|
||||||
rdA, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
rdA, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Len(t, rdA.Entries, 1)
|
require.Len(t, rdA.Entries, 1)
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
|
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
// power not decreased, all stake was bonded since
|
// power not decreased, all stake was bonded since
|
||||||
require.Equal(t, int64(10), validator.GetConsensusPower())
|
require.Equal(t, int64(10), validator.GetConsensusPower())
|
||||||
|
|
|
@ -1,248 +1,13 @@
|
||||||
package keeper
|
package keeper // noalias
|
||||||
|
|
||||||
// noalias
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
|
||||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
|
||||||
dbm "github.com/tendermint/tm-db"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
simappcodec "github.com/cosmos/cosmos-sdk/simapp/codec"
|
|
||||||
"github.com/cosmos/cosmos-sdk/store"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
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/bank"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/params/keeper"
|
|
||||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/params/types/proposal"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// dummy addresses used for testing
|
|
||||||
// nolint:unused, deadcode
|
|
||||||
var (
|
|
||||||
Addrs = createTestAddrs(500)
|
|
||||||
PKs = createTestPubKeys(500)
|
|
||||||
|
|
||||||
addrDels = []sdk.AccAddress{
|
|
||||||
Addrs[0],
|
|
||||||
Addrs[1],
|
|
||||||
}
|
|
||||||
addrVals = []sdk.ValAddress{
|
|
||||||
sdk.ValAddress(Addrs[2]),
|
|
||||||
sdk.ValAddress(Addrs[3]),
|
|
||||||
sdk.ValAddress(Addrs[4]),
|
|
||||||
sdk.ValAddress(Addrs[5]),
|
|
||||||
sdk.ValAddress(Addrs[6]),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
//_______________________________________________________________________________________
|
|
||||||
|
|
||||||
// intended to be used with require/assert: require.True(ValEq(...))
|
|
||||||
func ValEq(t *testing.T, exp, got types.Validator) (*testing.T, bool, string, types.Validator, types.Validator) {
|
|
||||||
return t, exp.MinEqual(got), "expected:\n%v\ngot:\n%v", exp, got
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________________________________________
|
|
||||||
|
|
||||||
// create a codec used only for testing
|
|
||||||
func MakeTestCodec() *codec.Codec {
|
|
||||||
var cdc = codec.New()
|
|
||||||
|
|
||||||
// Register Msgs
|
|
||||||
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
|
||||||
cdc.RegisterConcrete(bank.MsgSend{}, "test/staking/Send", nil)
|
|
||||||
cdc.RegisterConcrete(types.MsgCreateValidator{}, "test/staking/CreateValidator", nil)
|
|
||||||
cdc.RegisterConcrete(types.MsgEditValidator{}, "test/staking/EditValidator", nil)
|
|
||||||
cdc.RegisterConcrete(types.MsgUndelegate{}, "test/staking/Undelegate", nil)
|
|
||||||
cdc.RegisterConcrete(types.MsgBeginRedelegate{}, "test/staking/BeginRedelegate", nil)
|
|
||||||
|
|
||||||
// Register AppAccount
|
|
||||||
cdc.RegisterInterface((*authexported.Account)(nil), nil)
|
|
||||||
cdc.RegisterConcrete(&auth.BaseAccount{}, "test/staking/BaseAccount", nil)
|
|
||||||
supply.RegisterCodec(cdc)
|
|
||||||
codec.RegisterCrypto(cdc)
|
|
||||||
|
|
||||||
return cdc
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hogpodge of all sorts of input required for testing.
|
|
||||||
// `initPower` is converted to an amount of tokens.
|
|
||||||
// If `initPower` is 0, no addrs get created.
|
|
||||||
func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context, auth.AccountKeeper, types.BankKeeper, Keeper, types.SupplyKeeper) {
|
|
||||||
keyStaking := sdk.NewKVStoreKey(types.StoreKey)
|
|
||||||
keyAcc := sdk.NewKVStoreKey(auth.StoreKey)
|
|
||||||
bankKey := sdk.NewKVStoreKey(bank.StoreKey)
|
|
||||||
keyParams := sdk.NewKVStoreKey(paramtypes.StoreKey)
|
|
||||||
tkeyParams := sdk.NewTransientStoreKey(paramtypes.TStoreKey)
|
|
||||||
keySupply := sdk.NewKVStoreKey(supply.StoreKey)
|
|
||||||
|
|
||||||
db := dbm.NewMemDB()
|
|
||||||
ms := store.NewCommitMultiStore(db)
|
|
||||||
ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db)
|
|
||||||
ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
|
|
||||||
ms.MountStoreWithDB(bankKey, sdk.StoreTypeIAVL, db)
|
|
||||||
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
|
|
||||||
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
|
|
||||||
ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db)
|
|
||||||
err := ms.LoadLatestVersion()
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger())
|
|
||||||
ctx = ctx.WithConsensusParams(
|
|
||||||
&abci.ConsensusParams{
|
|
||||||
Validator: &abci.ValidatorParams{
|
|
||||||
PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
cdc := MakeTestCodec()
|
|
||||||
appCodec := simappcodec.NewAppCodec(cdc)
|
|
||||||
|
|
||||||
feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
|
|
||||||
notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking)
|
|
||||||
bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking)
|
|
||||||
|
|
||||||
blacklistedAddrs := make(map[string]bool)
|
|
||||||
blacklistedAddrs[feeCollectorAcc.GetAddress().String()] = true
|
|
||||||
blacklistedAddrs[notBondedPool.GetAddress().String()] = true
|
|
||||||
blacklistedAddrs[bondPool.GetAddress().String()] = true
|
|
||||||
|
|
||||||
pk := keeper.NewKeeper(proposal.ModuleCdc, keyParams, tkeyParams)
|
|
||||||
|
|
||||||
accountKeeper := auth.NewAccountKeeper(
|
|
||||||
appCodec,
|
|
||||||
keyAcc,
|
|
||||||
pk.Subspace(auth.DefaultParamspace),
|
|
||||||
auth.ProtoBaseAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
bk := bank.NewBaseKeeper(
|
|
||||||
appCodec,
|
|
||||||
bankKey,
|
|
||||||
accountKeeper,
|
|
||||||
pk.Subspace(bank.DefaultParamspace),
|
|
||||||
blacklistedAddrs,
|
|
||||||
)
|
|
||||||
|
|
||||||
maccPerms := map[string][]string{
|
|
||||||
auth.FeeCollectorName: nil,
|
|
||||||
types.NotBondedPoolName: {supply.Burner, supply.Staking},
|
|
||||||
types.BondedPoolName: {supply.Burner, supply.Staking},
|
|
||||||
}
|
|
||||||
supplyKeeper := supply.NewKeeper(appCodec, keySupply, accountKeeper, bk, maccPerms)
|
|
||||||
|
|
||||||
initTokens := sdk.TokensFromConsensusPower(initPower)
|
|
||||||
initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
|
|
||||||
totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(Addrs)))))
|
|
||||||
|
|
||||||
supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
|
|
||||||
|
|
||||||
keeper := NewKeeper(types.ModuleCdc, keyStaking, bk, supplyKeeper, pk.Subspace(DefaultParamspace))
|
|
||||||
keeper.SetParams(ctx, types.DefaultParams())
|
|
||||||
|
|
||||||
// set module accounts
|
|
||||||
require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply))
|
|
||||||
|
|
||||||
supplyKeeper.SetModuleAccount(ctx, feeCollectorAcc)
|
|
||||||
supplyKeeper.SetModuleAccount(ctx, bondPool)
|
|
||||||
supplyKeeper.SetModuleAccount(ctx, notBondedPool)
|
|
||||||
|
|
||||||
// fill all the addresses with some coins, set the loose pool tokens simultaneously
|
|
||||||
for i, addr := range Addrs {
|
|
||||||
accountKeeper.SetAccount(ctx, auth.NewBaseAccount(addr, PKs[i], uint64(i), 0))
|
|
||||||
require.NoError(t, bk.SetBalances(ctx, addr, initCoins))
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx, accountKeeper, bk, keeper, supplyKeeper
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPubKey(pk string) (res crypto.PubKey) {
|
|
||||||
pkBytes, err := hex.DecodeString(pk)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
//res, err = crypto.PubKeyFromBytes(pkBytes)
|
|
||||||
var pkEd ed25519.PubKeyEd25519
|
|
||||||
copy(pkEd[:], pkBytes)
|
|
||||||
return pkEd
|
|
||||||
}
|
|
||||||
|
|
||||||
// for incode address generation
|
|
||||||
func TestAddr(addr string, bech string) sdk.AccAddress {
|
|
||||||
|
|
||||||
res, err := sdk.AccAddressFromHex(addr)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
bechexpected := res.String()
|
|
||||||
if bech != bechexpected {
|
|
||||||
panic("Bech encoding doesn't match reference")
|
|
||||||
}
|
|
||||||
|
|
||||||
bechres, err := sdk.AccAddressFromBech32(bech)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(bechres, res) {
|
|
||||||
panic("Bech decode and hex decode don't match")
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint: unparam
|
|
||||||
func createTestAddrs(numAddrs int) []sdk.AccAddress {
|
|
||||||
var addresses []sdk.AccAddress
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
|
|
||||||
// start at 100 so we can make up to 999 test addresses with valid test addresses
|
|
||||||
for i := 100; i < (numAddrs + 100); i++ {
|
|
||||||
numString := strconv.Itoa(i)
|
|
||||||
buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string
|
|
||||||
|
|
||||||
buffer.WriteString(numString) //adding on final two digits to make addresses unique
|
|
||||||
res, _ := sdk.AccAddressFromHex(buffer.String())
|
|
||||||
bech := res.String()
|
|
||||||
addresses = append(addresses, TestAddr(buffer.String(), bech))
|
|
||||||
buffer.Reset()
|
|
||||||
}
|
|
||||||
return addresses
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint: unparam
|
|
||||||
func createTestPubKeys(numPubKeys int) []crypto.PubKey {
|
|
||||||
var publicKeys []crypto.PubKey
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
|
|
||||||
//start at 10 to avoid changing 1 to 01, 2 to 02, etc
|
|
||||||
for i := 100; i < (numPubKeys + 100); i++ {
|
|
||||||
numString := strconv.Itoa(i)
|
|
||||||
buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") //base pubkey string
|
|
||||||
buffer.WriteString(numString) //adding on final two digits to make pubkeys unique
|
|
||||||
publicKeys = append(publicKeys, NewPubKey(buffer.String()))
|
|
||||||
buffer.Reset()
|
|
||||||
}
|
|
||||||
return publicKeys
|
|
||||||
}
|
|
||||||
|
|
||||||
//_____________________________________________________________________________________
|
|
||||||
|
|
||||||
// does a certain by-power index record exist
|
// does a certain by-power index record exist
|
||||||
func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) bool {
|
func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) bool {
|
||||||
store := ctx.KVStore(keeper.storeKey)
|
store := ctx.KVStore(keeper.storeKey)
|
||||||
|
@ -291,12 +56,6 @@ func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Vali
|
||||||
return validator
|
return validator
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:deadcode, unused
|
|
||||||
func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool {
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
|
||||||
return store.Has(power)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RandomValidator returns a random validator given access to the keeper and ctx
|
// RandomValidator returns a random validator given access to the keeper and ctx
|
||||||
func RandomValidator(r *rand.Rand, keeper Keeper, ctx sdk.Context) (val types.Validator, ok bool) {
|
func RandomValidator(r *rand.Rand, keeper Keeper, ctx sdk.Context) (val types.Validator, ok bool) {
|
||||||
vals := keeper.GetAllValidators(ctx)
|
vals := keeper.GetAllValidators(ctx)
|
||||||
|
|
|
@ -210,7 +210,7 @@ func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) typ
|
||||||
}
|
}
|
||||||
|
|
||||||
// switches a validator from unbonding state to unbonded state
|
// switches a validator from unbonding state to unbonded state
|
||||||
func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) types.Validator {
|
func (k Keeper) UnbondingToUnbonded(ctx sdk.Context, validator types.Validator) types.Validator {
|
||||||
if !validator.IsUnbonding() {
|
if !validator.IsUnbonding() {
|
||||||
panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator))
|
panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator))
|
||||||
}
|
}
|
||||||
|
|
|
@ -441,7 +441,7 @@ func (k Keeper) UnbondAllMatureValidatorQueue(ctx sdk.Context) {
|
||||||
panic("unexpected validator in unbonding queue; status was not unbonding")
|
panic("unexpected validator in unbonding queue; status was not unbonding")
|
||||||
}
|
}
|
||||||
|
|
||||||
val = k.unbondingToUnbonded(ctx, val)
|
val = k.UnbondingToUnbonded(ctx, val)
|
||||||
if val.GetDelegatorShares().IsZero() {
|
if val.GetDelegatorShares().IsZero() {
|
||||||
k.RemoveValidator(ctx, val.OperatorAddress)
|
k.RemoveValidator(ctx, val.OperatorAddress)
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,8 +3,9 @@ package types
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCommissionRates returns an initialized validator commission rates.
|
// NewCommissionRates returns an initialized validator commission rates.
|
||||||
|
|
|
@ -6,10 +6,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/exported"
|
"github.com/cosmos/cosmos-sdk/x/staking/exported"
|
||||||
yaml "gopkg.in/yaml.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Implements Delegation interface
|
// Implements Delegation interface
|
||||||
|
|
|
@ -6,10 +6,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
yaml "gopkg.in/yaml.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Staking params default values
|
// Staking params default values
|
||||||
|
|
|
@ -38,6 +38,14 @@ func BeginBlocker(k Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) {
|
||||||
upgradeMsg := fmt.Sprintf("UPGRADE \"%s\" NEEDED at %s: %s", plan.Name, plan.DueAt(), plan.Info)
|
upgradeMsg := fmt.Sprintf("UPGRADE \"%s\" NEEDED at %s: %s", plan.Name, plan.DueAt(), plan.Info)
|
||||||
// We don't have an upgrade handler for this upgrade name, meaning this software is out of date so shutdown
|
// We don't have an upgrade handler for this upgrade name, meaning this software is out of date so shutdown
|
||||||
ctx.Logger().Error(upgradeMsg)
|
ctx.Logger().Error(upgradeMsg)
|
||||||
|
|
||||||
|
// Write the upgrade info to disk. The UpgradeStoreLoader uses this info to perform or skip
|
||||||
|
// store migrations.
|
||||||
|
err := k.DumpUpgradeInfoToDisk(ctx.BlockHeight(), plan.Name)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("unable to write upgrade info to filesystem: %s", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
panic(upgradeMsg)
|
panic(upgradeMsg)
|
||||||
}
|
}
|
||||||
// We have an upgrade handler for this upgrade name, so apply the upgrade
|
// We have an upgrade handler for this upgrade name, so apply the upgrade
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package upgrade_test
|
package upgrade_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
@ -31,7 +36,7 @@ var s TestSuite
|
||||||
|
|
||||||
func setupTest(height int64, skip map[int64]bool) TestSuite {
|
func setupTest(height int64, skip map[int64]bool) TestSuite {
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, skip, 0)
|
app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, skip, simapp.DefaultNodeHome, 0)
|
||||||
genesisState := simapp.NewDefaultGenesisState()
|
genesisState := simapp.NewDefaultGenesisState()
|
||||||
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
|
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -393,3 +398,30 @@ func TestUpgradeWithoutSkip(t *testing.T) {
|
||||||
VerifyDoUpgrade(t)
|
VerifyDoUpgrade(t)
|
||||||
VerifyDone(t, s.ctx, "test")
|
VerifyDone(t, s.ctx, "test")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDumpUpgradeInfoToFile(t *testing.T) {
|
||||||
|
s := setupTest(10, map[int64]bool{})
|
||||||
|
|
||||||
|
planHeight := s.ctx.BlockHeight() + 1
|
||||||
|
name := "test"
|
||||||
|
t.Log("verify if upgrade height is dumped to file")
|
||||||
|
err := s.keeper.DumpUpgradeInfoToDisk(planHeight, name)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
upgradeInfoFilePath, err := s.keeper.GetUpgradeInfoPath()
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(upgradeInfoFilePath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var upgradeInfo storetypes.UpgradeInfo
|
||||||
|
err = json.Unmarshal(data, &upgradeInfo)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
t.Log("Verify upgrade height from file matches ")
|
||||||
|
require.Equal(t, upgradeInfo.Height, planHeight)
|
||||||
|
|
||||||
|
// clear the test file
|
||||||
|
err = os.Remove(upgradeInfoFilePath)
|
||||||
|
require.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ var (
|
||||||
NewSoftwareUpgradeProposal = types.NewSoftwareUpgradeProposal
|
NewSoftwareUpgradeProposal = types.NewSoftwareUpgradeProposal
|
||||||
NewCancelSoftwareUpgradeProposal = types.NewCancelSoftwareUpgradeProposal
|
NewCancelSoftwareUpgradeProposal = types.NewCancelSoftwareUpgradeProposal
|
||||||
NewQueryAppliedParams = types.NewQueryAppliedParams
|
NewQueryAppliedParams = types.NewQueryAppliedParams
|
||||||
|
UpgradeStoreLoader = types.UpgradeStoreLoader
|
||||||
NewKeeper = keeper.NewKeeper
|
NewKeeper = keeper.NewKeeper
|
||||||
NewQuerier = keeper.NewQuerier
|
NewQuerier = keeper.NewQuerier
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cli
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
|
@ -68,6 +68,27 @@ as well as providing the opportunity for the upgraded software to perform any ne
|
||||||
(with the old binary) and applying the migration (with the new binary) are enforced in the state machine. Actually
|
(with the old binary) and applying the migration (with the new binary) are enforced in the state machine. Actually
|
||||||
switching the binaries is an ops task and not handled inside the sdk / abci app.
|
switching the binaries is an ops task and not handled inside the sdk / abci app.
|
||||||
|
|
||||||
|
Here is a sample code to set store migrations with an upgrade:
|
||||||
|
|
||||||
|
// this configures a no-op upgrade handler for the "my-fancy-upgrade" upgrade
|
||||||
|
app.UpgradeKeeper.SetUpgradeHandler("my-fancy-upgrade", func(ctx sdk.Context, plan upgrade.Plan) {
|
||||||
|
// upgrade changes here
|
||||||
|
})
|
||||||
|
|
||||||
|
upgradeInfo := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
|
||||||
|
if upgradeInfo.Name == "my-fancy-upgrade" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
|
||||||
|
storeUpgrades := store.StoreUpgrades{
|
||||||
|
Renamed: []store.StoreRename{{
|
||||||
|
OldKey: "foo",
|
||||||
|
NewKey: "bar",
|
||||||
|
}},
|
||||||
|
Deleted: []string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure store loader that checks if version == upgradeHeight and applies store upgrades
|
||||||
|
app.SetStoreLoader(upgrade.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
|
||||||
|
}
|
||||||
|
|
||||||
Halt Behavior
|
Halt Behavior
|
||||||
|
|
||||||
Before halting the ABCI state machine in the BeginBlocker method, the upgrade module will log an error
|
Before halting the ABCI state machine in the BeginBlocker method, the upgrade module will log an error
|
||||||
|
|
|
@ -2,18 +2,30 @@ package keeper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
tmos "github.com/tendermint/tendermint/libs/os"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||||
|
store "github.com/cosmos/cosmos-sdk/store/types"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// UpgradeInfoFileName file to store upgrade information
|
||||||
|
const UpgradeInfoFileName string = "upgrade-info.json"
|
||||||
|
|
||||||
type Keeper struct {
|
type Keeper struct {
|
||||||
|
homePath string
|
||||||
skipUpgradeHeights map[int64]bool
|
skipUpgradeHeights map[int64]bool
|
||||||
storeKey sdk.StoreKey
|
storeKey sdk.StoreKey
|
||||||
cdc codec.Marshaler
|
cdc codec.Marshaler
|
||||||
|
@ -21,8 +33,9 @@ type Keeper struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewKeeper constructs an upgrade Keeper
|
// NewKeeper constructs an upgrade Keeper
|
||||||
func NewKeeper(skipUpgradeHeights map[int64]bool, storeKey sdk.StoreKey, cdc codec.Marshaler) Keeper {
|
func NewKeeper(skipUpgradeHeights map[int64]bool, storeKey sdk.StoreKey, cdc codec.Marshaler, homePath string) Keeper {
|
||||||
return Keeper{
|
return Keeper{
|
||||||
|
homePath: homePath,
|
||||||
skipUpgradeHeights: skipUpgradeHeights,
|
skipUpgradeHeights: skipUpgradeHeights,
|
||||||
storeKey: storeKey,
|
storeKey: storeKey,
|
||||||
cdc: cdc,
|
cdc: cdc,
|
||||||
|
@ -130,3 +143,59 @@ func (k Keeper) ApplyUpgrade(ctx sdk.Context, plan types.Plan) {
|
||||||
func (k Keeper) IsSkipHeight(height int64) bool {
|
func (k Keeper) IsSkipHeight(height int64) bool {
|
||||||
return k.skipUpgradeHeights[height]
|
return k.skipUpgradeHeights[height]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DumpUpgradeInfoToDisk writes upgrade information to UpgradeInfoFileName.
|
||||||
|
func (k Keeper) DumpUpgradeInfoToDisk(height int64, name string) error {
|
||||||
|
upgradeInfoFilePath, err := k.GetUpgradeInfoPath()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
upgradeInfo := store.UpgradeInfo{
|
||||||
|
Name: name,
|
||||||
|
Height: height,
|
||||||
|
}
|
||||||
|
info, err := json.Marshal(upgradeInfo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioutil.WriteFile(upgradeInfoFilePath, info, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUpgradeInfoPath returns the upgrade info file path
|
||||||
|
func (k Keeper) GetUpgradeInfoPath() (string, error) {
|
||||||
|
upgradeInfoFileDir := path.Join(k.getHomeDir(), "data")
|
||||||
|
err := tmos.EnsureDir(upgradeInfoFileDir, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Join(upgradeInfoFileDir, UpgradeInfoFileName), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getHomeDir returns the height at which the given upgrade was executed
|
||||||
|
func (k Keeper) getHomeDir() string {
|
||||||
|
return k.homePath
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadUpgradeInfoFromDisk returns the name and height of the upgrade
|
||||||
|
// which is written to disk by the old binary when panic'ing
|
||||||
|
// if there's an error in reading the info,
|
||||||
|
// it assumes that the upgrade info is not available
|
||||||
|
func (k Keeper) ReadUpgradeInfoFromDisk() (upgradeInfo store.UpgradeInfo) {
|
||||||
|
upgradeInfoPath, err := k.GetUpgradeInfoPath()
|
||||||
|
// if error in reading the path, assume there are no upgrades
|
||||||
|
if err != nil {
|
||||||
|
return upgradeInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(upgradeInfoPath)
|
||||||
|
// if error in reading the file, assume there are no upgrades
|
||||||
|
if err != nil {
|
||||||
|
return upgradeInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
json.Unmarshal(data, &upgradeInfo)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package keeper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
|
@ -56,6 +56,33 @@ During each `EndBlock` execution, the `x/upgrade` module checks if there exists
|
||||||
`Handler` is executed. If the `Plan` is expected to execute but no `Handler` is registered
|
`Handler` is executed. If the `Plan` is expected to execute but no `Handler` is registered
|
||||||
or if the binary was upgraded too early, the node will gracefully panic and exit.
|
or if the binary was upgraded too early, the node will gracefully panic and exit.
|
||||||
|
|
||||||
|
## StoreLoader
|
||||||
|
|
||||||
|
|
||||||
|
The `x/upgrade` module also facilitates store migrations as part of the upgrade. The
|
||||||
|
`StoreLoader` sets the migrations that need to occur before the new binary can
|
||||||
|
successfully run the chain. This `StoreLoader` is also application specific and
|
||||||
|
not defined on a per-module basis. Registering this `StoreLoader` is done via
|
||||||
|
`app#SetStoreLoader` in the application.
|
||||||
|
|
||||||
|
```go
|
||||||
|
func UpgradeStoreLoader (upgradeHeight int64, storeUpgrades *store.StoreUpgrades) baseapp.StoreLoader
|
||||||
|
```
|
||||||
|
|
||||||
|
If there's a planned upgrade and the upgrade height is reached, the old binary writes `UpgradeInfo` to the disk before panic'ing.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type UpgradeInfo struct {
|
||||||
|
Name string
|
||||||
|
Height int64
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This information is critical to ensure the `StoreUpgrades` happens smoothly at correct height and
|
||||||
|
expected upgrade. It eliminiates the chances for the new binary to execute `StoreUpgrades` multiple
|
||||||
|
times everytime on restart. Also if there are multiple upgrades planned on same height, the `Name`
|
||||||
|
will ensure these `StoreUpgrades` takes place only in planned upgrade handler.
|
||||||
|
|
||||||
## Proposal
|
## Proposal
|
||||||
|
|
||||||
Typically, a `Plan` is proposed and submitted through governance via a `SoftwareUpgradeProposal`.
|
Typically, a `Plan` is proposed and submitted through governance via a `SoftwareUpgradeProposal`.
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
|
store "github.com/cosmos/cosmos-sdk/store/types"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UpgradeStoreLoader is used to prepare baseapp with a fixed StoreLoader
|
||||||
|
// pattern. This is useful for custom upgrade loading logic.
|
||||||
|
func UpgradeStoreLoader(upgradeHeight int64, storeUpgrades *store.StoreUpgrades) baseapp.StoreLoader {
|
||||||
|
return func(ms sdk.CommitMultiStore) error {
|
||||||
|
if upgradeHeight == ms.LastCommitID().Version {
|
||||||
|
// Check if the current commit version and upgrade height matches
|
||||||
|
if len(storeUpgrades.Renamed) > 0 || len(storeUpgrades.Deleted) > 0 {
|
||||||
|
return ms.LoadLatestVersionAndUpgrade(storeUpgrades)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise load default store loader
|
||||||
|
return baseapp.DefaultStoreLoader(ms)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
dbm "github.com/tendermint/tm-db"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
|
"github.com/cosmos/cosmos-sdk/store/rootmulti"
|
||||||
|
store "github.com/cosmos/cosmos-sdk/store/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/tests"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func useUpgradeLoader(height int64, upgrades *store.StoreUpgrades) func(*baseapp.BaseApp) {
|
||||||
|
return func(app *baseapp.BaseApp) {
|
||||||
|
app.SetStoreLoader(UpgradeStoreLoader(height, upgrades))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultLogger() log.Logger {
|
||||||
|
return log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initStore(t *testing.T, db dbm.DB, storeKey string, k, v []byte) {
|
||||||
|
rs := rootmulti.NewStore(db)
|
||||||
|
rs.SetPruning(store.PruneNothing)
|
||||||
|
key := sdk.NewKVStoreKey(storeKey)
|
||||||
|
rs.MountStoreWithDB(key, store.StoreTypeIAVL, nil)
|
||||||
|
err := rs.LoadLatestVersion()
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, int64(0), rs.LastCommitID().Version)
|
||||||
|
|
||||||
|
// write some data in substore
|
||||||
|
kv, _ := rs.GetStore(key).(store.KVStore)
|
||||||
|
require.NotNil(t, kv)
|
||||||
|
kv.Set(k, v)
|
||||||
|
commitID := rs.Commit()
|
||||||
|
require.Equal(t, int64(1), commitID.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkStore(t *testing.T, db dbm.DB, ver int64, storeKey string, k, v []byte) {
|
||||||
|
rs := rootmulti.NewStore(db)
|
||||||
|
rs.SetPruning(store.PruneNothing)
|
||||||
|
key := sdk.NewKVStoreKey(storeKey)
|
||||||
|
rs.MountStoreWithDB(key, store.StoreTypeIAVL, nil)
|
||||||
|
err := rs.LoadLatestVersion()
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, ver, rs.LastCommitID().Version)
|
||||||
|
|
||||||
|
// query data in substore
|
||||||
|
kv, _ := rs.GetStore(key).(store.KVStore)
|
||||||
|
|
||||||
|
require.NotNil(t, kv)
|
||||||
|
require.Equal(t, v, kv.Get(k))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that we can make commits and then reload old versions.
|
||||||
|
// Test that LoadLatestVersion actually does.
|
||||||
|
func TestSetLoader(t *testing.T) {
|
||||||
|
// set a temporary home dir
|
||||||
|
homeDir, cleanUp := tests.NewTestCaseDir(t)
|
||||||
|
defer cleanUp()
|
||||||
|
// TODO cleanup viper
|
||||||
|
viper.Set(flags.FlagHome, homeDir)
|
||||||
|
|
||||||
|
upgradeInfoFilePath := filepath.Join(homeDir, "upgrade-info.json")
|
||||||
|
upgradeInfo := &store.UpgradeInfo{
|
||||||
|
Name: "test", Height: 0,
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(upgradeInfo)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = ioutil.WriteFile(upgradeInfoFilePath, data, 0644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// make sure it exists before running everything
|
||||||
|
_, err = os.Stat(upgradeInfoFilePath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
cases := map[string]struct {
|
||||||
|
setLoader func(*baseapp.BaseApp)
|
||||||
|
origStoreKey string
|
||||||
|
loadStoreKey string
|
||||||
|
}{
|
||||||
|
"don't set loader": {
|
||||||
|
origStoreKey: "foo",
|
||||||
|
loadStoreKey: "foo",
|
||||||
|
},
|
||||||
|
"rename with inline opts": {
|
||||||
|
setLoader: useUpgradeLoader(0, &store.StoreUpgrades{
|
||||||
|
Renamed: []store.StoreRename{{
|
||||||
|
OldKey: "foo",
|
||||||
|
NewKey: "bar",
|
||||||
|
}},
|
||||||
|
}),
|
||||||
|
origStoreKey: "foo",
|
||||||
|
loadStoreKey: "bar",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
k := []byte("key")
|
||||||
|
v := []byte("value")
|
||||||
|
|
||||||
|
for name, tc := range cases {
|
||||||
|
tc := tc
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
// prepare a db with some data
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
|
||||||
|
initStore(t, db, tc.origStoreKey, k, v)
|
||||||
|
|
||||||
|
// load the app with the existing db
|
||||||
|
opts := []func(*baseapp.BaseApp){baseapp.SetPruning(store.PruneNothing)}
|
||||||
|
if tc.setLoader != nil {
|
||||||
|
opts = append(opts, tc.setLoader)
|
||||||
|
}
|
||||||
|
|
||||||
|
app := baseapp.NewBaseApp(t.Name(), defaultLogger(), db, nil, opts...)
|
||||||
|
capKey := sdk.NewKVStoreKey(baseapp.MainStoreKey)
|
||||||
|
app.MountStores(capKey)
|
||||||
|
app.MountStores(sdk.NewKVStoreKey(tc.loadStoreKey))
|
||||||
|
err := app.LoadLatestVersion(capKey)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
// "execute" one block
|
||||||
|
app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: 2}})
|
||||||
|
res := app.Commit()
|
||||||
|
require.NotNil(t, res.Data)
|
||||||
|
|
||||||
|
// check db is properly updated
|
||||||
|
checkStore(t, db, 2, tc.loadStoreKey, k, v)
|
||||||
|
checkStore(t, db, 2, tc.loadStoreKey, []byte("foo"), nil)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue