Merge branch 'master' into bez/5444-gov-proto-enc

This commit is contained in:
Aleksandr Bezobchuk 2020-03-02 12:50:32 -05:00
commit 31dc2729fc
No known key found for this signature in database
GPG Key ID: 7DAC30FBD99879B0
62 changed files with 2153 additions and 1721 deletions

View File

@ -3,7 +3,7 @@ version: 2.1
executors:
golang:
docker:
- image: circleci/golang:1.13
- image: circleci/golang:1.14
docs:
docker:
- image: tendermintdev/docker-website-deployment

2
.github/CODEOWNERS vendored
View File

@ -1,4 +1,4 @@
# CODEOWNERS: https://help.github.com/articles/about-codeowners/
# Primary repo maintainers
* @alexanderbez @jackzampolin @alessio @fedekunze
* @alexanderbez @alessio @fedekunze @nylira @hschoenburg

10
.mergify.yml Normal file
View File

@ -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

View File

@ -46,6 +46,7 @@ balances or a single balance by denom when the `denom` query parameter is presen
### 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
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.
@ -66,6 +67,8 @@ to now accept a `codec.JSONMarshaler` for modular serialization of genesis state
### 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.
* (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`

View File

@ -191,10 +191,10 @@ lint:
go mod verify
.PHONY: lint
format: tools
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" | 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
format:
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" -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" -not -name '*.pb.go' | xargs goimports -w -local github.com/cosmos/cosmos-sdk
.PHONY: format
###############################################################################

View File

@ -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
breaking changes.
**Note**: Requires [Go 1.13+](https://golang.org/dl/)
**Note**: Requires [Go 1.14+](https://golang.org/dl/)
## Quick Start

View File

@ -1,11 +1,8 @@
package baseapp
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"reflect"
"runtime/debug"
"strings"
@ -17,7 +14,6 @@ import (
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/store"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
@ -226,62 +222,6 @@ func DefaultStoreLoader(ms sdk.CommitMultiStore) error {
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
// more than once on a running baseapp.
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()
if err := validateBasicTxMsgs(msgs); err != nil {
gInfo = sdk.GasInfo{GasUsed: ctx.BlockGasMeter().GasConsumed()}
return gInfo, nil, err
return sdk.GasInfo{}, nil, err
}
if app.anteHandler != nil {

View File

@ -4,7 +4,6 @@ import (
"bytes"
"encoding/binary"
"fmt"
"io/ioutil"
"os"
"sync"
"testing"
@ -137,18 +136,6 @@ func useDefaultLoader(app *BaseApp) {
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) {
rs := rootmulti.NewStore(db)
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 LoadLatestVersion actually does.
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 {
setLoader func(*BaseApp)
origStoreKey string
@ -211,26 +185,6 @@ func TestSetLoader(t *testing.T) {
origStoreKey: "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")
@ -265,10 +219,6 @@ func TestSetLoader(t *testing.T) {
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) {

View File

@ -37,10 +37,10 @@ func TestValidateCmd(t *testing.T) {
args []string
wantErr bool
}{
{"misspelled command", []string{"comission"}, true}, // nolint: misspell
{"misspelled command", []string{"commission"}, true}, // nolint: misspell
{"no command provided", []string{}, false},
{"help flag", []string{"comission", "--help"}, false}, // nolint: misspell
{"shorthand help flag", []string{"comission", "-h"}, false}, // nolint: misspell
{"help flag", []string{"commission", "--help"}, false}, // nolint: misspell
{"shorthand help flag", []string{"commission", "-h"}, false}, // nolint: misspell
}
for _, tt := range tests {

View File

@ -3,10 +3,11 @@ package codec_test
import (
"testing"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/testdata"
"github.com/stretchr/testify/require"
amino "github.com/tendermint/go-amino"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/testdata"
)
func createTestCodec() *amino.Codec {

View File

@ -3,9 +3,10 @@ package codec_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/testdata"
"github.com/stretchr/testify/require"
)
func TestHybridCodec(t *testing.T) {

View File

@ -3,9 +3,10 @@ package codec_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/testdata"
"github.com/stretchr/testify/require"
)
func TestProtoCodec(t *testing.T) {

View File

@ -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
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:

4
go.mod
View File

@ -9,7 +9,7 @@ require (
github.com/cosmos/ledger-cosmos-go v0.11.1
github.com/gogo/protobuf v1.3.1
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/mux v1.7.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
go 1.13
go 1.14

15
go.sum
View File

@ -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/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/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-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=
@ -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-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI=
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/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU=
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.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.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/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
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/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
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/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
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/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
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/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=
@ -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/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
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/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
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.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
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.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
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.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
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/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
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/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/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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
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=
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-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-20190701094942-4def268fd1a4/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-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-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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -122,7 +122,7 @@ type SimApp struct {
// NewSimApp returns a reference to an initialized SimApp.
func NewSimApp(
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 {
// TODO: Remove cdc in favor of appCodec once all modules are migrated.
@ -189,7 +189,7 @@ func NewSimApp(
app.CrisisKeeper = crisis.NewKeeper(
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
evidenceKeeper := evidence.NewKeeper(

View File

@ -15,7 +15,7 @@ import (
func TestSimAppExport(t *testing.T) {
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()
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
@ -31,7 +31,7 @@ func TestSimAppExport(t *testing.T) {
app.Commit()
// 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{})
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
func TestBlackListedAddrs(t *testing.T) {
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 {
require.Equal(t, !allowedReceivingModAcc[acc], app.BankKeeper.BlacklistedAddr(app.SupplyKeeper.GetModuleAddress(acc)))

View File

@ -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
_, 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
_, simParams, simErr := simulation.SimulateFromSeed(

View File

@ -63,7 +63,7 @@ func TestFullAppSimulation(t *testing.T) {
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())
// run randomized simulation
@ -95,7 +95,7 @@ func TestAppImportExport(t *testing.T) {
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())
// Run randomized simulation
@ -129,7 +129,7 @@ func TestAppImportExport(t *testing.T) {
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())
var genesisState GenesisState
@ -181,7 +181,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
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())
// Run randomized simulation
@ -220,7 +220,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
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())
newApp.InitChain(abci.RequestInitChain{
@ -266,7 +266,7 @@ func TestAppStateDeterminism(t *testing.T) {
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(
"running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n",

View File

@ -1,6 +1,10 @@
package simapp
import (
"bytes"
"encoding/hex"
"fmt"
"strconv"
"testing"
"github.com/stretchr/testify/require"
@ -23,7 +27,7 @@ import (
// Setup initializes a new SimApp. A Nop logger is set in SimApp.
func Setup(isCheckTx bool) *SimApp {
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 {
// init chain must be called to stop deliverState from being nil
genesisState := NewDefaultGenesisState()
@ -48,7 +52,7 @@ func Setup(isCheckTx bool) *SimApp {
// accounts and possible balances.
func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances ...bank.Balance) *SimApp {
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
genesisState := NewDefaultGenesisState()
@ -77,15 +81,56 @@ func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances ..
return app
}
// AddTestAddrs constructs and returns accNum amount of accounts with an
// initial balance of accAmt
func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress {
type GenerateAccountStrategy func(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)
for i := 0; i < accNum; i++ {
pk := ed25519.GenPrivKey().PubKey()
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))
totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt.MulRaw(int64(len(testAddrs)))))
prevSupply := app.SupplyKeeper.GetSupply(ctx)
@ -104,6 +149,38 @@ func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sd
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.
func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) {
ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
@ -187,3 +264,31 @@ func incrementAllSequenceNumbers(initSeqNums []uint64) {
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
}

View File

@ -44,6 +44,13 @@ type StoreUpgrades struct {
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.
// All data previously under a PrefixStore with OldKey will be copied
// to a PrefixStore with NewKey, then deleted from OldKey store.

View File

@ -5,9 +5,10 @@ import (
"testing"
"time"
"github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/types"
"github.com/tendermint/tendermint/crypto/ed25519"
)

View File

@ -6,10 +6,11 @@ import (
"math/big"
"testing"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
yaml "gopkg.in/yaml.v2"
"github.com/cosmos/cosmos-sdk/codec"
)
// create a decimal from a decimal string (ex. "1234.5678")

View File

@ -2,7 +2,6 @@ package version
import (
"encoding/json"
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@ -21,29 +20,31 @@ func init() {
var Cmd = &cobra.Command{
Use: "version",
Short: "Print the app version",
RunE: func(_ *cobra.Command, _ []string) error {
verInfo := NewInfo()
if !viper.GetBool(flagLong) {
fmt.Println(verInfo.Version)
return nil
}
var bz []byte
var err error
switch viper.GetString(cli.OutputFlag) {
case "json":
bz, err = json.Marshal(verInfo)
default:
bz, err = yaml.Marshal(&verInfo)
}
if err != nil {
return err
}
_, err = fmt.Println(string(bz))
return err
},
RunE: runVersionCmd,
}
func runVersionCmd(cmd *cobra.Command, args []string) error {
verInfo := NewInfo()
if !viper.GetBool(flagLong) {
cmd.Println(verInfo.Version)
return nil
}
var bz []byte
var err error
switch viper.GetString(cli.OutputFlag) {
case "json":
bz, err = json.Marshal(verInfo)
default:
bz, err = yaml.Marshal(&verInfo)
}
if err != nil {
return err
}
cmd.Println(string(bz))
return nil
}

60
version/version_test.go Normal file
View File

@ -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())
}

View File

@ -1,8 +1,9 @@
package rest
import (
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/gorilla/mux"
"github.com/cosmos/cosmos-sdk/client/context"
)
// RegisterRoutes - Central function to define routes that get registered by the main application

View File

@ -3,9 +3,10 @@ package types_test
import (
"testing"
"github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
)
func cloneAppend(bz []byte, tail []byte) (res []byte) {

View File

@ -25,7 +25,7 @@ var (
func createTestApp() (*simapp.SimApp, sdk.Context, []sdk.AccAddress) {
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{})
constantFee := sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)

View File

@ -11,7 +11,7 @@ import (
func createTestApp() *simapp.SimApp {
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
genesisState := simapp.NewDefaultGenesisState()
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)

View File

@ -63,7 +63,7 @@ func TestImportExportQueues(t *testing.T) {
}
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(
abci.RequestInitChain{

View File

@ -1,14 +1,15 @@
package keeper_test
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/store"
sdk "github.com/cosmos/cosmos-sdk/types"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
"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) {

View File

@ -4,10 +4,11 @@ import (
"reflect"
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/stretchr/testify/require"
)
func validateNoOp(_ interface{}) error { return nil }

View File

@ -4,8 +4,9 @@ import (
"testing"
"time"
"github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/x/params/types"
)
func TestKeyTable(t *testing.T) {

View File

@ -1,12 +1,16 @@
package staking_test
import (
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"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"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
@ -16,16 +20,10 @@ var (
addr1 = sdk.AccAddress(priv1.PubKey().Address())
priv2 = secp256k1.GenPrivKey()
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())
PKs = simapp.CreateTestPubKeys(500)
)
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)
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
}

View File

@ -1,64 +1,83 @@
package staking
package staking_test
import (
"fmt"
"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/stretchr/testify/assert"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/cosmos/cosmos-sdk/simapp"
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/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) {
ctx, accKeeper, bk, keeper, supplyKeeper := keep.CreateTestInput(t, false, 1000)
app, ctx, addrs, _ := bootstrapGenesisTest(t, 1000, 10)
valTokens := sdk.TokensFromConsensusPower(1)
params := keeper.GetParams(ctx)
validators := make([]Validator, 2)
var delegations []Delegation
params := app.StakingKeeper.GetParams(ctx)
validators := make([]types.Validator, 2)
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)
pk1, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, keep.PKs[1])
pk1, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, PKs[1])
require.NoError(t, err)
// initialize the validators
validators[0].OperatorAddress = sdk.ValAddress(keep.Addrs[0])
validators[0].OperatorAddress = sdk.ValAddress(addrs[0])
validators[0].ConsensusPubkey = pk0
validators[0].Description = NewDescription("hoop", "", "", "", "")
validators[0].Description = types.NewDescription("hoop", "", "", "", "")
validators[0].Status = sdk.Bonded
validators[0].Tokens = valTokens
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].Description = NewDescription("bloop", "", "", "", "")
validators[1].Description = types.NewDescription("bloop", "", "", "", "")
validators[1].Status = sdk.Bonded
validators[1].Tokens = valTokens
validators[1].DelegatorShares = valTokens.ToDec()
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.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
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.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.Equal(t, sdk.Bonded, resVal.Status)
@ -74,15 +93,15 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
size := 200
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)
delegations := []Delegation{}
validators := make([]Validator, size)
params := app.StakingKeeper.GetParams(ctx)
delegations := []types.Delegation{}
validators := make([]types.Validator, size)
for i := range validators {
validators[i] = NewValidator(sdk.ValAddress(keep.Addrs[i]),
keep.PKs[i], NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""))
validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]),
PKs[i], types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""))
validators[i].Status = sdk.Bonded
@ -95,7 +114,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
}
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)
for i, val := range validators[:100] {
@ -140,9 +159,9 @@ func TestValidateGenesis(t *testing.T) {
genesisState := types.DefaultGenesisState()
tt.mutate(&genesisState)
if tt.wantErr {
assert.Error(t, ValidateGenesis(genesisState))
assert.Error(t, staking.ValidateGenesis(genesisState))
} else {
assert.NoError(t, ValidateGenesis(genesisState))
assert.NoError(t, staking.ValidateGenesis(genesisState))
}
})
}

File diff suppressed because it is too large Load Diff

View File

@ -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
}

View File

@ -548,7 +548,7 @@ func (k Keeper) Delegate(
}
// 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,
) (amount sdk.Int, err error) {
@ -654,7 +654,7 @@ func (k Keeper) Undelegate(
return time.Time{}, types.ErrMaxUnbondingDelegationEntries
}
returnAmount, err := k.unbond(ctx, delAddr, valAddr, sharesAmount)
returnAmount, err := k.Unbond(ctx, delAddr, valAddr, sharesAmount)
if err != nil {
return time.Time{}, err
}
@ -751,7 +751,7 @@ func (k Keeper) BeginRedelegation(
return time.Time{}, types.ErrMaxRedelegationEntries
}
returnAmount, err := k.unbond(ctx, delAddr, valSrcAddr, sharesAmount)
returnAmount, err := k.Unbond(ctx, delAddr, valSrcAddr, sharesAmount)
if err != nil {
return time.Time{}, err
}

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,13 @@
package keeper
package keeper_test
import (
"sort"
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/stretchr/testify/require"
@ -12,7 +15,11 @@ import (
)
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))
for i, valAddr := range addrVals {
@ -21,27 +28,30 @@ func TestHistoricalInfo(t *testing.T) {
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.Equal(t, hi, recv, "HistoricalInfo not equal")
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.Equal(t, types.HistoricalInfo{}, recv, "HistoricalInfo is not empty")
}
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
params := types.DefaultParams()
params.HistoricalEntries = 5
k.SetParams(ctx, params)
app.StakingKeeper.SetParams(ctx, params)
// set historical info at 5, 4 which should be pruned
// and check that it has been stored
@ -54,29 +64,29 @@ func TestTrackHistoricalInfo(t *testing.T) {
Height: 5,
}
valSet := []types.Validator{
types.NewValidator(sdk.ValAddress(Addrs[0]), PKs[0], types.Description{}),
types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}),
types.NewValidator(addrVals[0], PKs[0], types.Description{}),
types.NewValidator(addrVals[1], PKs[1], types.Description{}),
}
hi4 := types.NewHistoricalInfo(h4, valSet)
hi5 := types.NewHistoricalInfo(h5, valSet)
k.SetHistoricalInfo(ctx, 4, hi4)
k.SetHistoricalInfo(ctx, 5, hi5)
recv, found := k.GetHistoricalInfo(ctx, 4)
app.StakingKeeper.SetHistoricalInfo(ctx, 4, hi4)
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi5)
recv, found := app.StakingKeeper.GetHistoricalInfo(ctx, 4)
require.True(t, found)
require.Equal(t, hi4, recv)
recv, found = k.GetHistoricalInfo(ctx, 5)
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5)
require.True(t, found)
require.Equal(t, hi5, recv)
// Set last validators in keeper
val1 := types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{})
k.SetValidator(ctx, val1)
k.SetLastValidatorPower(ctx, val1.OperatorAddress, 10)
val2 := types.NewValidator(sdk.ValAddress(Addrs[3]), PKs[3], types.Description{})
val1 := types.NewValidator(addrVals[2], PKs[2], types.Description{})
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetLastValidatorPower(ctx, val1.OperatorAddress, 10)
val2 := types.NewValidator(addrVals[3], PKs[3], types.Description{})
vals := []types.Validator{val1, val2}
sort.Sort(types.Validators(vals))
k.SetValidator(ctx, val2)
k.SetLastValidatorPower(ctx, val2.OperatorAddress, 8)
app.StakingKeeper.SetValidator(ctx, val2)
app.StakingKeeper.SetLastValidatorPower(ctx, val2.OperatorAddress, 8)
// Set Header for BeginBlock context
header := abci.Header{
@ -85,22 +95,22 @@ func TestTrackHistoricalInfo(t *testing.T) {
}
ctx = ctx.WithBlockHeader(header)
k.TrackHistoricalInfo(ctx)
app.StakingKeeper.TrackHistoricalInfo(ctx)
// Check HistoricalInfo at height 10 is persisted
expected := types.HistoricalInfo{
Header: header,
Valset: vals,
}
recv, found = k.GetHistoricalInfo(ctx, 10)
recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 10)
require.True(t, found, "GetHistoricalInfo failed after BeginBlock")
require.Equal(t, expected, recv, "GetHistoricalInfo returned eunexpected result")
// 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.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.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune")
}

View File

@ -37,6 +37,10 @@ func NewKeeper(
cdc codec.Marshaler, key sdk.StoreKey, bk types.BankKeeper, sk types.SupplyKeeper, ps paramtypes.Subspace,
) Keeper {
if !ps.HasKeyTable() {
ps = ps.WithKeyTable(ParamKeyTable())
}
// ensure bonded and not bonded module accounts are set
if addr := sk.GetModuleAddress(types.BondedPoolName); addr == nil {
panic(fmt.Sprintf("%s module account has not been set", types.BondedPoolName))
@ -51,7 +55,7 @@ func NewKeeper(
cdc: cdc,
bankKeeper: bk,
supplyKeeper: sk,
paramstore: ps.WithKeyTable(ParamKeyTable()),
paramstore: ps,
hooks: nil,
validatorCache: make(map[string]cachedValidator, aminoCacheSize),
validatorCacheList: list.New(),

View File

@ -1,24 +1,28 @@
package keeper
package keeper_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/x/staking/types"
abci "github.com/tendermint/tendermint/abci/types"
)
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()
//check that the empty keeper loads the default
resParams := keeper.GetParams(ctx)
resParams := app.StakingKeeper.GetParams(ctx)
require.True(t, expParams.Equal(resParams))
//modify a params, save, and retrieve
expParams.MaxValidators = 777
keeper.SetParams(ctx, expParams)
resParams = keeper.GetParams(ctx)
app.StakingKeeper.SetParams(ctx, expParams)
resParams = app.StakingKeeper.GetParams(ctx)
require.True(t, expParams.Equal(resParams))
}

View File

@ -1,34 +1,34 @@
package keeper
package keeper_test
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
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"
"github.com/cosmos/cosmos-sdk/x/staking"
"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) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000)
cdc, app, ctx := createTestInput()
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
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8)}
var validators [2]types.Validator
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)
keeper.SetValidator(ctx, validators[i])
keeper.SetValidatorByPowerIndex(ctx, validators[i])
app.StakingKeeper.SetValidator(ctx, validators[i])
app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i])
}
header := abci.Header{
@ -36,14 +36,14 @@ func TestNewQuerier(t *testing.T) {
Height: 5,
}
hi := types.NewHistoricalInfo(header, validators[:])
keeper.SetHistoricalInfo(ctx, 5, hi)
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi)
query := abci.RequestQuery{
Path: "",
Data: []byte{},
}
querier := NewQuerier(keeper)
querier := staking.NewQuerier(app.StakingKeeper)
bz, err := querier(ctx, []string{"other"}, query)
require.Error(t, err)
@ -106,50 +106,54 @@ func TestNewQuerier(t *testing.T) {
}
func TestQueryParametersPool(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000)
cdc, app, ctx := createTestInput()
querier := staking.NewQuerier(app.StakingKeeper)
bondDenom := sdk.DefaultBondDenom
res, err := queryParameters(ctx, keeper)
res, err := querier(ctx, []string{staking.QueryParameters}, abci.RequestQuery{})
require.NoError(t, err)
var params types.Params
errRes := cdc.UnmarshalJSON(res, &params)
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)
var pool types.Pool
bondedPool := keeper.GetBondedPool(ctx)
notBondedPool := keeper.GetNotBondedPool(ctx)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
require.NoError(t, cdc.UnmarshalJSON(res, &pool))
require.Equal(t, keeper.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, notBondedPool.GetAddress(), bondDenom).Amount, pool.NotBondedTokens)
require.Equal(t, app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, pool.BondedTokens)
}
func TestQueryValidators(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
params := keeper.GetParams(ctx)
cdc, app, ctx := createTestInput()
params := app.StakingKeeper.GetParams(ctx)
querier := staking.NewQuerier(app.StakingKeeper)
addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.TokensFromConsensusPower(10000))
// Create Validators
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)}
status := []sdk.BondStatus{sdk.Bonded, sdk.Unbonded, sdk.Unbonding}
var validators [3]types.Validator
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].UpdateStatus(status[i])
}
keeper.SetValidator(ctx, validators[0])
keeper.SetValidator(ctx, validators[1])
keeper.SetValidator(ctx, validators[2])
app.StakingKeeper.SetValidator(ctx, validators[0])
app.StakingKeeper.SetValidator(ctx, validators[1])
app.StakingKeeper.SetValidator(ctx, validators[2])
// 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 {
queryValsParams := types.NewQueryValidatorsParams(1, int(params.MaxValidators), s.String())
@ -161,7 +165,7 @@ func TestQueryValidators(t *testing.T) {
Data: bz,
}
res, err := queryValidators(ctx, req, keeper)
res, err := querier(ctx, []string{types.QueryValidators}, req)
require.NoError(t, err)
var validatorsResp []types.Validator
@ -170,47 +174,56 @@ func TestQueryValidators(t *testing.T) {
require.Equal(t, 1, len(validatorsResp))
require.ElementsMatch(t, validators[i].OperatorAddress, validatorsResp[0].OperatorAddress)
}
// Query each validator
queryParams := types.NewQueryValidatorParams(addrVal1)
bz, err := cdc.MarshalJSON(queryParams)
require.NoError(t, err)
for _, validator := range validators {
queryParams := types.NewQueryValidatorParams(validator.OperatorAddress)
bz, err := cdc.MarshalJSON(queryParams)
require.NoError(t, err)
query := abci.RequestQuery{
Path: "/custom/staking/validator",
Data: bz,
query := abci.RequestQuery{
Path: "/custom/staking/validator",
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) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
params := keeper.GetParams(ctx)
cdc, app, ctx := createTestInput()
params := app.StakingKeeper.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
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
keeper.SetValidator(ctx, val1)
keeper.SetValidatorByPowerIndex(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidatorByPowerIndex(ctx, val1)
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
keeper.SetValidator(ctx, val2)
keeper.SetValidatorByPowerIndex(ctx, val2)
app.StakingKeeper.SetValidator(ctx, val2)
app.StakingKeeper.SetValidatorByPowerIndex(ctx, val2)
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
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
// Query Delegator bonded validators
queryParams := types.NewQueryDelegatorParams(addrAcc2)
@ -222,9 +235,9 @@ func TestQueryDelegation(t *testing.T) {
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)
var validatorsResp []types.Validator
@ -237,7 +250,7 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryDelegatorValidators(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryDelegatorValidators}, query)
require.Error(t, err)
// Query bonded validator
@ -250,7 +263,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryDelegatorValidator(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query)
require.NoError(t, err)
var validator types.Validator
@ -262,7 +275,7 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryDelegatorValidator(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryDelegatorValidator}, query)
require.Error(t, err)
// Query delegation
@ -272,10 +285,10 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
delegation, found := keeper.GetDelegation(ctx, addrAcc2, addrVal1)
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc2, addrVal1)
require.True(t, found)
res, err = queryDelegation(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegation}, query)
require.NoError(t, err)
var delegationRes types.DelegationResponse
@ -292,7 +305,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryDelegatorDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorDelegations}, query)
require.NoError(t, err)
var delegatorDelegations types.DelegationResponses
@ -306,11 +319,10 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryDelegation(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryDelegation}, query)
require.Error(t, err)
// Query validator delegations
bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1))
require.NoError(t, errRes)
@ -319,7 +331,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryValidatorDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryValidatorDelegations}, query)
require.NoError(t, err)
var delegationsRes types.DelegationResponses
@ -330,9 +342,9 @@ func TestQueryDelegation(t *testing.T) {
require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress)
require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance)
// Query unbonging delegation
// Query unbonding delegation
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)
queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1)
@ -344,10 +356,10 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
unbond, found := keeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1)
unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1)
require.True(t, found)
res, err = queryUnbondingDelegation(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
require.NoError(t, err)
var unbondRes types.UnbondingDelegation
@ -359,7 +371,7 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryUnbondingDelegation(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
require.Error(t, err)
// Query Delegator Delegations
@ -369,7 +381,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
require.NoError(t, err)
var delegatorUbds []types.UnbondingDelegation
@ -380,15 +392,15 @@ func TestQueryDelegation(t *testing.T) {
// error unknown request
query.Data = bz[:len(bz)-1]
_, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
require.Error(t, err)
// Query redelegation
redelegationTokens := sdk.TokensFromConsensusPower(10)
_, err = keeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress,
_, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress,
val2.OperatorAddress, redelegationTokens.ToDec())
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)
bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress))
@ -399,7 +411,7 @@ func TestQueryDelegation(t *testing.T) {
Data: bz,
}
res, err = queryRedelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryRedelegations}, query)
require.NoError(t, err)
var redelRes types.RedelegationResponses
@ -413,24 +425,28 @@ func TestQueryDelegation(t *testing.T) {
}
func TestQueryRedelegations(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
cdc, app, ctx := createTestInput()
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
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
keeper.SetValidator(ctx, val1)
keeper.SetValidator(ctx, val2)
val1 := types.NewValidator(addrVal1, PKs[0], types.Description{})
val2 := types.NewValidator(addrVal2, PKs[1], types.Description{})
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val2)
delAmount := sdk.TokensFromConsensusPower(100)
keeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true)
_ = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true)
_ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
rdAmount := sdk.TokensFromConsensusPower(20)
keeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec())
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec())
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)
// delegator redelegations
@ -443,7 +459,7 @@ func TestQueryRedelegations(t *testing.T) {
Data: bz,
}
res, err := queryRedelegations(ctx, query, keeper)
res, err := querier(ctx, []string{types.QueryRedelegations}, query)
require.NoError(t, err)
var redelRes types.RedelegationResponses
@ -465,7 +481,7 @@ func TestQueryRedelegations(t *testing.T) {
Data: bz,
}
res, err = queryRedelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryRedelegations}, query)
require.NoError(t, err)
errRes = cdc.UnmarshalJSON(res, &redelRes)
@ -478,26 +494,30 @@ func TestQueryRedelegations(t *testing.T) {
}
func TestQueryUnbondingDelegation(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
cdc, app, ctx := createTestInput()
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
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
keeper.SetValidator(ctx, val1)
val1 := types.NewValidator(addrVal1, PKs[0], types.Description{})
app.StakingKeeper.SetValidator(ctx, val1)
// delegate
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)
_ = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
_ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
// undelegate
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)
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)
//
@ -510,7 +530,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
Path: "/custom/staking/unbondingDelegation",
Data: bz,
}
res, err := queryUnbondingDelegation(ctx, query, keeper)
res, err := querier(ctx, []string{types.QueryUnbondingDelegation}, query)
require.NoError(t, err)
require.NotNil(t, res)
var ubDel types.UnbondingDelegation
@ -529,7 +549,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
Path: "/custom/staking/unbondingDelegation",
Data: bz,
}
_, err = queryUnbondingDelegation(ctx, query, keeper)
_, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
require.Error(t, err)
//
@ -542,7 +562,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
Path: "/custom/staking/delegatorUnbondingDelegations",
Data: bz,
}
res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
require.NoError(t, err)
require.NotNil(t, res)
var ubDels []types.UnbondingDelegation
@ -561,7 +581,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
Path: "/custom/staking/delegatorUnbondingDelegations",
Data: bz,
}
res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper)
res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query)
require.NoError(t, err)
require.NotNil(t, res)
require.NoError(t, cdc.UnmarshalJSON(res, &ubDels))
@ -569,22 +589,26 @@ func TestQueryUnbondingDelegation(t *testing.T) {
}
func TestQueryHistoricalInfo(t *testing.T) {
cdc := codec.New()
ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000)
cdc, app, ctx := createTestInput()
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
val1 := types.NewValidator(addrVal1, pk1, types.Description{})
val2 := types.NewValidator(addrVal2, pk2, types.Description{})
val1 := types.NewValidator(addrVal1, PKs[0], types.Description{})
val2 := types.NewValidator(addrVal2, PKs[1], types.Description{})
vals := []types.Validator{val1, val2}
keeper.SetValidator(ctx, val1)
keeper.SetValidator(ctx, val2)
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val2)
header := abci.Header{
ChainID: "HelloChain",
Height: 5,
}
hi := types.NewHistoricalInfo(header, vals)
keeper.SetHistoricalInfo(ctx, 5, hi)
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi)
queryHistoricalParams := types.NewQueryHistoricalInfoParams(4)
bz, errRes := cdc.MarshalJSON(queryHistoricalParams)
@ -593,7 +617,7 @@ func TestQueryHistoricalInfo(t *testing.T) {
Path: "/custom/staking/historicalInfo",
Data: bz,
}
res, err := queryHistoricalInfo(ctx, query, keeper)
res, err := querier(ctx, []string{types.QueryHistoricalInfo}, query)
require.Error(t, err, "Invalid query passed")
require.Nil(t, res, "Invalid query returned non-nil result")
@ -601,7 +625,7 @@ func TestQueryHistoricalInfo(t *testing.T) {
bz, errRes = cdc.MarshalJSON(queryHistoricalParams)
require.NoError(t, errRes)
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.NotNil(t, res, "Valid query returned nil result")

View File

@ -82,7 +82,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
// Iterate through unbonding delegations from slashed validator
unbondingDelegations := k.GetUnbondingDelegationsFromValidator(ctx, operatorAddress)
for _, unbondingDelegation := range unbondingDelegations {
amountSlashed := k.slashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor)
amountSlashed := k.SlashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor)
if amountSlashed.IsZero() {
continue
}
@ -92,7 +92,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
// Iterate through redelegations from slashed source validator
redelegations := k.GetRedelegationsFromSrcValidator(ctx, operatorAddress)
for _, redelegation := range redelegations {
amountSlashed := k.slashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor)
amountSlashed := k.SlashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor)
if amountSlashed.IsZero() {
continue
}
@ -160,7 +160,7 @@ func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress) {
// the unbonding delegation had enough stake to slash
// (the amount actually slashed may be less if there's
// 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) {
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
// insufficient stake remaining)
// 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) {
now := ctx.BlockHeader().Time
@ -254,7 +254,7 @@ func (k Keeper) slashRedelegation(ctx sdk.Context, srcValidator types.Validator,
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 {
panic(fmt.Errorf("error unbonding delegator: %v", err))
}

View File

@ -1,72 +1,83 @@
package keeper
package keeper_test
import (
"testing"
"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"
"github.com/cosmos/cosmos-sdk/simapp"
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/stretchr/testify/require"
)
// TODO integrate with test_common.go helper (CreateTestInput)
// setup helper function - creates two validators
func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) {
// setup
ctx, _, _, keeper, _ := CreateTestInput(t, false, power)
params := keeper.GetParams(ctx)
numVals := int64(3)
// bootstrapSlashTest creates 3 validators and bootstrap the app.
func bootstrapSlashTest(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) {
_, app, ctx := createTestInput()
addrDels, addrVals := generateAddresses(app, ctx, 100)
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)
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins))
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply)
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++ {
validator := types.NewValidator(addrVals[i], PKs[i], types.Description{})
validator, _ = validator.AddTokensFromDel(amt)
validator = TestingUpdateValidator(keeper, ctx, validator, true)
keeper.SetValidatorByConsAddr(ctx, validator)
validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true)
app.StakingKeeper.SetValidatorByConsAddr(ctx, validator)
}
return ctx, keeper, params
return app, ctx, addrDels, addrVals
}
//_________________________________________________________________________________
// tests Jail, Unjail
func TestRevocation(t *testing.T) {
// setup
ctx, keeper, _ := setupHelper(t, 10)
addr := addrVals[0]
app, ctx, _, addrVals := bootstrapSlashTest(t, 5)
consAddr := sdk.ConsAddress(PKs[0].Address())
// initial state
val, found := keeper.GetValidator(ctx, addr)
val, found := app.StakingKeeper.GetValidator(ctx, addrVals[0])
require.True(t, found)
require.False(t, val.IsJailed())
// test jail
keeper.Jail(ctx, consAddr)
val, found = keeper.GetValidator(ctx, addr)
app.StakingKeeper.Jail(ctx, consAddr)
val, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
require.True(t, found)
require.True(t, val.IsJailed())
// test unjail
keeper.Unjail(ctx, consAddr)
val, found = keeper.GetValidator(ctx, addr)
app.StakingKeeper.Unjail(ctx, consAddr)
val, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
require.True(t, found)
require.False(t, val.IsJailed())
}
// tests slashUnbondingDelegation
func TestSlashUnbondingDelegation(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
fraction := sdk.NewDecWithPrec(5, 1)
// 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,
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
slashAmount := keeper.slashUnbondingDelegation(ctx, ubd, 1, fraction)
slashAmount := app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 1, fraction)
require.Equal(t, int64(0), slashAmount.Int64())
// after the expiration time, no longer eligible for slashing
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
keeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
require.Equal(t, int64(0), slashAmount.Int64())
// test valid slash, before expiration timestamp and to which stake contributed
notBondedPool := keeper.GetNotBondedPool(ctx)
oldUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
oldUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
keeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction)
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.Len(t, ubd.Entries, 1)
@ -102,153 +113,157 @@ func TestSlashUnbondingDelegation(t *testing.T) {
// balance decreased
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)
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
func TestSlashRedelegation(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
fraction := sdk.NewDecWithPrec(5, 1)
// add bonded tokens to pool for (re)delegations
startCoins := sdk.NewCoins(sdk.NewInt64Coin(keeper.BondDenom(ctx), 15))
bondedPool := keeper.GetBondedPool(ctx)
balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
startCoins := sdk.NewCoins(sdk.NewInt64Coin(app.StakingKeeper.BondDenom(ctx), 15))
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
balances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...)))
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
require.NoError(t, app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...)))
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
// set a redelegation with an expiration timestamp beyond which the
// redelegation shouldn't be slashed
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0,
time.Unix(5, 0), sdk.NewInt(10), sdk.NewDec(10))
keeper.SetRedelegation(ctx, rd)
app.StakingKeeper.SetRedelegation(ctx, rd)
// set the associated delegation
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
validator, found := keeper.GetValidator(ctx, addrVals[1])
validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[1])
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())
// after the expiration time, no longer eligible for slashing
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
keeper.SetRedelegation(ctx, rd)
validator, found = keeper.GetValidator(ctx, addrVals[1])
app.StakingKeeper.SetRedelegation(ctx, rd)
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
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())
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
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
keeper.SetRedelegation(ctx, rd)
validator, found = keeper.GetValidator(ctx, addrVals[1])
app.StakingKeeper.SetRedelegation(ctx, rd)
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1])
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())
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.Len(t, rd.Entries, 1)
// end block
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
require.Equal(t, 1, len(updates))
// initialbalance unchanged
require.Equal(t, sdk.NewInt(10), rd.Entries[0].InitialBalance)
// 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.Equal(t, int64(5), del.Shares.RoundInt64())
// pool bonded tokens should decrease
burnedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), slashAmount))
require.Equal(t, balances.Sub(burnedCoins), keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()))
burnedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), slashAmount))
require.Equal(t, balances.Sub(burnedCoins), app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()))
}
// tests Slash at a future height (must panic)
func TestSlashAtFutureHeight(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
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
// this just represents pre-genesis and should have the same effect as slashing at height 0
func TestSlashAtNegativeHeight(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondedPool := keeper.GetBondedPool(ctx)
oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
keeper.Slash(ctx, consAddr, -2, 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr, -2, 10, fraction)
// read updated state
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// 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)
validator = keeper.mustGetValidator(ctx, validator.OperatorAddress)
validator, found = app.StakingKeeper.GetValidator(ctx, validator.OperatorAddress)
require.True(t, found)
// power decreased
require.Equal(t, int64(5), validator.GetConsensusPower())
// pool bonded shares decreased
newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String())
}
// tests Slash at the current height
func TestSlashValidatorAtCurrentHeight(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, _, _ := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondedPool := keeper.GetBondedPool(ctx)
oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
keeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction)
// read updated state
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// 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)
validator = keeper.mustGetValidator(ctx, validator.OperatorAddress)
validator, found = app.StakingKeeper.GetValidator(ctx, validator.OperatorAddress)
assert.True(t, found)
// power decreased
require.Equal(t, int64(5), validator.GetConsensusPower())
// pool bonded shares decreased
newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String())
}
// tests Slash at a previous height with an unbonding delegation
func TestSlashWithUnbondingDelegation(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
@ -257,23 +272,23 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
ubdTokens := sdk.TokensFromConsensusPower(4)
ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
time.Unix(0, 0), ubdTokens)
keeper.SetUnbondingDelegation(ctx, ubd)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
// slash validator for the first time
ctx = ctx.WithBlockHeight(12)
bondedPool := keeper.GetBondedPool(ctx)
oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
keeper.Slash(ctx, consAddr, 10, 10, fraction)
app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction)
// end block
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
require.Equal(t, 1, len(updates))
// 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.Len(t, ubd.Entries, 1)
@ -281,12 +296,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
require.Equal(t, sdk.TokensFromConsensusPower(2), ubd.Entries[0].Balance)
// bonded tokens burned
newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(3), diffTokens)
// read updated validator
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// 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
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.Len(t, ubd.Entries, 1)
@ -307,12 +322,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
// bonded tokens burned again
newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(6), diffTokens)
// read updated validator
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// 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
// this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440
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.Len(t, ubd.Entries, 1)
@ -333,12 +348,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
// bonded tokens burned again
newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(9), diffTokens)
// read updated validator
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// 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
// this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440
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.Len(t, ubd.Entries, 1)
@ -359,76 +374,77 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance)
// just 1 bonded token burned again since that's all the validator now has
newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx))
newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx))
require.Equal(t, sdk.TokensFromConsensusPower(10), diffTokens)
// apply TM updates
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
// read updated validator
// power decreased by 1 again, validator is out of stake
// validator should be in unbonding period
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
}
//_________________________________________________________________________________
// tests Slash at a previous height with a redelegation
func TestSlashWithRedelegation(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
consAddr := sdk.ConsAddress(PKs[0].Address())
fraction := sdk.NewDecWithPrec(5, 1)
bondDenom := keeper.BondDenom(ctx)
bondDenom := app.StakingKeeper.BondDenom(ctx)
// set a redelegation
rdTokens := sdk.TokensFromConsensusPower(6)
rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11,
time.Unix(0, 0), rdTokens, rdTokens.ToDec())
keeper.SetRedelegation(ctx, rd)
app.StakingKeeper.SetRedelegation(ctx, rd)
// set the associated delegation
del := types.NewDelegation(addrDels[0], addrVals[1], rdTokens.ToDec())
keeper.SetDelegation(ctx, del)
app.StakingKeeper.SetDelegation(ctx, del)
// update bonded tokens
bondedPool := keeper.GetBondedPool(ctx)
notBondedPool := keeper.GetNotBondedPool(ctx)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2)))
balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
err := keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...))
balances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
err := app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...))
require.NoError(t, err)
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
// slash validator
ctx = ctx.WithBlockHeight(12)
validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
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()
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
// 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))
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))
oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
// 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.Len(t, rd.Entries, 1)
// read updated validator
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// 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
@ -437,102 +453,102 @@ func TestSlashWithRedelegation(t *testing.T) {
require.Equal(t, int64(8), validator.GetConsensusPower())
// slash the validator again
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
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)
// read updated pool
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(ctx)
notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx)
// 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, 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))
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))
oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
// 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.Len(t, rd.Entries, 1)
// read updated validator
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
require.True(t, found)
// power decreased by 4
require.Equal(t, int64(4), validator.GetConsensusPower())
// slash the validator again, by 100%
ctx = ctx.WithBlockHeight(12)
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
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 = burnAmount.Sub(sdk.OneDec().MulInt(rdTokens).TruncateInt())
// read updated pool
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(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))
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))
oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
// 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.Len(t, rd.Entries, 1)
// apply TM updates
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
// read updated validator
// 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)
// slash the validator again, by 100%
// no stake remains to be slashed
ctx = ctx.WithBlockHeight(12)
// validator still in unbonding period
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
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
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(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))
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))
// 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.Len(t, rd.Entries, 1)
// read updated validator
// 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)
}
// tests Slash at a previous height with both an unbonding delegation and a redelegation
func TestSlashBoth(t *testing.T) {
ctx, keeper, _ := setupHelper(t, 10)
app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10)
fraction := sdk.NewDecWithPrec(5, 1)
bondDenom := keeper.BondDenom(ctx)
bondDenom := app.StakingKeeper.BondDenom(ctx)
// set a redelegation with expiration timestamp beyond which the
// redelegation shouldn't be slashed
@ -540,64 +556,64 @@ func TestSlashBoth(t *testing.T) {
rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11,
time.Unix(0, 0), rdATokens,
rdATokens.ToDec())
keeper.SetRedelegation(ctx, rdA)
app.StakingKeeper.SetRedelegation(ctx, rdA)
// set the associated delegation
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
// unbonding delegation shouldn't be slashed)
ubdATokens := sdk.TokensFromConsensusPower(4)
ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11,
time.Unix(0, 0), ubdATokens)
keeper.SetUnbondingDelegation(ctx, ubdA)
app.StakingKeeper.SetUnbondingDelegation(ctx, ubdA)
bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdATokens.MulRaw(2)))
notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, ubdATokens))
// update bonded tokens
bondedPool := keeper.GetBondedPool(ctx)
notBondedPool := keeper.GetNotBondedPool(ctx)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
bondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...)))
bondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
require.NoError(t, app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...)))
notBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
require.NoError(t, keeper.bankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...)))
notBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
require.NoError(t, app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...)))
keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool)
keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool)
app.SupplyKeeper.SetModuleAccount(ctx, bondedPool)
app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool)
oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount
oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount
// slash validator
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)
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()
burnedBondAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt()
burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount)
// read updated pool
bondedPool = keeper.GetBondedPool(ctx)
notBondedPool = keeper.GetNotBondedPool(ctx)
bondedPool = app.StakingKeeper.GetBondedPool(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))
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))
// 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.Len(t, rdA.Entries, 1)
// 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)
// power not decreased, all stake was bonded since
require.Equal(t, int64(10), validator.GetConsensusPower())

View File

@ -1,248 +1,13 @@
package keeper
// noalias
package keeper // noalias
import (
"bytes"
"encoding/hex"
"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"
"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/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
func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) bool {
store := ctx.KVStore(keeper.storeKey)
@ -291,12 +56,6 @@ func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Vali
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
func RandomValidator(r *rand.Rand, keeper Keeper, ctx sdk.Context) (val types.Validator, ok bool) {
vals := keeper.GetAllValidators(ctx)

View File

@ -210,7 +210,7 @@ func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) typ
}
// 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() {
panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator))
}

View File

@ -441,7 +441,7 @@ func (k Keeper) UnbondAllMatureValidatorQueue(ctx sdk.Context) {
panic("unexpected validator in unbonding queue; status was not unbonding")
}
val = k.unbondingToUnbonded(ctx, val)
val = k.UnbondingToUnbonded(ctx, val)
if val.GetDelegatorShares().IsZero() {
k.RemoveValidator(ctx, val.OperatorAddress)
}

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,9 @@ package types
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
yaml "gopkg.in/yaml.v2"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// NewCommissionRates returns an initialized validator commission rates.

View File

@ -6,10 +6,11 @@ import (
"strings"
"time"
yaml "gopkg.in/yaml.v2"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/exported"
yaml "gopkg.in/yaml.v2"
)
// Implements Delegation interface

View File

@ -6,10 +6,11 @@ import (
"strings"
"time"
yaml "gopkg.in/yaml.v2"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
yaml "gopkg.in/yaml.v2"
)
// Staking params default values

View File

@ -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)
// We don't have an upgrade handler for this upgrade name, meaning this software is out of date so shutdown
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)
}
// We have an upgrade handler for this upgrade name, so apply the upgrade

View File

@ -1,10 +1,15 @@
package upgrade_test
import (
"encoding/json"
"errors"
"io/ioutil"
"os"
"testing"
"time"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
@ -31,7 +36,7 @@ var s TestSuite
func setupTest(height int64, skip map[int64]bool) TestSuite {
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()
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
if err != nil {
@ -393,3 +398,30 @@ func TestUpgradeWithoutSkip(t *testing.T) {
VerifyDoUpgrade(t)
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)
}

View File

@ -27,6 +27,7 @@ var (
NewSoftwareUpgradeProposal = types.NewSoftwareUpgradeProposal
NewCancelSoftwareUpgradeProposal = types.NewCancelSoftwareUpgradeProposal
NewQueryAppliedParams = types.NewQueryAppliedParams
UpgradeStoreLoader = types.UpgradeStoreLoader
NewKeeper = keeper.NewKeeper
NewQuerier = keeper.NewQuerier
)

View File

@ -3,6 +3,7 @@ package cli
import (
"encoding/binary"
"fmt"
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/spf13/cobra"

View File

@ -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
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
Before halting the ABCI state machine in the BeginBlocker method, the upgrade module will log an error

View File

@ -2,18 +2,30 @@ package keeper
import (
"encoding/binary"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
store "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
// UpgradeInfoFileName file to store upgrade information
const UpgradeInfoFileName string = "upgrade-info.json"
type Keeper struct {
homePath string
skipUpgradeHeights map[int64]bool
storeKey sdk.StoreKey
cdc codec.Marshaler
@ -21,8 +33,9 @@ type Keeper struct {
}
// 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{
homePath: homePath,
skipUpgradeHeights: skipUpgradeHeights,
storeKey: storeKey,
cdc: cdc,
@ -130,3 +143,59 @@ func (k Keeper) ApplyUpgrade(ctx sdk.Context, plan types.Plan) {
func (k Keeper) IsSkipHeight(height int64) bool {
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
}

View File

@ -2,6 +2,7 @@ package keeper
import (
"encoding/binary"
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
abci "github.com/tendermint/tendermint/abci/types"

View File

@ -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
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
Typically, a `Plan` is proposed and submitted through governance via a `SoftwareUpgradeProposal`.

View File

@ -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)
}
}

View File

@ -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)
})
}
}